These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / armada / armada_drv.c
index b01420c..77ab93d 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/of_graph.h>
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
+#include <drm/drm_of.h>
 #include "armada_crtc.h"
 #include "armada_drm.h"
 #include "armada_gem.h"
 #include <drm/armada_drm.h>
 #include "armada_ioctlP.h"
 
-#ifdef CONFIG_DRM_ARMADA_TDA1998X
-#include <drm/i2c/tda998x.h>
-#include "armada_slave.h"
-
-static struct tda998x_encoder_params params = {
-       /* With 0x24, there is no translation between vp_out and int_vp
-       FB      LCD out Pins    VIP     Int Vp
-       R:23:16 R:7:0   VPC7:0  7:0     7:0[R]
-       G:15:8  G:15:8  VPB7:0  23:16   23:16[G]
-       B:7:0   B:23:16 VPA7:0  15:8    15:8[B]
-       */
-       .swap_a = 2,
-       .swap_b = 3,
-       .swap_c = 4,
-       .swap_d = 5,
-       .swap_e = 0,
-       .swap_f = 1,
-       .audio_cfg = BIT(2),
-       .audio_frame[1] = 1,
-       .audio_format = AFMT_SPDIF,
-       .audio_sample_rate = 44100,
-};
-
-static const struct armada_drm_slave_config tda19988_config = {
-       .i2c_adapter_id = 0,
-       .crtcs = 1 << 0, /* Only LCD0 at the moment */
-       .polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT,
-       .interlace_allowed = true,
-       .info = {
-               .type = "tda998x",
-               .addr = 0x70,
-               .platform_data = &params,
-       },
-};
-#endif
-
-static bool is_componentized(struct device *dev)
-{
-       return dev->of_node || dev->platform_data;
-}
-
 static void armada_drm_unref_work(struct work_struct *work)
 {
        struct armada_private *priv =
@@ -91,16 +51,11 @@ void armada_drm_queue_unref_work(struct drm_device *dev,
 
 static int armada_drm_load(struct drm_device *dev, unsigned long flags)
 {
-       const struct platform_device_id *id;
-       const struct armada_variant *variant;
        struct armada_private *priv;
-       struct resource *res[ARRAY_SIZE(priv->dcrtc)];
        struct resource *mem = NULL;
-       int ret, n, i;
+       int ret, n;
 
-       memset(res, 0, sizeof(res));
-
-       for (n = i = 0; ; n++) {
+       for (n = 0; ; n++) {
                struct resource *r = platform_get_resource(dev->platformdev,
                                                           IORESOURCE_MEM, n);
                if (!r)
@@ -109,8 +64,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
                /* Resources above 64K are graphics memory */
                if (resource_size(r) > SZ_64K)
                        mem = r;
-               else if (i < ARRAY_SIZE(priv->dcrtc))
-                       res[i++] = r;
                else
                        return -EINVAL;
        }
@@ -131,13 +84,6 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
        platform_set_drvdata(dev->platformdev, dev);
        dev->dev_private = priv;
 
-       /* Get the implementation specific driver data. */
-       id = platform_get_device_id(dev->platformdev);
-       if (!id)
-               return -ENXIO;
-
-       variant = (const struct armada_variant *)id->driver_data;
-
        INIT_WORK(&priv->fb_unref_work, armada_drm_unref_work);
        INIT_KFIFO(priv->fb_unref);
 
@@ -157,34 +103,9 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
        dev->mode_config.funcs = &armada_drm_mode_config_funcs;
        drm_mm_init(&priv->linear, mem->start, resource_size(mem));
 
-       /* Create all LCD controllers */
-       for (n = 0; n < ARRAY_SIZE(priv->dcrtc); n++) {
-               int irq;
-
-               if (!res[n])
-                       break;
-
-               irq = platform_get_irq(dev->platformdev, n);
-               if (irq < 0)
-                       goto err_kms;
-
-               ret = armada_drm_crtc_create(dev, dev->dev, res[n], irq,
-                                            variant, NULL);
-               if (ret)
-                       goto err_kms;
-       }
-
-       if (is_componentized(dev->dev)) {
-               ret = component_bind_all(dev->dev, dev);
-               if (ret)
-                       goto err_kms;
-       } else {
-#ifdef CONFIG_DRM_ARMADA_TDA1998X
-               ret = armada_drm_connector_slave_create(dev, &tda19988_config);
-               if (ret)
-                       goto err_kms;
-#endif
-       }
+       ret = component_bind_all(dev->dev, dev);
+       if (ret)
+               goto err_kms;
 
        ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
        if (ret)
@@ -202,8 +123,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
        return 0;
 
  err_comp:
-       if (is_componentized(dev->dev))
-               component_unbind_all(dev->dev, dev);
+       component_unbind_all(dev->dev, dev);
  err_kms:
        drm_mode_config_cleanup(dev);
        drm_mm_takedown(&priv->linear);
@@ -219,8 +139,7 @@ static int armada_drm_unload(struct drm_device *dev)
        drm_kms_helper_poll_fini(dev);
        armada_fbdev_fini(dev);
 
-       if (is_componentized(dev->dev))
-               component_unbind_all(dev->dev, dev);
+       component_unbind_all(dev->dev, dev);
 
        drm_mode_config_cleanup(dev);
        drm_mm_takedown(&priv->linear);
@@ -230,60 +149,24 @@ static int armada_drm_unload(struct drm_device *dev)
        return 0;
 }
 
-void armada_drm_vbl_event_add(struct armada_crtc *dcrtc,
-       struct armada_vbl_event *evt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&dcrtc->irq_lock, flags);
-       if (list_empty(&evt->node)) {
-               list_add_tail(&evt->node, &dcrtc->vbl_list);
-
-               drm_vblank_get(dcrtc->crtc.dev, dcrtc->num);
-       }
-       spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
-void armada_drm_vbl_event_remove(struct armada_crtc *dcrtc,
-       struct armada_vbl_event *evt)
-{
-       if (!list_empty(&evt->node)) {
-               list_del_init(&evt->node);
-               drm_vblank_put(dcrtc->crtc.dev, dcrtc->num);
-       }
-}
-
-void armada_drm_vbl_event_remove_unlocked(struct armada_crtc *dcrtc,
-       struct armada_vbl_event *evt)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&dcrtc->irq_lock, flags);
-       armada_drm_vbl_event_remove(dcrtc, evt);
-       spin_unlock_irqrestore(&dcrtc->irq_lock, flags);
-}
-
 /* These are called under the vbl_lock. */
-static int armada_drm_enable_vblank(struct drm_device *dev, int crtc)
+static int armada_drm_enable_vblank(struct drm_device *dev, unsigned int pipe)
 {
        struct armada_private *priv = dev->dev_private;
-       armada_drm_crtc_enable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA);
+       armada_drm_crtc_enable_irq(priv->dcrtc[pipe], VSYNC_IRQ_ENA);
        return 0;
 }
 
