]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00240988: gpu: allocate contiguous memory from CMA for 3.10 kernel
authorShawn Guo <shawn.guo@freescale.com>
Fri, 26 Jul 2013 08:49:39 +0000 (16:49 +0800)
committerJason Liu <r64343@freescale.com>
Wed, 30 Oct 2013 01:54:00 +0000 (09:54 +0800)
The Contiguous Memory Allocator (CMA) is mature in 3.10 kernel.  Let's
change gpu driver to allocate contiguous memory from CMA pool.  Doing so
will save not only the memblock reserve calls in machine code but also
the request_mem_region() and ioremap() in gpu driver.  And all the
system memory will be seen by kernel no matter whether gpu driver is
running or not.

It also changes the default contiguousSize to 128 MiB for Freescale
adjustment.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c

index 2f755d06e5e26e2814342d2d2a9e75ab7e27e751..84a3c5e61ed6188dcfb0cba7db4b385fdf68b890 100644 (file)
@@ -851,6 +851,7 @@ gckGALDEVICE_Construct(
             }
             else
             {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)
                 mem_region = request_mem_region(
                     ContiguousBase, ContiguousSize, "galcore managed memory"
                     );
@@ -866,6 +867,7 @@ gckGALDEVICE_Construct(
 
                     gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
                 }
+#endif
 
                 device->requestedContiguousBase  = ContiguousBase;
                 device->requestedContiguousSize  = ContiguousSize;
index dde4f034442ea76f53d4699bcf4e9ceeb3d57eaa..6e71e00509dd26e9fe0a8c3eb6956b113a04af62 100644 (file)
 ******************************* gckGALDEVICE Structure *******************************
 \******************************************************************************/
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+struct contiguous_mem_pool {
+       struct dma_attrs attrs;
+       dma_addr_t phys;
+       void *virt;
+       size_t size;
+};
+#endif
+
 typedef struct _gckGALDEVICE
 {
     /* Objects. */
@@ -97,6 +106,9 @@ typedef struct _gckGALDEVICE
 #endif
        /*Run time pm*/
        struct device           *pmdev;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+       struct contiguous_mem_pool *pool;
+#endif
 }
 * gckGALDEVICE;
 
index 2232fefb20198b3cabc4d7fb02577b80fa28a23f..e7cdb71bc68756bf22e7434c177cc770bfde8fdb 100644 (file)
@@ -118,7 +118,11 @@ module_param(registerMemBaseVG, ulong, 0644);
 static ulong registerMemSizeVG = 2 << 10;
 module_param(registerMemSizeVG, ulong, 0644);
 
+#if gcdENABLE_FSCALE_VAL_ADJUST
+static ulong contiguousSize = 128 << 20;
+#else
 static ulong contiguousSize = 4 << 20;
+#endif
 module_param(contiguousSize, ulong, 0644);
 
 static ulong contiguousBase = 0;
@@ -846,6 +850,10 @@ static int drv_init(struct device *pdev)
         &device
         ));
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+       device->pool = dev_get_drvdata(pdev);
+#endif
+
     /* Start the GAL device. */
     gcmkONERROR(gckGALDEVICE_Start(device));
 
@@ -1038,7 +1046,9 @@ static int __devinit gpu_probe(struct platform_device *pdev)
 {
     int ret = -ENODEV;
     struct resource* res;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+       struct contiguous_mem_pool *pool;
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
        struct device_node *dn =pdev->dev.of_node;
        const u32 *prop;
 #else
@@ -1083,7 +1093,22 @@ static int __devinit gpu_probe(struct platform_device *pdev)
         registerMemSizeVG = res->end - res->start + 1;
     }
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+       pool = devm_kzalloc(&pdev->dev, sizeof(*pool), GFP_KERNEL);
+       if (!pool)
+               return -ENOMEM;
+       pool->size = contiguousSize;
+       init_dma_attrs(&pool->attrs);
+       dma_set_attr(DMA_ATTR_WRITE_COMBINE, &pool->attrs);
+       pool->virt = dma_alloc_attrs(&pdev->dev, pool->size, &pool->phys,
+                                    GFP_KERNEL, &pool->attrs);
+       if (!pool->virt) {
+               dev_err(&pdev->dev, "Failed to allocate contiguous memory\n");
+               return -ENOMEM;
+       }
+       contiguousBase = pool->phys;
+       dev_set_drvdata(&pdev->dev, pool);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
        prop = of_get_property(dn, "contiguousbase", NULL);
        if(prop)
                contiguousBase = *prop;
@@ -1112,6 +1137,10 @@ static int __devinit gpu_probe(struct platform_device *pdev)
     }
 #if gcdENABLE_FSCALE_VAL_ADJUST
     unregister_thermal_notifier(&thermal_hot_pm_notifier);
+#endif
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+       dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
+                      &pool->attrs);
 #endif
     gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret);
     return ret;
@@ -1123,12 +1152,20 @@ static int gpu_remove(struct platform_device *pdev)
 static int __devexit gpu_remove(struct platform_device *pdev)
 #endif
 {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+       gckGALDEVICE device = platform_get_drvdata(pdev);
+       struct contiguous_mem_pool *pool = device->pool;
+#endif
     gcmkHEADER();
 #if gcdENABLE_FSCALE_VAL_ADJUST
     if(galDevice->kernels[gcvCORE_MAJOR])
         unregister_thermal_notifier(&thermal_hot_pm_notifier);
 #endif
     drv_exit();
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+       dma_free_attrs(&pdev->dev, pool->size, pool->virt, pool->phys,
+                      &pool->attrs);
+#endif
     gcmkFOOTER_NO();
     return 0;
 }
index 60452400046c3ac25274d440dd3b9b90e357c67f..2a0379b9284fc31d736dd8419d57d23f7e74cf78 100644 (file)
@@ -2801,16 +2801,25 @@ gckOS_MapPhysical(
 
     if (mdl == gcvNULL)
     {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
+       struct contiguous_mem_pool *pool = Os->device->pool;
+
+       if (Physical >= pool->phys && Physical < pool->phys + pool->size)
+               logical = (gctPOINTER)(Physical - pool->phys + pool->virt);
+       else
+               logical = gcvNULL;
+#else
         /* Map memory as cached memory. */
         request_mem_region(physical, Bytes, "MapRegion");
         logical = (gctPOINTER) ioremap_nocache(physical, Bytes);
+#endif
 
         if (logical == gcvNULL)
         {
             gcmkTRACE_ZONE(
                 gcvLEVEL_INFO, gcvZONE_OS,
-                "%s(%d): Failed to ioremap",
-                __FUNCTION__, __LINE__
+                "%s(%d): Failed to map physical address 0x%08x",
+                __FUNCTION__, __LINE__, Physical
                 );
 
             MEMORY_UNLOCK(Os);