From: Shawn Guo Date: Fri, 26 Jul 2013 08:49:39 +0000 (+0800) Subject: ENGR00240988: gpu: allocate contiguous memory from CMA for 3.10 kernel X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=49d42c76ae4b7527a06181d79fb09c51de57de2e;p=karo-tx-linux.git ENGR00240988: gpu: allocate contiguous memory from CMA for 3.10 kernel 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 --- diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c index 2f755d06e5e2..84a3c5e61ed6 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c @@ -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; diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h index dde4f034442e..6e71e00509dd 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h @@ -26,6 +26,15 @@ ******************************* 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; diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c index 2232fefb2019..e7cdb71bc687 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c @@ -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; } diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c index 60452400046c..2a0379b9284f 100644 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c @@ -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);