-static void armada_drm_disable_vblank(struct drm_device *dev, int crtc)
+static void armada_drm_disable_vblank(struct drm_device *dev, unsigned int pipe)
 {
        struct armada_private *priv = dev->dev_private;
-       armada_drm_crtc_disable_irq(priv->dcrtc[crtc], VSYNC_IRQ_ENA);
+       armada_drm_crtc_disable_irq(priv->dcrtc[pipe], VSYNC_IRQ_ENA);
 }
 
 static struct drm_ioctl_desc armada_ioctls[] = {
-       DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl,
-               DRM_UNLOCKED),
-       DRM_IOCTL_DEF_DRV(ARMADA_GEM_MMAP, armada_gem_mmap_ioctl,
-               DRM_UNLOCKED),
-       DRM_IOCTL_DEF_DRV(ARMADA_GEM_PWRITE, armada_gem_pwrite_ioctl,
-               DRM_UNLOCKED),
+       DRM_IOCTL_DEF_DRV(ARMADA_GEM_CREATE, armada_gem_create_ioctl,0),
+       DRM_IOCTL_DEF_DRV(ARMADA_GEM_MMAP, armada_gem_mmap_ioctl, 0),
+       DRM_IOCTL_DEF_DRV(ARMADA_GEM_PWRITE, armada_gem_pwrite_ioctl, 0),
 };
 
 static void armada_drm_lastclose(struct drm_device *dev)
