static int drv_init(struct device *pdev) #endif { int ret; int result = -EINVAL; gceSTATUS status; gckGALDEVICE device = gcvNULL; struct class* device_class = gcvNULL; gcmkHEADER(); #if ENABLE_GPU_CLOCK_BY_DRIVER && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) { # if 0 struct clk * clk; clk = clk_get(NULL, "GCCLK"); if (IS_ERR(clk)) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): clk get error: %d\n", __FUNCTION__, __LINE__, PTR_ERR(clk) ); result = -ENODEV; gcmkONERROR(gcvSTATUS_GENERIC_IO); } /* * APMU_GC_156M, APMU_GC_312M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently. * Use the 2X clock. */ if (clk_set_rate(clk, coreClock * 2)) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to set core clock.\n", __FUNCTION__, __LINE__ ); result = -EAGAIN; gcmkONERROR(gcvSTATUS_GENERIC_IO); } clk_enable(clk); #if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) gc_pwr(1); # endif # endif } #endif printk(KERN_INFO "Galcore version %d.%d.%d.%d\n", gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD); /* when enable gpu profiler, we need to turn off gpu powerMangement */ if(gpuProfiler) powerManagement = 0; if (showArgs) { printk("galcore options:\n"); printk(" irqLine = %d\n", irqLine); printk(" registerMemBase = 0x%08lX\n", registerMemBase); printk(" registerMemSize = 0x%08lX\n", registerMemSize); if (irqLine2D != -1) { printk(" irqLine2D = %d\n", irqLine2D); printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D); printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D); } if (irqLineVG != -1) { printk(" irqLineVG = %d\n", irqLineVG); printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG); printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG); } printk(" contiguousSize = %ld\n", contiguousSize); printk(" contiguousBase = 0x%08lX\n", contiguousBase); printk(" bankSize = 0x%08lX\n", bankSize); printk(" fastClear = %d\n", fastClear); printk(" compression = %d\n", compression); printk(" signal = %d\n", signal); printk(" baseAddress = 0x%08lX\n", baseAddress); printk(" physSize = 0x%08lX\n", physSize); printk(" logFileSize = %d KB \n", logFileSize); printk(" powerManagement = %d\n", powerManagement); printk(" gpuProfiler = %d\n", gpuProfiler); #if ENABLE_GPU_CLOCK_BY_DRIVER printk(" coreClock = %lu\n", coreClock); #endif } if(logFileSize != 0) { gckDebugFileSystemInitialize(); } /* Create the GAL device. */ gcmkONERROR(gckGALDEVICE_Construct( irqLine, registerMemBase, registerMemSize, irqLine2D, registerMemBase2D, registerMemSize2D, irqLineVG, registerMemBaseVG, registerMemSizeVG, contiguousBase, contiguousSize, bankSize, fastClear, compression, baseAddress, physSize, signal, logFileSize, pdev, powerManagement, gpuProfiler, &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)); if ((physSize != 0) && (device->kernels[gcvCORE_MAJOR] != gcvNULL) && (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0)) { status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, baseAddress, physSize); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Enable new MMU: status=%d\n", status); if ((device->kernels[gcvCORE_2D] != gcvNULL) && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0)) { status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, baseAddress, physSize); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Enable new MMU for 2D: status=%d\n", status); } /* Reset the base address */ device->baseAddress = 0; } #ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT task_free_register(&task_nb); viv_gpu_resmem_handler.data = device->kernels[gcvCORE_MAJOR]; register_reserved_memory_account(&viv_gpu_resmem_handler); #endif /* Register the character device. */ ret = register_chrdev(major, DRV_NAME, &driver_fops); if (ret < 0) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Could not allocate major number for mmap.\n", __FUNCTION__, __LINE__ ); gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } if (major == 0) { major = ret; } /* Create the device class. */ device_class = class_create(THIS_MODULE, "graphics_class"); if (IS_ERR(device_class)) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to create the class.\n", __FUNCTION__, __LINE__ ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) device_create(device_class, NULL, MKDEV(major, 0), NULL, "galcore"); #else device_create(device_class, NULL, MKDEV(major, 0), "galcore"); #endif galDevice = device; gpuClass = device_class; gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_DRIVER, "%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n", __FUNCTION__, __LINE__, irqLine, contiguousSize, registerMemBase ); /* Success. */ gcmkFOOTER_NO(); return 0; OnError: /* Roll back. */ if (device_class != gcvNULL) { device_destroy(device_class, MKDEV(major, 0)); class_destroy(device_class); } if (device != gcvNULL) { gcmkVERIFY_OK(gckGALDEVICE_Stop(device)); gcmkVERIFY_OK(gckGALDEVICE_Destroy(device)); } gcmkFOOTER(); return result; }
static int drv_init(void) #endif { int ret; int result = -EINVAL; gceSTATUS status; gckGALDEVICE device = gcvNULL; struct class* device_class = gcvNULL; gcsDEVICE_CONSTRUCT_ARGS args = { .recovery = recovery, .stuckDump = stuckDump, }; gcmkHEADER(); #if ENABLE_GPU_CLOCK_BY_DRIVER && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) { struct clk * clk; clk = clk_get(NULL, "GCCLK"); if (IS_ERR(clk)) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): clk get error: %d\n", __FUNCTION__, __LINE__, PTR_ERR(clk) ); result = -ENODEV; gcmkONERROR(gcvSTATUS_GENERIC_IO); } /* * APMU_GC_156M, APMU_GC_312M, APMU_GC_PLL2, APMU_GC_PLL2_DIV2 currently. * Use the 2X clock. */ if (clk_set_rate(clk, coreClock * 2)) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to set core clock.\n", __FUNCTION__, __LINE__ ); result = -EAGAIN; gcmkONERROR(gcvSTATUS_GENERIC_IO); } clk_enable(clk); #if defined(CONFIG_PXA_DVFM) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,29)) gc_pwr(1); # endif } #endif printk(KERN_INFO "Galcore version %d.%d.%d.%d\n", gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD); /* when enable gpu profiler, we need to turn off gpu powerMangement */ if(gpuProfiler) powerManagement = 0; if (showArgs) { gckOS_DumpParam(); } if(logFileSize != 0) { gckDEBUGFS_Initialize(); } /* Create the GAL device. */ status = gckGALDEVICE_Construct( #if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY irqLine3D0, registerMemBase3D0, registerMemSize3D0, irqLine3D1, registerMemBase3D1, registerMemSize3D1, #else irqLine, registerMemBase, registerMemSize, #endif irqLine2D, registerMemBase2D, registerMemSize2D, irqLineVG, registerMemBaseVG, registerMemSizeVG, contiguousBase, contiguousSize, bankSize, fastClear, compression, baseAddress, physSize, signal, logFileSize, powerManagement, gpuProfiler, &args, &device ); if (gcmIS_ERROR(status)) { gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to create the GAL device: status=%d\n", __FUNCTION__, __LINE__, status); goto OnError; } /* Start the GAL device. */ gcmkONERROR(gckGALDEVICE_Start(device)); if ((physSize != 0) && (device->kernels[gcvCORE_MAJOR] != gcvNULL) && (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0)) { #if !gcdSECURITY status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, baseAddress, physSize); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Enable new MMU: status=%d\n", status); #if gcdMULTI_GPU_AFFINITY status = gckMMU_Enable(device->kernels[gcvCORE_OCL]->mmu, baseAddress, physSize); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Enable new MMU: status=%d\n", status); #endif if ((device->kernels[gcvCORE_2D] != gcvNULL) && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0)) { status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, baseAddress, physSize); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Enable new MMU for 2D: status=%d\n", status); } #endif /* Reset the base address */ device->baseAddress = 0; } /* Register the character device. */ ret = register_chrdev(major, DEVICE_NAME, &driver_fops); if (ret < 0) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Could not allocate major number for mmap.\n", __FUNCTION__, __LINE__ ); gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } if (major == 0) { major = ret; } /* Create the device class. */ /*####modified for marvell-bg2*/ device_class = class_create(THIS_MODULE, "graphics_3d_class"); /*####end for marvell-bg2*/ if (IS_ERR(device_class)) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to create the class.\n", __FUNCTION__, __LINE__ ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) device_create(device_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME); #else device_create(device_class, NULL, MKDEV(major, 0), DEVICE_NAME); #endif galDevice = device; gpuClass = device_class; #if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_DRIVER, "%s(%d): irqLine3D0=%d, contiguousSize=%lu, memBase3D0=0x%lX\n", __FUNCTION__, __LINE__, irqLine3D0, contiguousSize, registerMemBase3D0 ); #else gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_DRIVER, "%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n", __FUNCTION__, __LINE__, irqLine, contiguousSize, registerMemBase ); #endif /* Success. */ gcmkFOOTER_NO(); return 0; OnError: /* Roll back. */ if (device_class != gcvNULL) { device_destroy(device_class, MKDEV(major, 0)); class_destroy(device_class); } if (device != gcvNULL) { gcmkVERIFY_OK(gckGALDEVICE_Stop(device)); gcmkVERIFY_OK(gckGALDEVICE_Destroy(device)); } gcmkFOOTER(); return result; }
static int drv_init(void) #endif { int ret, i; int result = -EINVAL; gceSTATUS status = gcvSTATUS_OK; gckGALDEVICE device = gcvNULL; struct class* device_class = gcvNULL; gcmkHEADER(); #if ENABLE_GPU_CLOCK_BY_DRIVER && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) gcmkONERROR(gckOS_GpuPowerEnable(gcvNULL, gcvCORE_MAJOR, gcvTRUE, gcvTRUE, coreClock*1000*1000)); #if MRVL_PLATFORM_PXA1088 /* PXA1088: 2D power is shared with 3D */ gcmkONERROR(gckOS_GpuPowerEnable(gcvNULL, gcvCORE_2D, gcvTRUE, gcvFALSE, coreClock*1000*1000)); #endif #endif #if MRVL_PLATFORM_NEVO if (cpu_is_pxa978_Dx()) { baseAddress = 0x0; } else { baseAddress = 0x80000000; } #endif if (showArgs) { printk("galcore options:\n"); printk(" irqLine = %d\n", irqLine); printk(" registerMemBase = 0x%08lX\n", registerMemBase); printk(" registerMemSize = 0x%08lX\n", registerMemSize); if (irqLine2D != -1) { printk(" irqLine2D = %d\n", irqLine2D); printk(" registerMemBase2D = 0x%08lX\n", registerMemBase2D); printk(" registerMemSize2D = 0x%08lX\n", registerMemSize2D); } if (irqLineVG != -1) { printk(" irqLineVG = %d\n", irqLineVG); printk(" registerMemBaseVG = 0x%08lX\n", registerMemBaseVG); printk(" registerMemSizeVG = 0x%08lX\n", registerMemSizeVG); } printk(" contiguousSize = %ld\n", contiguousSize); printk(" contiguousBase = 0x%08lX\n", contiguousBase); printk(" bankSize = 0x%08lX\n", bankSize); #if (MRVL_VIDEO_MEMORY_USE_TYPE != gcdMEM_TYPE_NONE) printk(" pmemSize = %ld\n", pmemSize); #endif printk(" fastClear = %d\n", fastClear); printk(" compression = %d\n", compression); printk(" signal = %d\n", signal); printk(" baseAddress = 0x%08lX\n", baseAddress); printk(" physSize = 0x%08lX\n", physSize); printk(" logFileSize = %d KB \n", logFileSize); #if ENABLE_GPU_CLOCK_BY_DRIVER printk(" coreClock = %lu\n", coreClock); #endif } physSize = 0x80000000; #ifndef CONFIG_CPU_PXA988 pmemSize = 0x0; #endif printk(" physSize modified to = 0x%08lX\n", physSize); if(logFileSize != 0) { gckDebugFileSystemInitialize(); } /* Create the GAL device. */ gcmkONERROR(gckGALDEVICE_Construct( irqLine, registerMemBase, registerMemSize, irqLine2D, registerMemBase2D, registerMemSize2D, irqLineVG, registerMemBaseVG, registerMemSizeVG, contiguousBase, contiguousSize, #if (MRVL_VIDEO_MEMORY_USE_TYPE != gcdMEM_TYPE_NONE) pmemSize, #endif bankSize, fastClear, compression, baseAddress, physSize, signal, logFileSize, &device )); /* Start the GAL device. */ gcmkONERROR(gckGALDEVICE_Start(device)); if ((physSize != 0) && (device->kernels[gcvCORE_MAJOR] != gcvNULL) && (device->kernels[gcvCORE_MAJOR]->hardware->mmuVersion != 0)) { status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, mmuBaseAddress, physSize); //status = gckMMU_Enable(device->kernels[gcvCORE_MAJOR]->mmu, (gctUINT32)device->contiguousStart, contiguousSize); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Enable new MMU: status=%d\n", status); if ((device->kernels[gcvCORE_2D] != gcvNULL) && (device->kernels[gcvCORE_2D]->hardware->mmuVersion != 0)) { status = gckMMU_Enable(device->kernels[gcvCORE_2D]->mmu, mmuBaseAddress, physSize); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER, "Enable new MMU for 2D: status=%d\n", status); } /* Reset the base address */ device->baseAddress = 0; } for (i = 0; i < gcdMAX_GPU_COUNT; i++) { if(device->kernels[i] != gcvNULL) { device->kernels[i]->bTryIdleGPUEnable = gcvTRUE; } } /* Register the character device. */ ret = register_chrdev(major, DRV_NAME, &driver_fops); if (ret < 0) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Could not allocate major number for mmap.\n", __FUNCTION__, __LINE__ ); gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } if (major == 0) { major = ret; } /* Create the device class. */ device_class = class_create(THIS_MODULE, "graphics_class"); if (IS_ERR(device_class)) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to create the class.\n", __FUNCTION__, __LINE__ ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } if (pdevice == gcvNULL) gcmkONERROR(gcvSTATUS_DEVICE); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) device_create(device_class, pdevice, MKDEV(major, 0), NULL, "galcore"); #else device_create(device_class, pdevice, MKDEV(major, 0), "galcore"); #endif galDevice = device; gpuClass = device_class; gcmkTRACE_ZONE( gcvLEVEL_INFO, gcvZONE_DRIVER, "%s(%d): irqLine=%d, contiguousSize=%lu, memBase=0x%lX\n", __FUNCTION__, __LINE__, irqLine, contiguousSize, registerMemBase ); /* Success. */ gcmkFOOTER_NO(); return 0; OnError: /* Roll back. */ if (device_class != gcvNULL) { device_destroy(device_class, MKDEV(major, 0)); class_destroy(device_class); } if (device != gcvNULL) { gcmkVERIFY_OK(gckGALDEVICE_Stop(device)); gcmkVERIFY_OK(gckGALDEVICE_Destroy(device)); } gcmkFOOTER(); return result; }