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; int result = -EINVAL; gceSTATUS status; gckGALDEVICE device = gcvNULL; struct class* device_class = gcvNULL; gcsDEVICE_CONSTRUCT_ARGS args = { .recovery = recovery, .stuckDump = stuckDump, .gpu3DMinClock = gpu3DMinClock, .contiguousRequested = contiguousRequested, .platform = &platform, .mmu = mmu, }; gcmkHEADER(); printk(KERN_INFO "Galcore version %d.%d.%d.%d\n", gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD); #if !VIVANTE_PROFILER_PM /* when enable gpu profiler, we need to turn off gpu powerMangement */ if (gpuProfiler) { powerManagement = 0; } #endif 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)) { /* 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. */ 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, 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; }