@@ -310,7 +193,7 @@ static struct drm_driver armada_drm_driver = {
        .lastclose              = armada_drm_lastclose,
        .unload                 = armada_drm_unload,
        .set_busid              = drm_platform_set_busid,
-       .get_vblank_counter     = drm_vblank_count,
+       .get_vblank_counter     = drm_vblank_no_hw_counter,
        .enable_vblank          = armada_drm_enable_vblank,
        .disable_vblank         = armada_drm_disable_vblank,
 #ifdef CONFIG_DEBUG_FS
@@ -380,43 +263,29 @@ static void armada_add_endpoints(struct device *dev,
        }
 }
 
-static int armada_drm_find_components(struct device *dev,
-       struct component_match **match)
-{
-       struct device_node *port;
-       int i;
-
-       if (dev->of_node) {
-               struct device_node *np = dev->of_node;
-
-               for (i = 0; ; i++) {
-                       port = of_parse_phandle(np, "ports", i);
-                       if (!port)
-                               break;
-
-                       component_match_add(dev, match, compare_of, port);
-                       of_node_put(port);
-               }
+static const struct component_master_ops armada_master_ops = {
+       .bind = armada_drm_bind,
+       .unbind = armada_drm_unbind,
+};
 
-               if (i == 0) {
-                       dev_err(dev, "missing 'ports' property\n");
-                       return -ENODEV;
-               }
+static int armada_drm_probe(struct platform_device *pdev)
+{
+       struct component_match *match = NULL;
+       struct device *dev = &pdev->dev;
+       int ret;
 
-               for (i = 0; ; i++) {
-                       port = of_parse_phandle(np, "ports", i);
-                       if (!port)
-                               break;
+       ret = drm_of_component_probe(dev, compare_dev_name, &armada_master_ops);
+       if (ret != -EINVAL)
+               return ret;
 
-                       armada_add_endpoints(dev, match, port);
-                       of_node_put(port);
-               }
-       } else if (dev->platform_data) {
+       if (dev->platform_data) {
                char **devices = dev->platform_data;
+               struct device_node *port;
                struct device *d;
+               int i;
 
                for (i = 0; devices[i]; i++)
-                       component_match_add(dev, match, compare_dev_name,
+                       component_match_add(dev, &match, compare_dev_name,
                                            devices[i]);
 
                if (i == 0) {
@@ -426,56 +295,30 @@ static int armada_drm_find_components(struct device *dev,
 
                for (i = 0; devices[i]; i++) {
                        d = bus_find_device_by_name(&platform_bus_type, NULL,
-                                       devices[i]);
+                                                   devices[i]);
                        if (d && d->of_node) {
                                for_each_child_of_node(d->of_node, port)
-                                       armada_add_endpoints(dev, match, port);
+                                       armada_add_endpoints(dev, &match, port);
                        }
                        put_device(d);
                }
        }
 
-       return 0;
-}
-
-static const struct component_master_ops armada_master_ops = {
-       .bind = armada_drm_bind,
-       .unbind = armada_drm_unbind,
-};
-
-static int armada_drm_probe(struct platform_device *pdev)
-{
-       if (is_componentized(&pdev->dev)) {
-               struct component_match *match = NULL;
-               int ret;
-
-               ret = armada_drm_find_components(&pdev->dev, &match);
-               if (ret < 0)
-                       return ret;
-
-               return component_master_add_with_match(&pdev->dev,
-                               &armada_master_ops, match);
-       } else {
-               return drm_platform_init(&armada_drm_driver, pdev);
-       }
+       return component_master_add_with_match(&pdev->dev, &armada_master_ops,
+                                              match);
 }
 
 static int armada_drm_remove(struct platform_device *pdev)
 {
-       if (is_componentized(&pdev->dev))
-               component_master_del(&pdev->dev, &armada_master_ops);
-       else
-               drm_put_dev(platform_get_drvdata(pdev));
+       component_master_del(&pdev->dev, &armada_master_ops);
        return 0;
 }
 
 static const struct platform_device_id armada_drm_platform_ids[] = {
        {
                .name           = "armada-drm",
-               .driver_data    = (unsigned long)&armada510_ops,
        }, {
                .name           = "armada-510-drm",
-               .driver_data    = (unsigned long)&armada510_ops,
        },
        { },
 };