]> Git Repo - linux.git/blobdiff - drivers/gpu/drm/msm/msm_drv.c
Merge Linus master into drm-next
[linux.git] / drivers / gpu / drm / msm / msm_drv.c
index a4269119f9eaf3eae5c2b0dbb6d37745466bd44f..47f4dd407671970fc247c4a9999dcccc03202c8e 100644 (file)
@@ -182,41 +182,57 @@ static int get_mdp_ver(struct platform_device *pdev)
        return 4;
 }
 
-static int msm_load(struct drm_device *dev, unsigned long flags)
-{
-       struct platform_device *pdev = dev->platformdev;
-       struct msm_drm_private *priv;
-       struct msm_kms *kms;
-       int ret;
-
-       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-       if (!priv) {
-               dev_err(dev->dev, "failed to allocate private data\n");
-               return -ENOMEM;
-       }
+#include <linux/of_address.h>
 
-       dev->dev_private = priv;
-
-       priv->wq = alloc_ordered_workqueue("msm", 0);
-       init_waitqueue_head(&priv->fence_event);
-       init_waitqueue_head(&priv->pending_crtcs_event);
-
-       INIT_LIST_HEAD(&priv->inactive_list);
-       INIT_LIST_HEAD(&priv->fence_cbs);
+static int msm_init_vram(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       unsigned long size = 0;
+       int ret = 0;
 
-       drm_mode_config_init(dev);
+#ifdef CONFIG_OF
+       /* In the device-tree world, we could have a 'memory-region'
+        * phandle, which gives us a link to our "vram".  Allocating
+        * is all nicely abstracted behind the dma api, but we need
+        * to know the entire size to allocate it all in one go. There
+        * are two cases:
+        *  1) device with no IOMMU, in which case we need exclusive
+        *     access to a VRAM carveout big enough for all gpu
+        *     buffers
+        *  2) device with IOMMU, but where the bootloader puts up
+        *     a splash screen.  In this case, the VRAM carveout
+        *     need only be large enough for fbdev fb.  But we need
+        *     exclusive access to the buffer to avoid the kernel
+        *     using those pages for other purposes (which appears
+        *     as corruption on screen before we have a chance to
+        *     load and do initial modeset)
+        */
+       struct device_node *node;
+
+       node = of_parse_phandle(dev->dev->of_node, "memory-region", 0);
+       if (node) {
+               struct resource r;
+               ret = of_address_to_resource(node, 0, &r);
+               if (ret)
+                       return ret;
+               size = r.end - r.start;
+               DRM_INFO("using VRAM carveout: %lx@%08x\n", size, r.start);
+       } else
+#endif
 
        /* if we have no IOMMU, then we need to use carveout allocator.
         * Grab the entire CMA chunk carved out in early startup in
         * mach-msm:
         */
        if (!iommu_present(&platform_bus_type)) {
+               DRM_INFO("using %s VRAM carveout\n", vram);
+               size = memparse(vram, NULL);
+       }
+
+       if (size) {
                DEFINE_DMA_ATTRS(attrs);
-               unsigned long size;
                void *p;
 
-               DBG("using %s VRAM carveout", vram);
-               size = memparse(vram, NULL);
                priv->vram.size = size;
 
                drm_mm_init(&priv->vram.mm, 0, (size >> PAGE_SHIFT) - 1);
@@ -232,8 +248,7 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
                if (!p) {
                        dev_err(dev->dev, "failed to allocate VRAM\n");
                        priv->vram.paddr = 0;
-                       ret = -ENOMEM;
-                       goto fail;
+                       return -ENOMEM;
                }
 
                dev_info(dev->dev, "VRAM: %08x->%08x\n",
@@ -241,6 +256,37 @@ static int msm_load(struct drm_device *dev, unsigned long flags)
                                (uint32_t)(priv->vram.paddr + size));
        }
 
+       return ret;
+}
+
+static int msm_load(struct drm_device *dev, unsigned long flags)
+{
+       struct platform_device *pdev = dev->platformdev;
+       struct msm_drm_private *priv;
+       struct msm_kms *kms;
+       int ret;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(dev->dev, "failed to allocate private data\n");
+               return -ENOMEM;
+       }
+
+       dev->dev_private = priv;
+
+       priv->wq = alloc_ordered_workqueue("msm", 0);
+       init_waitqueue_head(&priv->fence_event);
+       init_waitqueue_head(&priv->pending_crtcs_event);
+
+       INIT_LIST_HEAD(&priv->inactive_list);
+       INIT_LIST_HEAD(&priv->fence_cbs);
+
+       drm_mode_config_init(dev);
+
+       ret = msm_init_vram(dev);
+       if (ret)
+               goto fail;
+
        platform_set_drvdata(pdev, dev);
 
        /* Bind all our sub-components: */
@@ -1030,6 +1076,7 @@ static struct platform_driver msm_platform_driver = {
 static int __init msm_drm_register(void)
 {
        DBG("init");
+       msm_dsi_register();
        msm_edp_register();
        hdmi_register();
        adreno_register();
@@ -1043,6 +1090,7 @@ static void __exit msm_drm_unregister(void)
        hdmi_unregister();
        adreno_unregister();
        msm_edp_unregister();
+       msm_dsi_unregister();
 }
 
 module_init(msm_drm_register);
This page took 0.03967 seconds and 4 git commands to generate.