static int viv_sync_pt_has_signaled( struct sync_pt * sync_pt ) { gceSTATUS status; gctBOOL state; struct viv_sync_pt * pt; struct viv_sync_timeline * obj; pt = (struct viv_sync_pt *)sync_pt; obj = (struct viv_sync_timeline *)sync_pt->parent; status = gckOS_QuerySyncPoint(obj->os, pt->sync, &state); if (gcmIS_ERROR(status)) { /* Error. */ return -1; } return state; }
gctINT slScanFieldSelection( IN sloCOMPILER Compiler, IN gctUINT LineNo, IN gctUINT StringNo, IN gctSTRING Symbol, OUT slsLexToken * Token ) { gceSTATUS status; sltPOOL_STRING symbolInPool; gcmASSERT(Token); Token->lineNo = LineNo; Token->stringNo = StringNo; status = sloCOMPILER_AllocatePoolString( Compiler, Symbol, &symbolInPool); if (gcmIS_ERROR(status)) return T_EOF; Token->type = T_FIELD_SELECTION; Token->u.fieldSelection = symbolInPool; gcmVERIFY_OK(sloCOMPILER_Dump( Compiler, slvDUMP_SCANNER, "<TOKEN line=\"%d\" string=\"%d\" type=\"fieldSelection\" symbol=\"%s\" />", LineNo, StringNo, Token->u.fieldSelection)); return T_FIELD_SELECTION; }
int main( int argc, char * argv[] ) { gctBOOL dumpLog = gcvFALSE; gctSTRING fileName[2] = { gcvNULL, gcvNULL }; gcSHADER shaders[2] = { gcvNULL, gcvNULL }; gctINT i; gcoOS os = gcvNULL; gcoHAL hal = gcvNULL; gceSTATUS result; gctUINT option = 1; /* no optimization */ char outFile[128] = { '\0' }; char logVSFile[128] = { '\0' }; char logFSFile[128] = { '\0' }; printf("vCompile version 0.8, Copyright (c) 2005-2011, Vivante Corporation\n\n"); #ifdef _WIN32 _CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) /*| _CRTDBG_CHECK_ALWAYS_DF*/ | _CRTDBG_DELAY_FREE_MEM_DF | _CRTDBG_LEAK_CHECK_DF); _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE ); _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDERR ); /* _CrtSetBreakAlloc(79); */ #endif #if gcdDEBUG gcoOS_SetDebugLevel(gcvLEVEL_VERBOSE); gcoOS_SetDebugZone(gcvZONE_COMPILER); #endif for (i = 1; i < argc; i++) { if (gcmIS_SUCCESS(gcoOS_StrCmp(argv[i], "-l"))) { dumpLog = gcvTRUE; } else if (gcmIS_SUCCESS(gcoOS_StrCmp(argv[i], "-O0"))) { /* Currently, optimization level is either FULL or NONE */ option = 0; /* no optimization */ } else if (gcmIS_SUCCESS(gcoOS_StrCmp(argv[i], "-O"))) { option = 1; /* full optimization */ } else if (gcmIS_SUCCESS(gcoOS_StrCmp(argv[i], "-OT"))) { /* For optimization unit test */ if (i++ == argc) { printf("*ERROR* Optimization testing pattern not provided.\n"); return 1; } else { gctINT testPattern; gcmVERIFY_OK(gcoOS_StrToInt(argv[i], (gctINT *)&testPattern)); if (testPattern < 0) { printf("*ERROR* Unknown optimization testing pattern.\n"); return 1; } option = testPattern; } } else { if (fileName[0] == gcvNULL) fileName[0] = argv[i]; else if (fileName[1] == gcvNULL) fileName[1] = argv[i]; else { printf("*ERROR* Too many shaders.\n"); return 1; } } } if (fileName[0] == gcvNULL) { printf("Usage: %s [-l] [-O0] shaderFileName [shaderFileName]\n", argv[0]); printf(" -l Generate log file.\n" " -O0 Disable optimizations.\n" "\n" "If only one shader is specified, that shader will be compiled into a .gcSL\n" "file. If two shaders are specified, those shaders will be compiled and\n" "linked into a .gcPGM file. With two shaders, the vertex shader file needs\n" "to be the first.\n"); return 0; } result = gcoOS_Construct(gcvNULL, &os); if (result != gcvSTATUS_OK) { printf("*ERROR* Failed to construct a new gcoOS object\n"); return 1; } result = gcoHAL_Construct(gcvNULL, os, &hal); if (result != gcvSTATUS_OK) { printf("*ERROR* Failed to construct a new gcoHAL object\n"); goto ErrorExit; } /* Dump compile log only when one shader is present */ shaders[0] = CompileFile(os, fileName[0], hal, option, dumpLog && (fileName[1] == gcvNULL), fileName[1] == gcvNULL ); if (shaders[0] == gcvNULL) { goto ErrorExit; } if (fileName[1] != gcvNULL) { gctSIZE_T programBufferSize = 0; gctPOINTER programBuffer = gcvNULL; gcsHINT_PTR hints = gcvNULL; gceSTATUS status; gctPOINTER binary = gcvNULL; gctSIZE_T binarySize = 0; FILE * f; gctSTRING p; gcoOS_StrCopySafe(outFile, gcmSIZEOF(outFile), fileName[0]); p = strrchr(outFile, '.'); gcoOS_StrCopySafe(p, gcmSIZEOF(outFile) - (p - outFile), ".gcPGM"); gcoOS_StrCopySafe(logVSFile, gcmSIZEOF(logVSFile), fileName[0]); gcoOS_StrCatSafe(logVSFile, gcmSIZEOF(logVSFile), ".log"); gcoOS_StrCopySafe(logFSFile, gcmSIZEOF(logFSFile), fileName[1]); gcoOS_StrCatSafe(logFSFile, gcmSIZEOF(logFSFile), ".log"); shaders[1] = CompileFile(os, fileName[1], hal, option, gcvFALSE, gcvFALSE); if (shaders[1] == gcvNULL) { goto ErrorExit; } if ( dumpLog) { gcoOS_SetDebugShaderFiles(logVSFile, logFSFile); } status = gcLinkShaders(shaders[0], shaders[1], gcvSHADER_DEAD_CODE | gcvSHADER_RESOURCE_USAGE | gcvSHADER_OPTIMIZER | gcvSHADER_USE_GL_Z | gcvSHADER_USE_GL_POSITION | gcvSHADER_USE_GL_FACE, &programBufferSize, &programBuffer, &hints); if ( dumpLog) { gcoOS_SetDebugShaderFiles(gcvNULL, gcvNULL); } if (gcmIS_ERROR(status)) { printf("*ERROR* gcLinkShaders returned errror %d\n", status); } else { int ret; status = gcSaveProgram(shaders[0], shaders[1], programBufferSize, programBuffer, hints, &binary, &binarySize); if (gcmIS_ERROR(status)) { printf("*ERROR* gcSaveShaders returned errror %d\n", status); } f = fopen(outFile, "wb"); ret = fwrite(binary, binarySize, 1, f); if (ret); fclose(f); } if (programBuffer != gcvNULL) gcoOS_Free(os, programBuffer); if (hints != gcvNULL) gcoOS_Free(os, hints); if (binary != gcvNULL) gcoOS_Free(os, binary); } gcSHADER_Destroy(shaders[0]); if (shaders[1] != gcvNULL) gcSHADER_Destroy(shaders[1]); gcoHAL_Destroy(hal); gcoOS_Destroy(os); return 0; ErrorExit: if (shaders[0] != gcvNULL) gcSHADER_Destroy(shaders[0]); if (shaders[1] != gcvNULL) gcSHADER_Destroy(shaders[1]); if (gcvNULL != hal) gcoHAL_Destroy(hal); if (gcvNULL != os) gcoOS_Destroy(os); return 1; }
static gcSHADER CompileFile( IN gcoOS Os, IN gctCONST_STRING FileName, IN gcoHAL Hal, IN gctUINT Option, IN gctBOOL DumpLog, IN gctBOOL DumpCompiledShader ) { gceSTATUS status; gctINT shaderType; gctSIZE_T sourceSize; gctSTRING source = gcvNULL; gcSHADER binary; gctSTRING log = gcvNULL; gctSIZE_T bufferSize; gctSTRING buffer; gctSTRING dataFileName = gcvNULL; gctSIZE_T length; gctFILE logFile = gcvNULL; gcmASSERT(FileName); shaderType = GetShaderType(FileName); if (!ReadSource(Os, FileName, &sourceSize, &source)) return gcvNULL; status = gcCompileShader(Hal, shaderType, sourceSize, source, &binary, &log); if (log != gcvNULL) { printf("<LOG>\n"); printf("%s", log); printf("</LOG>\n"); } if (gcmIS_ERROR(status)) { gcmASSERT(binary == gcvNULL); binary = gcvNULL; printf("*ERROR* Failed to compile %s (error: %d)\n", FileName, status); goto Exit; } gcmASSERT(binary != gcvNULL); if (DumpLog) { gcmVERIFY_OK(gcoOS_StrLen(FileName, &length)); length += 5; gcmVERIFY_OK(gcoOS_Allocate(Os, length, (gctPOINTER *) &dataFileName)); gcmVERIFY_OK(gcoOS_StrCopySafe(dataFileName, length, FileName)); gcmVERIFY_OK(gcoOS_StrCatSafe(dataFileName, length, ".log")); status = gcoOS_Open(Os, dataFileName, gcvFILE_CREATETEXT, &logFile); if (gcmIS_ERROR(status)) { logFile = gcvNULL; printf("*ERROR* Failed to open the log file: %s\n", dataFileName); } gcoOS_Free(Os, dataFileName); } gcmVERIFY_OK(gcSHADER_SetOptimizationOption(binary, Option)); status = gcOptimizeShader(binary, logFile); if (!gcmIS_SUCCESS(status)) { printf("*ERROR* Failed to optimize %s (error: %d)\n", FileName, status); } if (logFile != gcvNULL) { gcmVERIFY_OK(gcoOS_Close(Os, logFile)); } if (DumpCompiledShader) { status = gcSHADER_Save(binary, gcvNULL, &bufferSize); if (gcmIS_ERROR(status)) { printf("*ERROR* Failed to get the buffer size of the shader\n"); goto Exit; } status = gcoOS_Allocate(Os, bufferSize, (gctPOINTER *) &buffer); if (!gcmIS_SUCCESS(status)) { printf("*ERROR* Not enough memory\n"); goto Exit; } status = gcSHADER_Save(binary, buffer, &bufferSize); if (status != gcvSTATUS_OK) { printf("*ERROR* Failed to get the buffer size of the shader\n"); gcoOS_Free(Os, buffer); goto Exit; } OutputShaderData(Os, FileName, bufferSize, buffer); gcoOS_Free(Os, buffer); } Exit: if (DumpLog && log != gcvNULL) { printf("**************** Compile Log ****************"); printf("%s", log); printf("*********************************************"); } if (log != gcvNULL) gcoOS_Free(Os, log); if (source != gcvNULL) gcoOS_Free(Os, source); return binary; }
/******************************************************************************* ** ** gckGALDEVICE_Construct ** ** Constructor. ** ** INPUT: ** ** OUTPUT: ** ** gckGALDEVICE * Device ** Pointer to a variable receiving the gckGALDEVICE object pointer on ** success. */ gceSTATUS gckGALDEVICE_Construct( IN gctINT IrqLine, IN gctUINT32 RegisterMemBase, IN gctSIZE_T RegisterMemSize, IN gctINT IrqLine2D, IN gctUINT32 RegisterMemBase2D, IN gctSIZE_T RegisterMemSize2D, IN gctINT IrqLineVG, IN gctUINT32 RegisterMemBaseVG, IN gctSIZE_T RegisterMemSizeVG, IN gctUINT32 ContiguousBase, IN gctSIZE_T ContiguousSize, IN gctSIZE_T BankSize, IN gctINT FastClear, IN gctINT Compression, IN gctUINT32 PhysBaseAddr, IN gctUINT32 PhysSize, IN gctINT Signal, OUT gckGALDEVICE *Device ) { gctUINT32 internalBaseAddress = 0, internalAlignment = 0; gctUINT32 externalBaseAddress = 0, externalAlignment = 0; gctUINT32 horizontalTileSize, verticalTileSize; struct resource* mem_region; gctUINT32 physAddr; gctUINT32 physical; gckGALDEVICE device; gceSTATUS status; gctINT32 i; gceHARDWARE_TYPE type; gckDB sharedDB = gcvNULL; gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u " "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u " "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u " "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu " "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d", IrqLine, RegisterMemBase, RegisterMemSize, IrqLine2D, RegisterMemBase2D, RegisterMemSize2D, IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG, ContiguousBase, ContiguousSize, BankSize, FastClear, Compression, PhysBaseAddr, PhysSize, Signal); /* Allocate device structure. */ device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN); if (!device) { gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } memset(device, 0, sizeof(struct _gckGALDEVICE)); if (IrqLine != -1) { device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase; device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize; } if (IrqLine2D != -1) { device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D; device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D; } if (IrqLineVG != -1) { device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG; device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG; } device->requestedContiguousBase = 0; device->requestedContiguousSize = 0; for (i = 0; i < gcdCORE_COUNT; i++) { physical = device->requestedRegisterMemBases[i]; /* Set up register memory region. */ if (physical != 0) { mem_region = request_mem_region( physical, device->requestedRegisterMemSizes[i], "galcore register region" ); #if 0 if (mem_region == gcvNULL) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to claim %lu bytes @ 0x%08X\n", __FUNCTION__, __LINE__, physical, device->requestedRegisterMemSizes[i] ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } #endif device->registerBases[i] = (gctPOINTER) ioremap_nocache( physical, device->requestedRegisterMemSizes[i]); if (device->registerBases[i] == gcvNULL) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Unable to map %ld bytes @ 0x%08X\n", __FUNCTION__, __LINE__, physical, device->requestedRegisterMemSizes[i] ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } physical += device->requestedRegisterMemSizes[i]; } else { device->registerBases[i] = gcvNULL; } } /* Set the base address */ device->baseAddress = PhysBaseAddr; /* Construct the gckOS object. */ gcmkONERROR(gckOS_Construct(device, &device->os)); if (IrqLine != -1) { /* Construct the gckKERNEL object. */ gcmkONERROR(gckKERNEL_Construct( device->os, gcvCORE_MAJOR, device, gcvNULL, &device->kernels[gcvCORE_MAJOR])); sharedDB = device->kernels[gcvCORE_MAJOR]->db; /* Initialize core mapping */ for (i = 0; i < 8; i++) { device->coreMapping[i] = gcvCORE_MAJOR; } /* Setup the ISR manager. */ gcmkONERROR(gckHARDWARE_SetIsrManager( device->kernels[gcvCORE_MAJOR]->hardware, (gctISRMANAGERFUNC) gckGALDEVICE_Setup_ISR, (gctISRMANAGERFUNC) gckGALDEVICE_Release_ISR, device )); gcmkONERROR(gckHARDWARE_SetFastClear( device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression )); #if COMMAND_PROCESSOR_VERSION == 1 /* Start the command queue. */ gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_MAJOR]->command)); #endif } else { device->kernels[gcvCORE_MAJOR] = gcvNULL; } if (IrqLine2D != -1) { gcmkONERROR(gckKERNEL_Construct( device->os, gcvCORE_2D, device, sharedDB, &device->kernels[gcvCORE_2D])); if (sharedDB == gcvNULL) sharedDB = device->kernels[gcvCORE_2D]->db; /* Verify the hardware type */ gcmkONERROR(gckHARDWARE_GetType(device->kernels[gcvCORE_2D]->hardware, &type)); if (type != gcvHARDWARE_2D) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Unexpected hardware type: %d\n", __FUNCTION__, __LINE__, type ); gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } /* Initialize core mapping */ if (device->kernels[gcvCORE_MAJOR] == gcvNULL) { for (i = 0; i < 8; i++) { device->coreMapping[i] = gcvCORE_2D; } } else { device->coreMapping[gcvHARDWARE_2D] = gcvCORE_2D; } /* Setup the ISR manager. */ gcmkONERROR(gckHARDWARE_SetIsrManager( device->kernels[gcvCORE_2D]->hardware, (gctISRMANAGERFUNC) gckGALDEVICE_Setup_ISR_2D, (gctISRMANAGERFUNC) gckGALDEVICE_Release_ISR_2D, device )); #if COMMAND_PROCESSOR_VERSION == 1 /* Start the command queue. */ gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_2D]->command)); #endif } else { device->kernels[gcvCORE_2D] = gcvNULL; } if (IrqLineVG != -1) { #if gcdENABLE_VG gcmkONERROR(gckKERNEL_Construct( device->os, gcvCORE_VG, device, sharedDB, &device->kernels[gcvCORE_VG])); /* Initialize core mapping */ if (device->kernels[gcvCORE_MAJOR] == gcvNULL && device->kernels[gcvCORE_2D] == gcvNULL ) { for (i = 0; i < 8; i++) { device->coreMapping[i] = gcvCORE_VG; } } else { device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG; } #endif } else { device->kernels[gcvCORE_VG] = gcvNULL; } /* Initialize the ISR. */ device->irqLines[gcvCORE_MAJOR] = IrqLine; device->irqLines[gcvCORE_2D] = IrqLine2D; device->irqLines[gcvCORE_VG] = IrqLineVG; /* Initialize the kernel thread semaphores. */ for (i = 0; i < gcdCORE_COUNT; i++) { if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0); } device->signal = Signal; for (i = 0; i < gcdCORE_COUNT; i++) { if (device->kernels[i] != gcvNULL) break; } if (i == gcdCORE_COUNT) gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); #if gcdENABLE_VG if (i == gcvCORE_VG) { /* Query the ceiling of the system memory. */ gcmkONERROR(gckVGHARDWARE_QuerySystemMemory( device->kernels[i]->vg->hardware, &device->systemMemorySize, &device->systemMemoryBaseAddress )); /* query the amount of video memory */ gcmkONERROR(gckVGHARDWARE_QueryMemory( device->kernels[i]->vg->hardware, &device->internalSize, &internalBaseAddress, &internalAlignment, &device->externalSize, &externalBaseAddress, &externalAlignment, &horizontalTileSize, &verticalTileSize )); } else #endif { /* Query the ceiling of the system memory. */ gcmkONERROR(gckHARDWARE_QuerySystemMemory( device->kernels[i]->hardware, &device->systemMemorySize, &device->systemMemoryBaseAddress )); /* query the amount of video memory */ gcmkONERROR(gckHARDWARE_QueryMemory( device->kernels[i]->hardware, &device->internalSize, &internalBaseAddress, &internalAlignment, &device->externalSize, &externalBaseAddress, &externalAlignment, &horizontalTileSize, &verticalTileSize )); } /* Set up the internal memory region. */ if (device->internalSize > 0) { status = gckVIDMEM_Construct( device->os, internalBaseAddress, device->internalSize, internalAlignment, 0, &device->internalVidMem ); if (gcmIS_ERROR(status)) { /* Error, disable internal heap. */ device->internalSize = 0; } else { /* Map internal memory. */ device->internalLogical = (gctPOINTER) ioremap_nocache(physical, device->internalSize); if (device->internalLogical == gcvNULL) { gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } device->internalPhysical = (gctPHYS_ADDR) physical; physical += device->internalSize; } } if (device->externalSize > 0) { /* create the external memory heap */ status = gckVIDMEM_Construct( device->os, externalBaseAddress, device->externalSize, externalAlignment, 0, &device->externalVidMem ); if (gcmIS_ERROR(status)) { /* Error, disable internal heap. */ device->externalSize = 0; } else { /* Map external memory. */ device->externalLogical = (gctPOINTER) ioremap_nocache(physical, device->externalSize); if (device->externalLogical == gcvNULL) { gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } device->externalPhysical = (gctPHYS_ADDR) physical; physical += device->externalSize; } } /* set up the contiguous memory */ device->contiguousSize = ContiguousSize; if (ContiguousSize > 0) { if (ContiguousBase == 0) { while (device->contiguousSize > 0) { /* Allocate contiguous memory. */ status = _AllocateMemory( device, device->contiguousSize, &device->contiguousBase, &device->contiguousPhysical, &physAddr ); if (gcmIS_SUCCESS(status)) { status = gckVIDMEM_Construct( device->os, physAddr | device->systemMemoryBaseAddress, device->contiguousSize, 64, BankSize, &device->contiguousVidMem ); if (gcmIS_SUCCESS(status)) { break; } gcmkONERROR(_FreeMemory( device, device->contiguousBase, device->contiguousPhysical )); device->contiguousBase = gcvNULL; device->contiguousPhysical = gcvNULL; } if (device->contiguousSize <= (4 << 20)) { device->contiguousSize = 0; } else { device->contiguousSize -= (4 << 20); } } } else { /* Create the contiguous memory heap. */ status = gckVIDMEM_Construct( device->os, (ContiguousBase - device->baseAddress) | device->systemMemoryBaseAddress, ContiguousSize, 64, BankSize, &device->contiguousVidMem ); if (gcmIS_ERROR(status)) { /* Error, disable contiguous memory pool. */ device->contiguousVidMem = gcvNULL; device->contiguousSize = 0; } else { mem_region = request_mem_region( ContiguousBase, ContiguousSize, "galcore managed memory" ); #if 0 if (mem_region == gcvNULL) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to claim %ld bytes @ 0x%08X\n", __FUNCTION__, __LINE__, ContiguousSize, ContiguousBase ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } #endif device->requestedContiguousBase = ContiguousBase; device->requestedContiguousSize = ContiguousSize; #if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG if (gcmIS_CORE_PRESENT(device, gcvCORE_VG)) { device->contiguousBase #if gcdPAGED_MEMORY_CACHEABLE = (gctPOINTER) ioremap_cached(ContiguousBase, ContiguousSize); #else = (gctPOINTER) ioremap_nocache(ContiguousBase, ContiguousSize); #endif if (device->contiguousBase == gcvNULL) { device->contiguousVidMem = gcvNULL; device->contiguousSize = 0; gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } } #endif device->contiguousPhysical = (gctPHYS_ADDR) ContiguousBase; device->contiguousSize = ContiguousSize; device->contiguousMapped = gcvTRUE; } } }
gceSTATUS ppoPREPROCESSOR_MacroExpand( ppoPREPROCESSOR PP, ppoINPUT_STREAM *IS, ppoTOKEN *Head, ppoTOKEN *End, gctBOOL *AnyExpanationHappened) { gceSTATUS status = gcvSTATUS_INVALID_DATA; ppoTOKEN *headtail = gcvNULL; ppoTOKEN *expanded_headtail = gcvNULL; gctBOOL match_case = gcvFALSE; ppoTOKEN id = gcvNULL; ppoMACRO_SYMBOL ms = gcvNULL; gctPOINTER pointer = gcvNULL; if ((*IS) == gcvNULL) { *AnyExpanationHappened = gcvFALSE; *Head = gcvNULL; *End = gcvNULL; return gcvSTATUS_OK; } gcmONERROR( ppoPREPROCESSOR_MacroExpand_0_SelfContain(PP, IS, Head, End, AnyExpanationHappened, &match_case, &id) ); if (match_case == gcvTRUE) return gcvSTATUS_OK; gcmONERROR( ppoPREPROCESSOR_MacroExpand_1_NotMacroSymbol(PP, IS, Head, End, AnyExpanationHappened, &match_case, id, &ms) ); if (match_case == gcvTRUE) return gcvSTATUS_OK; gcmONERROR( ppoPREPROCESSOR_MacroExpand_2_NoFormalArgs(PP, IS, Head, End, AnyExpanationHappened, &match_case, id, ms) ); if (match_case == gcvTRUE) return gcvSTATUS_OK; gcmONERROR( ppoPREPROCESSOR_MacroExpand_3_NoMoreTokenInIS(PP, IS, Head, End, AnyExpanationHappened, &match_case, id) ); if (match_case == gcvTRUE) return gcvSTATUS_OK; gcmONERROR( ppoPREPROCESSOR_MacroExpand_4_NoRealArg(PP, IS, Head, End, AnyExpanationHappened, &match_case, id) ); if (match_case == gcvTRUE) return gcvSTATUS_OK; status = sloCOMPILER_Allocate( PP->compiler, sizeof(ppoTOKEN)*2*(ms->argc), &pointer ); if (gcmIS_ERROR(status)) return status; headtail = pointer; gcoOS_MemFill((gctPOINTER)headtail, 0, sizeof(ppoTOKEN) * 2 * (ms->argc)); gcmONERROR(sloCOMPILER_Allocate( PP->compiler, sizeof(ppoTOKEN)*2*(ms->argc), (void*)&expanded_headtail)); gcoOS_MemFill((gctPOINTER)expanded_headtail, 0, sizeof(ppoTOKEN) * 2 * (ms->argc)); gcmONERROR( ppoPREPROCESSOR_MacroExpand_5_BufferRealArgs(PP, IS, headtail, id, ms) ); if (match_case == gcvTRUE) return gcvSTATUS_OK; gcmONERROR( ppoPREPROCESSOR_MacroExpand_6_ExpandHeadTail(PP, IS, headtail, expanded_headtail, id, ms) ); gcmONERROR( ppoPREPROCESSOR_MacroExpand_7_ParseReplacementList(PP, IS, Head, End, AnyExpanationHappened,expanded_headtail, id, ms) ); gcmONERROR( sloCOMPILER_Free(PP->compiler, headtail) ); gcmONERROR( sloCOMPILER_Free(PP->compiler, expanded_headtail) ); return gcvSTATUS_OK; OnError: if (headtail != gcvNULL) { gcmVERIFY_OK(sloCOMPILER_Free(PP->compiler, headtail)); headtail = gcvNULL; } if (expanded_headtail != gcvNULL) { gcmVERIFY_OK(sloCOMPILER_Free(PP->compiler, expanded_headtail)); expanded_headtail = gcvNULL; } return status; }
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; }
/******************************************************************************* ** ** gckKERNEL_Dispatch ** ** Dispatch a command received from the user HAL layer. ** ** INPUT: ** ** gckKERNEL Kernel ** Pointer to an gckKERNEL object. ** ** gctBOOL FromUser ** whether the call is from the user space. ** ** gcsHAL_INTERFACE * Interface ** Pointer to a gcsHAL_INTERFACE structure that defines the command to ** be dispatched. ** ** OUTPUT: ** ** gcsHAL_INTERFACE * Interface ** Pointer to a gcsHAL_INTERFACE structure that receives any data to be ** returned. */ gceSTATUS gckKERNEL_Dispatch( IN gckKERNEL Kernel, IN gctBOOL FromUser, IN OUT gcsHAL_INTERFACE * Interface ) { gceSTATUS status; gctUINT32 bitsPerPixel; gctSIZE_T bytes; gcuVIDMEM_NODE_PTR node; gctBOOL locked = gcvFALSE; gctPHYS_ADDR physical; gctUINT32 address; gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x", Kernel, FromUser, Interface); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); gcmkVERIFY_ARGUMENT(Interface != gcvNULL); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, "Dispatching command %d", Interface->command); /* Dispatch on command. */ switch (Interface->command) { case gcvHAL_GET_BASE_ADDRESS: /* Get base address. */ gcmkONERROR( gckOS_GetBaseAddress(Kernel->os, &Interface->u.GetBaseAddress.baseAddress)); break; case gcvHAL_QUERY_VIDEO_MEMORY: /* Query video memory size. */ gcmkONERROR(gckKERNEL_QueryVideoMemory(Kernel, Interface)); break; case gcvHAL_QUERY_CHIP_IDENTITY: /* Query chip identity. */ gcmkONERROR( gckHARDWARE_QueryChipIdentity( Kernel->hardware, &Interface->u.QueryChipIdentity.chipModel, &Interface->u.QueryChipIdentity.chipRevision, &Interface->u.QueryChipIdentity.chipFeatures, &Interface->u.QueryChipIdentity.chipMinorFeatures, &Interface->u.QueryChipIdentity.chipMinorFeatures1)); /* Query chip specifications. */ gcmkONERROR( gckHARDWARE_QueryChipSpecs( Kernel->hardware, &Interface->u.QueryChipIdentity.streamCount, &Interface->u.QueryChipIdentity.registerMax, &Interface->u.QueryChipIdentity.threadCount, &Interface->u.QueryChipIdentity.shaderCoreCount, &Interface->u.QueryChipIdentity.vertexCacheSize, &Interface->u.QueryChipIdentity.vertexOutputBufferSize)); break; case gcvHAL_MAP_MEMORY: physical = Interface->u.MapMemory.physical; /* Map memory. */ gcmkONERROR( gckKERNEL_MapMemory(Kernel, physical, Interface->u.MapMemory.bytes, &Interface->u.MapMemory.logical)); break; case gcvHAL_UNMAP_MEMORY: physical = Interface->u.UnmapMemory.physical; /* Unmap memory. */ gcmkONERROR( gckKERNEL_UnmapMemory(Kernel, physical, Interface->u.UnmapMemory.bytes, Interface->u.UnmapMemory.logical)); break; case gcvHAL_ALLOCATE_NON_PAGED_MEMORY: /* Allocate non-paged memory. */ #ifdef __QNXNTO__ if (FromUser) { gcmkONERROR( gckOS_AllocateNonPagedMemoryShmPool( Kernel->os, FromUser, Interface->pid, Interface->handle, &Interface->u.AllocateNonPagedMemory.bytes, &Interface->u.AllocateNonPagedMemory.physical, &Interface->u.AllocateNonPagedMemory.logical)); break; } #endif gcmkONERROR( gckOS_AllocateNonPagedMemory( Kernel->os, FromUser, &Interface->u.AllocateNonPagedMemory.bytes, &Interface->u.AllocateNonPagedMemory.physical, &Interface->u.AllocateNonPagedMemory.logical)); break; case gcvHAL_FREE_NON_PAGED_MEMORY: physical = Interface->u.FreeNonPagedMemory.physical; /* Free non-paged memory. */ gcmkONERROR( gckOS_FreeNonPagedMemory(Kernel->os, Interface->u.FreeNonPagedMemory.bytes, physical, Interface->u.FreeNonPagedMemory.logical)); break; case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY: /* Allocate contiguous memory. */ #ifdef __QNXNTO__ if (FromUser) { gcmkONERROR( gckOS_AllocateNonPagedMemoryShmPool( Kernel->os, FromUser, Interface->pid, Interface->handle, &Interface->u.AllocateNonPagedMemory.bytes, &Interface->u.AllocateNonPagedMemory.physical, &Interface->u.AllocateNonPagedMemory.logical)); break; } #endif gcmkONERROR( gckOS_AllocateContiguous( Kernel->os, FromUser, &Interface->u.AllocateContiguousMemory.bytes, &Interface->u.AllocateContiguousMemory.physical, &Interface->u.AllocateContiguousMemory.logical)); break; case gcvHAL_FREE_CONTIGUOUS_MEMORY: physical = Interface->u.FreeContiguousMemory.physical; /* Free contiguous memory. */ gcmkONERROR( gckOS_FreeContiguous(Kernel->os, physical, Interface->u.FreeContiguousMemory.logical, Interface->u.FreeContiguousMemory.bytes)); break; case gcvHAL_ALLOCATE_VIDEO_MEMORY: /* Align width and height to tiles. */ gcmkONERROR( gckHARDWARE_AlignToTile(Kernel->hardware, Interface->u.AllocateVideoMemory.type, &Interface->u.AllocateVideoMemory.width, &Interface->u.AllocateVideoMemory.height, gcvNULL)); /* Convert format into bytes per pixel and bytes per tile. */ gcmkONERROR( gckHARDWARE_ConvertFormat(Kernel->hardware, Interface->u.AllocateVideoMemory.format, &bitsPerPixel, gcvNULL)); /* Compute number of bytes for the allocation. */ bytes = Interface->u.AllocateVideoMemory.width * bitsPerPixel * Interface->u.AllocateVideoMemory.height * Interface->u.AllocateVideoMemory.depth / 8; /* Allocate memory. */ #ifdef __QNXNTO__ gcmkONERROR( _AllocateMemory(Kernel, &Interface->u.AllocateVideoMemory.pool, bytes, 64, Interface->u.AllocateVideoMemory.type, Interface->handle, &Interface->u.AllocateVideoMemory.node)); #else gcmkONERROR( _AllocateMemory(Kernel, &Interface->u.AllocateVideoMemory.pool, bytes, 64, Interface->u.AllocateVideoMemory.type, &Interface->u.AllocateVideoMemory.node)); #endif break; case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY: /* Allocate memory. */ #ifdef __QNXNTO__ gcmkONERROR( _AllocateMemory(Kernel, &Interface->u.AllocateLinearVideoMemory.pool, Interface->u.AllocateLinearVideoMemory.bytes, Interface->u.AllocateLinearVideoMemory.alignment, Interface->u.AllocateLinearVideoMemory.type, Interface->handle, &Interface->u.AllocateLinearVideoMemory.node)); /* Set the current user pid in the node, * which is used while locking memory. */ gcmkVERIFY_OK(gckVIDMEM_SetPID( Interface->u.AllocateLinearVideoMemory.node, Interface->pid)); #else gcmkONERROR( _AllocateMemory(Kernel, &Interface->u.AllocateLinearVideoMemory.pool, Interface->u.AllocateLinearVideoMemory.bytes, Interface->u.AllocateLinearVideoMemory.alignment, Interface->u.AllocateLinearVideoMemory.type, &Interface->u.AllocateLinearVideoMemory.node)); #endif break; case gcvHAL_FREE_VIDEO_MEMORY: #ifdef __QNXNTO__ node = Interface->u.FreeVideoMemory.node; if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM && node->VidMem.logical != gcvNULL) { gcmkONERROR( gckKERNEL_UnmapVideoMemory(Kernel, node->VidMem.logical, Interface->pid, node->VidMem.bytes)); node->VidMem.logical = gcvNULL; } #endif /* Free video memory. */ gcmkONERROR( gckVIDMEM_Free(Interface->u.FreeVideoMemory.node)); break; case gcvHAL_LOCK_VIDEO_MEMORY: /* Lock video memory. */ gcmkONERROR( gckVIDMEM_Lock(Interface->u.LockVideoMemory.node, &Interface->u.LockVideoMemory.address)); locked = gcvTRUE; node = Interface->u.LockVideoMemory.node; if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { /* Map video memory address into user space. */ #ifdef __QNXNTO__ if (node->VidMem.logical == gcvNULL) { gcmkONERROR( gckKERNEL_MapVideoMemory(Kernel, FromUser, Interface->u.LockVideoMemory.address, Interface->pid, node->VidMem.bytes, &node->VidMem.logical)); } Interface->u.LockVideoMemory.memory = node->VidMem.logical; #else gcmkONERROR( gckKERNEL_MapVideoMemory(Kernel, FromUser, Interface->u.LockVideoMemory.address, &Interface->u.LockVideoMemory.memory)); #endif #ifdef __QNXNTO__ /* Add more information to node, which is used while unmapping. */ gcmkVERIFY_OK(gckVIDMEM_SetPID( Interface->u.LockVideoMemory.node, Interface->pid)); #endif } else { /* Copy logical memory for virtual memory. */ Interface->u.LockVideoMemory.memory = node->Virtual.logical; /* Success. */ status = gcvSTATUS_OK; } #if gcdSECURE_USER /* Return logical address as physical address. */ Interface->u.LockVideoMemory.address = gcmPTR2INT(Interface->u.LockVideoMemory.memory); #endif break; case gcvHAL_UNLOCK_VIDEO_MEMORY: /* Unlock video memory. */ node = Interface->u.UnlockVideoMemory.node; /* Unlock video memory. */ gcmkONERROR( gckVIDMEM_Unlock(node, Interface->u.UnlockVideoMemory.type, &Interface->u.UnlockVideoMemory.asynchroneous)); break; case gcvHAL_EVENT_COMMIT: /* Commit an event queue. */ gcmkONERROR( gckEVENT_Commit(Kernel->event, Interface->u.Event.queue)); break; case gcvHAL_COMMIT: /* Commit a command and context buffer. */ gcmkONERROR( gckCOMMAND_Commit(Kernel->command, Interface->u.Commit.commandBuffer, Interface->u.Commit.contextBuffer, Interface->u.Commit.process)); break; case gcvHAL_STALL: /* Stall the command queue. */ gcmkONERROR(gckCOMMAND_Stall(Kernel->command)); break; case gcvHAL_MAP_USER_MEMORY: /* Map user memory to DMA. */ gcmkONERROR( gckOS_MapUserMemory(Kernel->os, Interface->u.MapUserMemory.memory, Interface->u.MapUserMemory.size, &Interface->u.MapUserMemory.info, &Interface->u.MapUserMemory.address)); break; case gcvHAL_UNMAP_USER_MEMORY: address = Interface->u.MapUserMemory.address; /* Unmap user memory. */ gcmkONERROR( gckOS_UnmapUserMemory(Kernel->os, Interface->u.UnmapUserMemory.memory, Interface->u.UnmapUserMemory.size, Interface->u.UnmapUserMemory.info, address)); break; #if !USE_NEW_LINUX_SIGNAL case gcvHAL_USER_SIGNAL: gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, "Dispatching gcvHAL_USER_SIGNAL %d", Interface->u.UserSignal.command); /* Dispatch depends on the user signal subcommands. */ switch(Interface->u.UserSignal.command) { case gcvUSER_SIGNAL_CREATE: /* Create a signal used in the user space. */ gcmkONERROR( gckOS_CreateUserSignal(Kernel->os, Interface->u.UserSignal.manualReset, Interface->u.UserSignal.signalType, &Interface->u.UserSignal.id)); break; case gcvUSER_SIGNAL_DESTROY: /* Destroy the signal. */ gcmkONERROR( gckOS_DestroyUserSignal(Kernel->os, Interface->u.UserSignal.id)); break; case gcvUSER_SIGNAL_SIGNAL: /* Signal the signal. */ gcmkONERROR( gckOS_SignalUserSignal(Kernel->os, Interface->u.UserSignal.id, Interface->u.UserSignal.state)); break; case gcvUSER_SIGNAL_WAIT: /* Wait on the signal. */ status = gckOS_WaitUserSignal(Kernel->os, Interface->u.UserSignal.id, Interface->u.UserSignal.wait); break; default: /* Invalid user signal command. */ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } break; #endif case gcvHAL_SET_POWER_MANAGEMENT_STATE: /* Set the power management state. */ gcmkONERROR( gckHARDWARE_SetPowerManagementState( Kernel->hardware, Interface->u.SetPowerManagement.state)); break; case gcvHAL_QUERY_POWER_MANAGEMENT_STATE: /* Chip is not idle. */ Interface->u.QueryPowerManagement.isIdle = gcvFALSE; /* Query the power management state. */ gcmkONERROR(gckHARDWARE_QueryPowerManagementState( Kernel->hardware, &Interface->u.QueryPowerManagement.state)); /* Query the idle state. */ gcmkONERROR( gckHARDWARE_QueryIdle(Kernel->hardware, &Interface->u.QueryPowerManagement.isIdle)); break; case gcvHAL_READ_REGISTER: #if gcdREGISTER_ACCESS_FROM_USER /* Read a register. */ gcmkONERROR( gckOS_ReadRegister(Kernel->os, Interface->u.ReadRegisterData.address, &Interface->u.ReadRegisterData.data)); #else /* No access from user land to read registers. */ Interface->u.ReadRegisterData.data = 0; status = gcvSTATUS_NOT_SUPPORTED; #endif break; case gcvHAL_WRITE_REGISTER: #if gcdREGISTER_ACCESS_FROM_USER /* Write a register. */ gcmkONERROR( gckOS_WriteRegister(Kernel->os, Interface->u.WriteRegisterData.address, Interface->u.WriteRegisterData.data)); #else /* No access from user land to write registers. */ status = gcvSTATUS_NOT_SUPPORTED; #endif break; case gcvHAL_READ_ALL_PROFILE_REGISTERS: #if VIVANTE_PROFILER /* Read all 3D profile registers. */ gcmkONERROR( gckHARDWARE_QueryProfileRegisters( Kernel->hardware, &Interface->u.RegisterProfileData.counters)); #else status = gcvSTATUS_OK; #endif break; case gcvHAL_PROFILE_REGISTERS_2D: #if VIVANTE_PROFILER /* Read all 2D profile registers. */ gcmkONERROR( gckHARDWARE_ProfileEngine2D( Kernel->hardware, Interface->u.RegisterProfileData2D.hwProfile2D)); #else status = gcvSTATUS_OK; #endif break; case gcvHAL_GET_PROFILE_SETTING: #if VIVANTE_PROFILER /* Get profile setting */ Interface->u.GetProfileSetting.enable = Kernel->profileEnable; gcmkVERIFY_OK( gckOS_MemCopy(Interface->u.GetProfileSetting.fileName, Kernel->profileFileName, gcdMAX_PROFILE_FILE_NAME)); #endif status = gcvSTATUS_OK; break; case gcvHAL_SET_PROFILE_SETTING: #if VIVANTE_PROFILER /* Set profile setting */ Kernel->profileEnable = Interface->u.SetProfileSetting.enable; gcmkVERIFY_OK( gckOS_MemCopy(Kernel->profileFileName, Interface->u.SetProfileSetting.fileName, gcdMAX_PROFILE_FILE_NAME)); #endif status = gcvSTATUS_OK; break; case gcvHAL_QUERY_KERNEL_SETTINGS: /* Get kernel settings. */ gcmkONERROR( gckKERNEL_QuerySettings(Kernel, &Interface->u.QueryKernelSettings.settings)); break; case gcvHAL_RESET: /* Reset the hardware. */ gcmkONERROR( gckHARDWARE_Reset(Kernel->hardware)); break; case gcvHAL_DEBUG: /* Set debug level and zones. */ if (Interface->u.Debug.set) { gckOS_SetDebugLevel(Interface->u.Debug.level); gckOS_SetDebugZones(Interface->u.Debug.zones, Interface->u.Debug.enable); } if (Interface->u.Debug.message[0] != '\0') { /* Print a message to the debugger. */ gcmkPRINT(Interface->u.Debug.message); } status = gcvSTATUS_OK; break; case gcvHAL_CACHE: if (Interface->u.Cache.invalidate) { /* Flush and invalidate the cache. */ status = gckOS_CacheInvalidate(Kernel->os, Interface->u.Cache.process, Interface->u.Cache.logical, Interface->u.Cache.bytes); } else { /* Flush the cache. */ status = gckOS_CacheFlush(Kernel->os, Interface->u.Cache.process, Interface->u.Cache.logical, Interface->u.Cache.bytes); } break; default: /* Invalid command. */ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } OnError: /* Save status. */ Interface->status = status; if (gcmIS_ERROR(status)) { if (locked) { /* Roll back the lock. */ gcmkVERIFY_OK( gckVIDMEM_Unlock(Interface->u.LockVideoMemory.node, gcvSURF_TYPE_UNKNOWN, gcvNULL)); } } /* Return the status. */ gcmkFOOTER(); return status; }
static int __init gpu_init(void) { int ret = 0; memset(&platform, 0, sizeof(gcsPLATFORM)); gckPLATFORM_QueryOperations(&platform.ops); if (platform.ops == gcvNULL) { printk(KERN_ERR "galcore: No platform specific operations.\n"); ret = -ENODEV; goto out; } if (platform.ops->allocPriv) { /* Allocate platform private data. */ if (gcmIS_ERROR(platform.ops->allocPriv(&platform))) { ret = -ENOMEM; goto out; } } if (platform.ops->needAddDevice && platform.ops->needAddDevice(&platform)) { /* Allocate device */ platform.device = platform_device_alloc(DEVICE_NAME, -1); if (!platform.device) { printk(KERN_ERR "galcore: platform_device_alloc failed.\n"); ret = -ENOMEM; goto out; } /* Add device */ ret = platform_device_add(platform.device); if (ret) { printk(KERN_ERR "galcore: platform_device_add failed.\n"); goto put_dev; } } platform.driver = &gpu_driver; if (platform.ops->adjustDriver) { /* Override default platform_driver struct. */ platform.ops->adjustDriver(&platform); } ret = platform_driver_register(&gpu_driver); if (!ret) { goto out; } platform_device_del(platform.device); put_dev: platform_device_put(platform.device); out: return ret; }
static int __devinit gpu_resume(struct platform_device *dev) { gceSTATUS status = gcvSTATUS_OK; gckGALDEVICE device; gctINT i; gctINT ret = 0; gceCHIPPOWERSTATE statesStored; device = platform_get_drvdata(dev); printk("[galcore] enter %s\n", __FUNCTION__); for (i = 0; i < gcdMAX_GPU_COUNT; i++) { if (device->kernels[i] != gcvNULL) { #if gcdENABLE_VG if (i == gcvCORE_VG) { status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON); } else #endif { status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON); } if (gcmIS_ERROR(status)) { ret = -1; goto err_out; } /* Convert global state to crossponding internal state. */ switch(device->statesStored[i]) { case gcvPOWER_OFF: statesStored = gcvPOWER_OFF_BROADCAST; break; case gcvPOWER_IDLE: statesStored = gcvPOWER_IDLE_BROADCAST; break; case gcvPOWER_SUSPEND: statesStored = gcvPOWER_SUSPEND_BROADCAST; break; case gcvPOWER_ON: statesStored = gcvPOWER_ON_AUTO; break; default: statesStored = device->statesStored[i]; break; } /* Restore states. */ #if gcdENABLE_VG if (i == gcvCORE_VG) { status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored); } else #endif { status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, statesStored); } if (gcmIS_ERROR(status)) { ret = -1; goto err_out; } #if MRVL_CONFIG_ENABLE_EARLYSUSPEND galDevice->currentPMode = gcvPM_EARLY_SUSPEND; #else galDevice->currentPMode = gcvPM_NORMAL; #endif } } err_out: printk("[galcore] exit %s, return %d\n", __FUNCTION__, ret); return ret; }
gceSTATUS _StretchBlitPE1x( IN gcsCOPYBIT_CONTEXT * Context, IN struct copybit_image_t const * Dest, IN struct copybit_image_t const * Source, IN struct copybit_rect_t const * DestRect, IN struct copybit_rect_t const * SourceRect, IN struct copybit_region_t const * Clip) { gceSTATUS status = gcvSTATUS_OK; gceSURF_FORMAT siFormat; gceSURF_FORMAT diFormat; gctUINT32 diPhysical = ~0; gctUINT32 diAlignedWidth; gctUINT32 diAlignedHeight; gctINT diStride; gcsRECT srcRect; gcsRECT dstRect; copybit_rect_t rect; gctUINT32 srcPhysical = ~0; gctINT srcStride; gctUINT32 srcAlignedWidth; gctUINT32 srcAlignedHeight; gceSURF_FORMAT srcFormat; gctUINT32 dstPhysical = ~0; gctINT dstStride; gctUINT32 dstAlignedWidth; gctUINT32 dstAlignedHeight; gceSURF_FORMAT dstFormat; gctBOOL stretch = gcvFALSE; gctBOOL yuvFormat = gcvFALSE; gctBOOL perpixelAlpha; gc_private_handle_t* dsthnd = (gc_private_handle_t *) Dest->handle; gc_private_handle_t* srchnd = (gc_private_handle_t *) Source->handle; LOGV("Blit from Source hnd=%p, to Dest hnd=%p", srchnd, dsthnd); if (gc_private_handle_t::validate(dsthnd) < 0) { gcmTRACE(gcvLEVEL_ERROR, "Invalid hnd in funciton %s", __func__); return gcvSTATUS_INVALID_ARGUMENT; } siFormat = (gceSURF_FORMAT) srchnd->format; diFormat = (gceSURF_FORMAT) dsthnd->format; if ((siFormat == gcvSURF_UNKNOWN) || (diFormat == gcvSURF_UNKNOWN) ) { gcmTRACE(gcvLEVEL_ERROR, "Image format not support in copybit!"); return gcvSTATUS_INVALID_ARGUMENT; } /* Convert to supported Source format. */ siFormat = (siFormat == gcvSURF_A8B8G8R8) ? gcvSURF_A8R8G8B8 : siFormat; siFormat = (siFormat == gcvSURF_X8B8G8R8) ? gcvSURF_X8R8G8B8 : siFormat; /* Convert to supported Dest format. */ diFormat = (diFormat == gcvSURF_A8B8G8R8) ? gcvSURF_A8R8G8B8 : diFormat; diFormat = (diFormat == gcvSURF_X8B8G8R8) ? gcvSURF_X8R8G8B8 : diFormat; do { srcPhysical = srchnd->phys; gcoSURF_GetAlignedSize((gcoSURF) srchnd->surface, &srcAlignedWidth, &srcAlignedHeight, &srcStride); diPhysical = dsthnd->phys; gcoSURF_GetAlignedSize((gcoSURF) dsthnd->surface, &diAlignedWidth, &diAlignedHeight, &diStride); if ((((gcoSURF)srchnd->surface)->info.type == gcvSURF_BITMAP) && !(srchnd->flags & gc_private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) { /* Clean the CPU cache. Source would've been rendered by the CPU. */ gcmERR_BREAK( gcoSURF_CPUCacheOperation( (gcoSURF) srchnd->surface, gcvCACHE_CLEAN ) ); } perpixelAlpha = _HasAlpha(siFormat) && (dsthnd->flags & gc_private_handle_t::PRIV_FLAGS_FRAMEBUFFER) && !(srchnd->flags & gc_private_handle_t::PRIV_FLAGS_FRAMEBUFFER); if (Context->perpixelAlpha != perpixelAlpha) { Context->perpixelAlpha = perpixelAlpha; if (Context->planeAlpha == 0xff) { Context->dirty.s.alphaKey = 1; } } /* Need temp surface if source has alpha channel, but dest not. */ Context->needAlphaDest = Context->perpixelAlpha && !_HasAlpha(diFormat); if (Context->needAlphaDest) { gcsRECT tempRect; tempRect.left = gcmMAX(0, DestRect->l); tempRect.top = gcmMAX(0, DestRect->t); tempRect.right = gcmMIN((int32_t) Dest->w, DestRect->r); tempRect.bottom = gcmMIN((int32_t) Dest->h, DestRect->b); gcmERR_BREAK( _FitSurface(Context, &Context->alphaDest, Dest->w, Dest->h)); if (Context->alphaDest.surface == gcvNULL) { gcmTRACE(gcvLEVEL_ERROR, "fail to construct tmp surface for per_pixel_alpha"); break; } /* Copy dest surface to temp surface. */ gcmERR_BREAK( _MonoBlit(Context, diPhysical, diStride, diFormat, Context->alphaDest.physical, Context->alphaDest.stride, Context->alphaDest.format, &tempRect)); } gcmERR_BREAK( _UploadStates(Context)); if (Context->needAlphaDest) { dstPhysical = Context->alphaDest.physical; dstStride = Context->alphaDest.stride; dstAlignedWidth = Context->alphaDest.alignedWidth; dstAlignedHeight = Context->alphaDest.alignedHeight; dstFormat = Context->alphaDest.format; } else { dstPhysical = diPhysical; dstStride = diStride; dstAlignedWidth = diAlignedWidth; dstAlignedHeight = diAlignedHeight; dstFormat = diFormat; } srcFormat = siFormat; if (Context->transform == COPYBIT_TRANSFORM_ROT_270) { srcRect.left = SourceRect->t; srcRect.top = Source->w - SourceRect->r; srcRect.right = SourceRect->b; srcRect.bottom = Source->w - SourceRect->l; } else { srcRect.left = SourceRect->l; srcRect.top = SourceRect->t; srcRect.right = SourceRect->r; srcRect.bottom = SourceRect->b; } if (Context->transform == COPYBIT_TRANSFORM_ROT_90) { dstRect.left = DestRect->t; dstRect.top = Dest->w - DestRect->r; dstRect.right = DestRect->b; dstRect.bottom = Dest->w - DestRect->l; } else { dstRect.left = DestRect->l; dstRect.top = DestRect->t; dstRect.right = DestRect->r; dstRect.bottom = DestRect->b; } /* Check yuv format. */ yuvFormat = (srcFormat == gcvSURF_YUY2 || srcFormat == gcvSURF_UYVY); stretch = (srcRect.right - srcRect.left) != (dstRect.right - dstRect.left) || (srcRect.bottom - srcRect.top) != (dstRect.bottom - dstRect.top); /* Upload stretch factor. */ if (stretch) { int hFactor; int vFactor; if ((dstRect.right-dstRect.left) > 1 && (dstRect.bottom-dstRect.top) > 1) { hFactor = ((srcRect.right - srcRect.left - 1) << 16) / (dstRect.right - dstRect.left - 1); vFactor = ((srcRect.bottom - srcRect.top - 1) << 16) / (dstRect.bottom - dstRect.top - 1); } else { hFactor = 0; vFactor = 0; } gcmERR_BREAK( gco2D_SetStretchFactors(Context->engine, hFactor, vFactor)); } /* Prepare source and target for normal blit. */ gcmERR_BREAK( gco2D_SetColorSource(Context->engine, srcPhysical, srcStride, srcFormat, Context->srcRotation, srcAlignedWidth, gcvFALSE, gcvSURF_OPAQUE, 0)); gcmERR_BREAK( gco2D_SetSource(Context->engine, &srcRect)); gcmERR_BREAK( gco2D_SetTarget(Context->engine, dstPhysical, dstStride, Context->dstRotation, dstAlignedWidth)); gcsRECT srcRectBackup = srcRect; gcsRECT dstRectBackup = dstRect; /* Go though all clip rectangles. */ while (Clip->next(Clip, &rect)) { gcsRECT clipRect; srcRect = srcRectBackup; dstRect = dstRectBackup; if (Context->transform == COPYBIT_TRANSFORM_ROT_90) { clipRect.left = rect.t; clipRect.top = Dest->w - rect.r; clipRect.right = rect.b; clipRect.bottom = Dest->w - rect.l; } else if (Context->transform == COPYBIT_TRANSFORM_ROT_180) { float hfactor = (float) (SourceRect->r - SourceRect->l) / (DestRect->r - DestRect->l); float vfactor = (float) (SourceRect->b - SourceRect->t) / (DestRect->b - DestRect->t); /* Intersect. */ clipRect.left = gcmMAX(dstRect.left, rect.l); clipRect.top = gcmMAX(dstRect.top, rect.t); clipRect.right = gcmMIN(dstRect.right, rect.r); clipRect.bottom = gcmMIN(dstRect.bottom, rect.b); /* Adjust src rectangle. */ srcRect.left += (int) ((dstRect.right - clipRect.right) * hfactor); srcRect.top += (int) ((dstRect.bottom - clipRect.bottom) * vfactor); srcRect.right -= (int) ((clipRect.left - dstRect.left) * hfactor); srcRect.bottom -= (int) ((clipRect.top - dstRect.top) * vfactor); /* Set dstRect to clip rectangle. */ dstRect = clipRect; if ((srcRect.left != srcRectBackup.left) || (srcRect.right != srcRectBackup.right) || (srcRect.top != srcRectBackup.top) || (srcRect.bottom != srcRectBackup.bottom) ) { gcmERR_BREAK( gco2D_SetSource(Context->engine, &srcRect)); } } else { clipRect.left = rect.l; clipRect.top = rect.t; clipRect.right = rect.r; clipRect.bottom = rect.b; } /* Clamp clip rectangle. */ if (clipRect.right > dstRect.right) clipRect.right = dstRect.right; if (clipRect.bottom > dstRect.bottom) clipRect.bottom = dstRect.bottom; if (clipRect.left < dstRect.left) clipRect.left = dstRect.left; if (clipRect.top < dstRect.top) clipRect.top = dstRect.top; gcmERR_BREAK( gco2D_SetClipping(Context->engine, &clipRect)); if (yuvFormat) { /* TODO: FilterBlit does not support rotation before PE20. */ /* Video filter blit */ /* 1. SetClipping() has no effect for FilterBlit() * so we use dstSubRect to realize clipping effect * 2. Only FilterBlit support yuv format covertion. */ gcsRECT dstSubRect; int dstWidth = dstRect.right - dstRect.left; int dstHeight = dstRect.bottom - dstRect.top; int clipWidth = clipRect.right - clipRect.left; int clipHeight = clipRect.bottom - clipRect.top; dstSubRect.left = clipRect.left - dstRect.left; dstSubRect.top = clipRect.top - dstRect.top; dstSubRect.right = dstWidth < clipWidth ? dstSubRect.left + dstWidth : dstSubRect.left + clipWidth; dstSubRect.bottom = dstHeight < clipHeight ? dstSubRect.top + dstHeight : dstSubRect.top + clipHeight; gcmERR_BREAK( gco2D_SetKernelSize(Context->engine, gcdFILTER_BLOCK_SIZE, gcdFILTER_BLOCK_SIZE)); gcmERR_BREAK( gco2D_SetFilterType(Context->engine, gcvFILTER_SYNC)); gcmERR_BREAK( gco2D_FilterBlit(Context->engine, srcPhysical, srcStride, 0, 0, 0, 0, srcFormat, Context->srcRotation, srcAlignedWidth, &srcRect, dstPhysical, dstStride, dstFormat, Context->dstRotation, dstAlignedWidth, &dstRect, &dstSubRect)); } else if (Context->blur) { /* TODO: FilterBlit does not support rotation before PE20. */ gcsRECT dstSubRect; dstSubRect.left = 0; dstSubRect.top = 0; dstSubRect.right = dstRect.right - dstRect.left; dstSubRect.bottom = dstRect.bottom - dstRect.top; /* Blur blit. */ gcmERR_BREAK( gco2D_SetKernelSize(Context->engine, gcdFILTER_BLOCK_SIZE, gcdFILTER_BLOCK_SIZE)); gcmERR_BREAK( gco2D_SetFilterType(Context->engine, gcvFILTER_BLUR)); gcmERR_BREAK( gco2D_FilterBlit(Context->engine, srcPhysical, srcStride, 0, 0, 0, 0, srcFormat, gcvSURF_0_DEGREE, srcAlignedWidth, &srcRect, dstPhysical, dstStride, dstFormat, gcvSURF_0_DEGREE, dstAlignedWidth, &dstRect, &dstSubRect)); gcmERR_BREAK( gco2D_FilterBlit(Context->engine, dstPhysical, dstStride, 0, 0, 0, 0, dstFormat, gcvSURF_0_DEGREE, dstAlignedWidth, &dstRect, dstPhysical, dstStride, dstFormat, gcvSURF_0_DEGREE, dstAlignedWidth, &dstRect, &dstSubRect)); /* TODO: surfaceflinger set blur issue. */ Context->blur = COPYBIT_DISABLE; } else if (stretch == gcvFALSE) { /* BitBlit. */ gcmERR_BREAK( gco2D_Blit(Context->engine, 1, &dstRect, 0xCC, 0xCC, dstFormat)); } else { /* Normal stretch blit. */ gcmERR_BREAK( gco2D_StretchBlit(Context->engine, 1, &dstRect, 0xCC, 0xCC, dstFormat)); } } if (gcmIS_ERROR(status)) { break; } if (Context->needAlphaDest) { gcsRECT tempRect; tempRect.left = gcmMAX(0, DestRect->l); tempRect.top = gcmMAX(0, DestRect->t); tempRect.right = gcmMIN((int32_t) Dest->w, DestRect->r); tempRect.bottom = gcmMIN((int32_t) Dest->h, DestRect->b); /* Blit back to actual dest. */ gcmERR_BREAK( _MonoBlit(Context, Context->alphaDest.physical, Context->alphaDest.stride, Context->alphaDest.format, diPhysical, diStride, diFormat, &tempRect)); } /* Flush and commit. */ gcmERR_BREAK( gco2D_Flush(Context->engine)); gcmERR_BREAK( gcoHAL_Commit(gcvNULL, gcvFALSE)); } while (gcvFALSE); return status; }
static gceSTATUS _DereferenceObjectCache( vgsCONTEXT_PTR Context, vgsOBJECT_CACHE_PTR * ObjectCache ) { /* Define the result and assume success. */ gceSTATUS status = gcvSTATUS_OK; do { vgsOBJECT_PTR object; vgsOBJECT_LIST_PTR objectList; /* Get a shortcut to the object cache. */ vgsOBJECT_CACHE_PTR objectCache = *ObjectCache; /* Existing object cache? */ if (objectCache == gcvNULL) { break; } /* Valid reference count? */ if (objectCache->referenceCount < 1) { gcmFATAL("Invalid reference count found.\n"); status = gcvSTATUS_INVALID_OBJECT; break; } /* Decrement the counter. */ objectCache->referenceCount--; /* Time to destroy? */ if (objectCache->referenceCount == 0) { gctUINT i; /* Delete objects that are still in the cache. */ for (i = 0; i < vgvOBJECTTYPE_COUNT; i++) { gctUINT32 index; /* Get the current object list. */ objectList = &objectCache->cache[i]; for (index = 0; index < vgvNAMED_OBJECTS_HASH; index++) { /* Are there objects in the list? */ if (objectList->head[index] != gcvNULL) { gcmTRACE( gcvLEVEL_ERROR, "%s (%d): object cache %d still has objects in it.\n", __FUNCTION__, __LINE__, i ); /* Delete the objects. */ while (objectList->head[index]) { /* Copy the head object. */ object = objectList->head[index]; /* Dereference it. */ gcmERR_BREAK(vgfDereferenceObject( Context, &object )); } } } /* Error? */ if (gcmIS_ERROR(status)) { break; } } /* Error? */ if (gcmIS_ERROR(status)) { break; } /* Allocate the context structure. */ gcmERR_BREAK(gcoOS_Free( Context->os, (gctPOINTER *) objectCache )); /* Reset the object. */ *ObjectCache = gcvNULL; } } while (gcvFALSE); /* Return status. */ return status; }
/* echo xx > /proc/driver/gc set ... */ static ssize_t gc_proc_write(struct file *file, const char *buff, size_t len, loff_t *off) { char messages[256]; if(len > 256) len = 256; if(copy_from_user(messages, buff, len)) return -EFAULT; printk("\n"); if(strncmp(messages, "printPID", 8) == 0) { galDevice->printPID = galDevice->printPID ? gcvFALSE : gcvTRUE; printk("==>Change printPID to %s\n", galDevice->printPID ? "gcvTRUE" : "gcvFALSE"); } else if(strncmp(messages, "profile", 7) == 0) { gctUINT32 idleTime, timeSlice; gctUINT32 start,end; timeSlice = 10000; start = gckOS_GetTicks(); gckOS_IdleProfile(galDevice->os, &timeSlice, &idleTime); end = gckOS_GetTicks(); printk("idle:total [%d, %d]\n", idleTime, timeSlice); printk("profile cost %d\n", end - start); } else if(strncmp(messages, "hang", 4) == 0) { galDevice->kernel->hardware->hang = galDevice->kernel->hardware->hang ? gcvFALSE : gcvTRUE; } else if(strncmp(messages, "reset", 5) == 0) { galDevice->reset = galDevice->reset ? gcvFALSE : gcvTRUE; } #ifdef CONFIG_PXA_DVFM else if(strncmp(messages, "d2debug", 7) == 0) { galDevice->needD2DebugInfo = galDevice->needD2DebugInfo ? gcvFALSE : gcvTRUE; } else if(strncmp(messages, "D1", 2) == 0) { galDevice->enableD1 = galDevice->enableD1 ? gcvFALSE : gcvTRUE; gckOS_SetConstraint(galDevice->os, gcvTRUE, gcvTRUE); } else if(strncmp(messages, "D2", 2) == 0) { galDevice->enableD2 = galDevice->enableD2 ? gcvFALSE : gcvTRUE; gckOS_SetConstraint(galDevice->os, gcvTRUE, gcvTRUE); } else if(strncmp(messages, "D0", 2) == 0) { galDevice->enableD0CS= galDevice->enableD0CS ? gcvFALSE : gcvTRUE; gckOS_SetConstraint(galDevice->os, gcvTRUE, gcvTRUE); } else if(strncmp(messages, "CG", 2) == 0) { galDevice->enableCG= galDevice->enableCG ? gcvFALSE : gcvTRUE; gckOS_SetConstraint(galDevice->os, gcvTRUE, gcvTRUE); } else if(strncmp(messages, "needreset", 9) == 0) { galDevice->needResetAfterD2 = galDevice->needResetAfterD2 ? gcvFALSE : gcvTRUE; } #endif else if(strncmp(messages, "su", 2) == 0) { gceSTATUS status; if(galDevice->kernel->hardware->chipPowerState != gcvPOWER_OFF) { status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_OFF); if (gcmIS_ERROR(status)) { return -1; } gckOS_SuspendInterrupt(galDevice->os); gckOS_ClockOff(); } } else if(strncmp(messages, "re", 2) == 0) { gceSTATUS status; if(galDevice->kernel->hardware->chipPowerState != gcvPOWER_ON) { gckOS_ClockOn(0); gckOS_ResumeInterrupt(galDevice->os); status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_ON); if (gcmIS_ERROR(status)) { return -1; } } } else if(strncmp(messages, "stress", 6) == 0) { int i; /* struct vmalloc_info vmi; */ /* {get_vmalloc_info(&vmi);printk("%s,%d,VmallocUsed: %8lu kB\n",__func__,__LINE__,vmi.used >> 10); } */ #ifdef _DEBUG gckOS_SetDebugLevel(gcvLEVEL_VERBOSE); gckOS_SetDebugZone(1023); #endif for(i=0;i<20000;i++) { gceSTATUS status; static int count = 0; printk("count:%d\n",count++); printk("!!!\t"); if(galDevice->kernel->hardware->chipPowerState != gcvPOWER_OFF) { status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_OFF); if (gcmIS_ERROR(status)) { return -1; } gckOS_SuspendInterrupt(galDevice->os); gckOS_ClockOff(); } printk("@@@\t"); if(galDevice->kernel->hardware->chipPowerState != gcvPOWER_ON) { gckOS_ClockOn(0); gckOS_ResumeInterrupt(galDevice->os); status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_ON); if (gcmIS_ERROR(status)) { return -1; } } printk("###\n"); } } else if(strncmp(messages, "debug", 5) == 0) { #ifdef _DEBUG static int count = 0; if(count%2 == 0) { gckOS_SetDebugLevel(gcvLEVEL_VERBOSE); gckOS_SetDebugZone(1023); } else { gckOS_SetDebugLevel(gcvLEVEL_NONE); gckOS_SetDebugZone(0); } count++; #endif } else if(strncmp(messages, "16", 2) == 0) { printk("frequency change to 1/16\n"); /* frequency change to 1/16 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x210)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x010)); } else if(strncmp(messages, "32", 2) == 0) { printk("frequency change to 1/32\n"); /* frequency change to 1/32*/ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x208)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x008)); } else if(strncmp(messages, "64", 2) == 0) { printk("frequency change to 1/64\n"); /* frequency change to 1/64 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x204)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x004)); } else if('1' == messages[0]) { printk("frequency change to full speed\n"); /* frequency change to full speed */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x300)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x100)); } else if('2' == messages[0]) { printk("frequency change to 1/2\n"); /* frequency change to 1/2 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x280)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x080)); } else if('4' == messages[0]) { printk("frequency change to 1/4\n"); /* frequency change to 1/4 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x240)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x040)); } else if('8' == messages[0]) { printk("frequency change to 1/8\n"); /* frequency change to 1/8 */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x220)); /* Loading the frequency scaler. */ gcmkVERIFY_OK(gckOS_WriteRegister(galDevice->os,0x00000,0x020)); } else { printk("unknown echo\n"); } return len; }
/******************************************************************************* ** ** _WorkaroundForFilterBlit ** ** Workaround for the dirty region issue of filter blit. ** It only exists for old GC300 before 2.0.2 (included). ** ** INPUT: ** ** gctHAL Hal ** Pointer to HAL. ** ** OUTPUT: ** ** Nothing. */ static gceSTATUS _WorkaroundForFilterBlit( IN gcoHAL Hal ) { gceSTATUS status; gcoSURF srcSurf = gcvNULL; gcsRECT srcRect; gcoSURF dstSurf = gcvNULL; gcsRECT dstRect; do { gcmERR_BREAK(gcoSURF_Construct( gcvNULL, 256, 256, 1, gcvSURF_BITMAP, gcvSURF_A8R8G8B8, gcvPOOL_DEFAULT, &srcSurf )); gcmERR_BREAK(gcoSURF_Construct( gcvNULL, 256, 256, 1, gcvSURF_BITMAP, gcvSURF_A8R8G8B8, gcvPOOL_DEFAULT, &dstSurf )); srcRect.left = 0; srcRect.top = 0; srcRect.right = 64; srcRect.bottom = 16; dstRect.left = 0; dstRect.top = 0; dstRect.right = 128; dstRect.bottom = 32; gcmERR_BREAK(gcoSURF_FilterBlit( srcSurf, dstSurf, &srcRect, &dstRect, gcvNULL )); gcmERR_BREAK(gcoSURF_Destroy(srcSurf)); srcSurf = gcvNULL; gcmERR_BREAK(gcoSURF_Destroy(dstSurf)); dstSurf = gcvNULL; } while(gcvFALSE); if (gcmIS_ERROR(status)) { gcmTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_HAL, "Failed to workarond for GC300."); if (srcSurf) { gcmVERIFY_OK(gcoSURF_Destroy(srcSurf)); } if (dstSurf) { gcmVERIFY_OK(gcoSURF_Destroy(dstSurf)); } } return status; }
/******************************************************************************* ** ** gckGALDEVICE_Construct ** ** Constructor. ** ** INPUT: ** ** OUTPUT: ** ** gckGALDEVICE * Device ** Pointer to a variable receiving the gckGALDEVICE object pointer on ** success. */ gceSTATUS gckGALDEVICE_Construct( IN gctINT IrqLine, IN gctUINT32 RegisterMemBase, IN gctSIZE_T RegisterMemSize, IN gctINT IrqLine2D, IN gctUINT32 RegisterMemBase2D, IN gctSIZE_T RegisterMemSize2D, IN gctINT IrqLineVG, IN gctUINT32 RegisterMemBaseVG, IN gctSIZE_T RegisterMemSizeVG, IN gctUINT32 ContiguousBase, IN gctSIZE_T ContiguousSize, IN gctSIZE_T BankSize, IN gctINT FastClear, IN gctINT Compression, IN gctUINT32 PhysBaseAddr, IN gctUINT32 PhysSize, IN gctINT Signal, IN gctUINT LogFileSize, IN struct device *pdev, IN gctINT PowerManagement, OUT gckGALDEVICE *Device ) { gctUINT32 internalBaseAddress = 0, internalAlignment = 0; gctUINT32 externalBaseAddress = 0, externalAlignment = 0; gctUINT32 horizontalTileSize, verticalTileSize; struct resource* mem_region; gctUINT32 physAddr; gctUINT32 physical; gckGALDEVICE device; gceSTATUS status; gctINT32 i; gceHARDWARE_TYPE type; gckDB sharedDB = gcvNULL; gckKERNEL kernel = gcvNULL; gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u " "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u " "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u " "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu " "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d", IrqLine, RegisterMemBase, RegisterMemSize, IrqLine2D, RegisterMemBase2D, RegisterMemSize2D, IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG, ContiguousBase, ContiguousSize, BankSize, FastClear, Compression, PhysBaseAddr, PhysSize, Signal); /* Allocate device structure. */ device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN); if (!device) { gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } memset(device, 0, sizeof(struct _gckGALDEVICE)); device->dbgnode = gcvNULL; if(LogFileSize != 0) { if(gckDebugFileSystemCreateNode(LogFileSize,PARENT_FILE,DEBUG_FILE,&(device->dbgnode)) != 0) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to create the debug file system %s/%s \n", __FUNCTION__, __LINE__, PARENT_FILE, DEBUG_FILE ); } else { /*Everything is OK*/ gckDebugFileSystemSetCurrentNode(device->dbgnode); } } #ifdef CONFIG_PM /*Init runtime pm for gpu*/ pm_runtime_enable(pdev); device->pmdev = pdev; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) /*get gpu regulator*/ device->gpu_regulator = regulator_get(pdev, "cpu_vddgpu"); if (IS_ERR(device->gpu_regulator)) { gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to get gpu regulator %s/%s \n", __FUNCTION__, __LINE__, PARENT_FILE, DEBUG_FILE); gcmkONERROR(gcvSTATUS_NOT_FOUND); } #endif /*Initialize the clock structure*/ if (IrqLine != -1) { device->clk_3d_core = clk_get(pdev, "gpu3d_clk"); if (!IS_ERR(device->clk_3d_core)) { #if LINUX_VERSION_CODE < KERNEL_VERSION(3,5,0) if (cpu_is_mx6q()) { device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk"); if (IS_ERR(device->clk_3d_shader)) { IrqLine = -1; clk_put(device->clk_3d_core); device->clk_3d_core = NULL; device->clk_3d_shader = NULL; gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n"); } } #else device->clk_3d_axi = clk_get(pdev, "gpu3d_axi_clk"); device->clk_3d_shader = clk_get(pdev, "gpu3d_shader_clk"); if (IS_ERR(device->clk_3d_shader)) { IrqLine = -1; clk_put(device->clk_3d_core); device->clk_3d_core = NULL; device->clk_3d_shader = NULL; gckOS_Print("galcore: clk_get gpu3d_shader_clk failed, disable 3d!\n"); } #endif } else { IrqLine = -1; device->clk_3d_core = NULL; gckOS_Print("galcore: clk_get gpu3d_clk failed, disable 3d!\n"); } } if ((IrqLine2D != -1) || (IrqLineVG != -1)) { device->clk_2d_core = clk_get(pdev, "gpu2d_clk"); if (IS_ERR(device->clk_2d_core)) { IrqLine2D = -1; IrqLineVG = -1; device->clk_2d_core = NULL; gckOS_Print("galcore: clk_get 2d core clock failed, disable 2d/vg!\n"); } else { if (IrqLine2D != -1) { device->clk_2d_axi = clk_get(pdev, "gpu2d_axi_clk"); if (IS_ERR(device->clk_2d_axi)) { device->clk_2d_axi = NULL; IrqLine2D = -1; gckOS_Print("galcore: clk_get 2d axi clock failed, disable 2d\n"); } } if (IrqLineVG != -1) { device->clk_vg_axi = clk_get(pdev, "openvg_axi_clk"); if (IS_ERR(device->clk_vg_axi)) { IrqLineVG = -1; device->clk_vg_axi = NULL; gckOS_Print("galcore: clk_get vg clock failed, disable vg!\n"); } } } } if (IrqLine != -1) { device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase; device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize; } if (IrqLine2D != -1) { device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D; device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D; } if (IrqLineVG != -1) { device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG; device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG; } device->requestedContiguousBase = 0; device->requestedContiguousSize = 0; for (i = 0; i < gcdMAX_GPU_COUNT; i++) { physical = device->requestedRegisterMemBases[i]; /* Set up register memory region. */ if (physical != 0) { mem_region = request_mem_region( physical, device->requestedRegisterMemSizes[i], "galcore register region" ); if (mem_region == gcvNULL) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to claim %lu bytes @ 0x%08X\n", __FUNCTION__, __LINE__, physical, device->requestedRegisterMemSizes[i] ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } device->registerBases[i] = (gctPOINTER) ioremap_nocache( physical, device->requestedRegisterMemSizes[i]); if (device->registerBases[i] == gcvNULL) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Unable to map %ld bytes @ 0x%08X\n", __FUNCTION__, __LINE__, physical, device->requestedRegisterMemSizes[i] ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } physical += device->requestedRegisterMemSizes[i]; } else { device->registerBases[i] = gcvNULL; } } /* Set the base address */ device->baseAddress = PhysBaseAddr; /* Construct the gckOS object. */ gcmkONERROR(gckOS_Construct(device, &device->os)); if (IrqLine != -1) { /* Construct the gckKERNEL object. */ gcmkONERROR(gckKERNEL_Construct( device->os, gcvCORE_MAJOR, device, gcvNULL, &device->kernels[gcvCORE_MAJOR])); sharedDB = device->kernels[gcvCORE_MAJOR]->db; /* Initialize core mapping */ for (i = 0; i < 8; i++) { device->coreMapping[i] = gcvCORE_MAJOR; } /* Setup the ISR manager. */ gcmkONERROR(gckHARDWARE_SetIsrManager( device->kernels[gcvCORE_MAJOR]->hardware, (gctISRMANAGERFUNC) gckGALDEVICE_Setup_ISR, (gctISRMANAGERFUNC) gckGALDEVICE_Release_ISR, device )); gcmkONERROR(gckHARDWARE_SetFastClear( device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression )); gcmkONERROR(gckHARDWARE_SetPowerManagement( device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement )); #if COMMAND_PROCESSOR_VERSION == 1 /* Start the command queue. */ gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_MAJOR]->command)); #endif } else { device->kernels[gcvCORE_MAJOR] = gcvNULL; } if (IrqLine2D != -1) { gcmkONERROR(gckKERNEL_Construct( device->os, gcvCORE_2D, device, sharedDB, &device->kernels[gcvCORE_2D])); if (sharedDB == gcvNULL) sharedDB = device->kernels[gcvCORE_2D]->db; /* Verify the hardware type */ gcmkONERROR(gckHARDWARE_GetType(device->kernels[gcvCORE_2D]->hardware, &type)); if (type != gcvHARDWARE_2D) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Unexpected hardware type: %d\n", __FUNCTION__, __LINE__, type ); gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } /* Initialize core mapping */ if (device->kernels[gcvCORE_MAJOR] == gcvNULL) { for (i = 0; i < 8; i++) { device->coreMapping[i] = gcvCORE_2D; } } else { device->coreMapping[gcvHARDWARE_2D] = gcvCORE_2D; } /* Setup the ISR manager. */ gcmkONERROR(gckHARDWARE_SetIsrManager( device->kernels[gcvCORE_2D]->hardware, (gctISRMANAGERFUNC) gckGALDEVICE_Setup_ISR_2D, (gctISRMANAGERFUNC) gckGALDEVICE_Release_ISR_2D, device )); gcmkONERROR(gckHARDWARE_SetPowerManagement( device->kernels[gcvCORE_2D]->hardware, PowerManagement )); #if COMMAND_PROCESSOR_VERSION == 1 /* Start the command queue. */ gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_2D]->command)); #endif } else { device->kernels[gcvCORE_2D] = gcvNULL; } if (IrqLineVG != -1) { #if gcdENABLE_VG gcmkONERROR(gckKERNEL_Construct( device->os, gcvCORE_VG, device, sharedDB, &device->kernels[gcvCORE_VG])); /* Initialize core mapping */ if (device->kernels[gcvCORE_MAJOR] == gcvNULL && device->kernels[gcvCORE_2D] == gcvNULL ) { for (i = 0; i < 8; i++) { device->coreMapping[i] = gcvCORE_VG; } } else { device->coreMapping[gcvHARDWARE_VG] = gcvCORE_VG; } gcmkONERROR(gckVGHARDWARE_SetPowerManagement( device->kernels[gcvCORE_VG]->vg->hardware, PowerManagement )); #endif } else { device->kernels[gcvCORE_VG] = gcvNULL; } /* Initialize the ISR. */ device->irqLines[gcvCORE_MAJOR] = IrqLine; device->irqLines[gcvCORE_2D] = IrqLine2D; device->irqLines[gcvCORE_VG] = IrqLineVG; /* Initialize the kernel thread semaphores. */ for (i = 0; i < gcdMAX_GPU_COUNT; i++) { if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0); } device->signal = Signal; for (i = 0; i < gcdMAX_GPU_COUNT; i++) { if (device->kernels[i] != gcvNULL) break; } if (i == gcdMAX_GPU_COUNT) { gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); } #if gcdENABLE_VG if (i == gcvCORE_VG) { /* Query the ceiling of the system memory. */ gcmkONERROR(gckVGHARDWARE_QuerySystemMemory( device->kernels[i]->vg->hardware, &device->systemMemorySize, &device->systemMemoryBaseAddress )); /* query the amount of video memory */ gcmkONERROR(gckVGHARDWARE_QueryMemory( device->kernels[i]->vg->hardware, &device->internalSize, &internalBaseAddress, &internalAlignment, &device->externalSize, &externalBaseAddress, &externalAlignment, &horizontalTileSize, &verticalTileSize )); } else #endif { /* Query the ceiling of the system memory. */ gcmkONERROR(gckHARDWARE_QuerySystemMemory( device->kernels[i]->hardware, &device->systemMemorySize, &device->systemMemoryBaseAddress )); /* query the amount of video memory */ gcmkONERROR(gckHARDWARE_QueryMemory( device->kernels[i]->hardware, &device->internalSize, &internalBaseAddress, &internalAlignment, &device->externalSize, &externalBaseAddress, &externalAlignment, &horizontalTileSize, &verticalTileSize )); } /* Grab the first availiable kernel */ for (i = 0; i < gcdMAX_GPU_COUNT; i++) { if (device->irqLines[i] != -1) { kernel = device->kernels[i]; break; } } /* Set up the internal memory region. */ if (device->internalSize > 0) { status = gckVIDMEM_Construct( device->os, internalBaseAddress, device->internalSize, internalAlignment, 0, &device->internalVidMem ); if (gcmIS_ERROR(status)) { /* Error, disable internal heap. */ device->internalSize = 0; } else { /* Map internal memory. */ device->internalLogical = (gctPOINTER) ioremap_nocache(physical, device->internalSize); if (device->internalLogical == gcvNULL) { gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } device->internalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical; device->internalPhysicalName = gcmPTR_TO_NAME(device->internalPhysical); physical += device->internalSize; } } if (device->externalSize > 0) { /* create the external memory heap */ status = gckVIDMEM_Construct( device->os, externalBaseAddress, device->externalSize, externalAlignment, 0, &device->externalVidMem ); if (gcmIS_ERROR(status)) { /* Error, disable internal heap. */ device->externalSize = 0; } else { /* Map external memory. */ device->externalLogical = (gctPOINTER) ioremap_nocache(physical, device->externalSize); if (device->externalLogical == gcvNULL) { gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } device->externalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical; device->externalPhysicalName = gcmPTR_TO_NAME(device->externalPhysical); physical += device->externalSize; } } /* set up the contiguous memory */ device->contiguousSize = ContiguousSize; if (ContiguousSize > 0) { if (ContiguousBase == 0) { while (device->contiguousSize > 0) { /* Allocate contiguous memory. */ status = _AllocateMemory( device, device->contiguousSize, &device->contiguousBase, &device->contiguousPhysical, &physAddr ); if (gcmIS_SUCCESS(status)) { device->contiguousPhysicalName = gcmPTR_TO_NAME(device->contiguousPhysical); status = gckVIDMEM_Construct( device->os, physAddr | device->systemMemoryBaseAddress, device->contiguousSize, 64, BankSize, &device->contiguousVidMem ); if (gcmIS_SUCCESS(status)) { break; } gcmkONERROR(_FreeMemory( device, device->contiguousBase, device->contiguousPhysical )); gcmRELEASE_NAME(device->contiguousPhysicalName); device->contiguousBase = gcvNULL; device->contiguousPhysical = gcvNULL; } if (device->contiguousSize <= (4 << 20)) { device->contiguousSize = 0; } else { device->contiguousSize -= (4 << 20); } } } else { /* Create the contiguous memory heap. */ status = gckVIDMEM_Construct( device->os, ContiguousBase | device->systemMemoryBaseAddress, ContiguousSize, 64, BankSize, &device->contiguousVidMem ); if (gcmIS_ERROR(status)) { /* Error, disable contiguous memory pool. */ device->contiguousVidMem = gcvNULL; device->contiguousSize = 0; } else { mem_region = request_mem_region( ContiguousBase, ContiguousSize, "galcore managed memory" ); if (mem_region == gcvNULL) { gcmkTRACE_ZONE( gcvLEVEL_ERROR, gcvZONE_DRIVER, "%s(%d): Failed to claim %ld bytes @ 0x%08X\n", __FUNCTION__, __LINE__, ContiguousSize, ContiguousBase ); gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } device->requestedContiguousBase = ContiguousBase; device->requestedContiguousSize = ContiguousSize; #if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG if (gcmIS_CORE_PRESENT(device, gcvCORE_VG)) { device->contiguousBase #if gcdPAGED_MEMORY_CACHEABLE = (gctPOINTER) ioremap_cached(ContiguousBase, ContiguousSize); #else = (gctPOINTER) ioremap_nocache(ContiguousBase, ContiguousSize); #endif if (device->contiguousBase == gcvNULL) { device->contiguousVidMem = gcvNULL; device->contiguousSize = 0; gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES); } } #endif device->contiguousPhysical = gcvNULL; device->contiguousPhysicalName = 0; device->contiguousSize = ContiguousSize; device->contiguousMapped = gcvTRUE; } } }
static int __devinit gpu_probe(struct platform_device *pdev) #endif { int ret = -ENODEV; gcsMODULE_PARAMETERS moduleParam = { #if gcdMULTI_GPU || gcdMULTI_GPU_AFFINITY #else .irqLine = irqLine, .registerMemBase = registerMemBase, .registerMemSize = registerMemSize, #endif .irqLine2D = irqLine2D, .registerMemBase2D = registerMemBase2D, .registerMemSize2D = registerMemSize2D, .irqLineVG = irqLineVG, .registerMemBaseVG = registerMemBaseVG, .registerMemSizeVG = registerMemSizeVG, .contiguousSize = contiguousSize, .contiguousBase = contiguousBase, .bankSize = bankSize, .fastClear = fastClear, .compression = compression, .powerManagement = powerManagement, .gpuProfiler = gpuProfiler, .signal = signal, .baseAddress = baseAddress, .physSize = physSize, .logFileSize = logFileSize, .recovery = recovery, .stuckDump = stuckDump, .showArgs = showArgs, .gpu3DMinClock = gpu3DMinClock, }; gcmkHEADER(); platform.device = pdev; if (platform.ops->getPower) { if (gcmIS_ERROR(platform.ops->getPower(&platform))) { gcmkFOOTER_NO(); return ret; } } if (platform.ops->adjustParam) { /* Override default module param. */ platform.ops->adjustParam(&platform, &moduleParam); /* Update module param because drv_init() uses them directly. */ _UpdateModuleParam(&moduleParam); } ret = drv_init(); if (!ret) { platform_set_drvdata(pdev, galDevice); gcmkFOOTER_NO(); return ret; } gcmkFOOTER_ARG(KERN_INFO "Failed to register gpu driver: %d\n", ret); return ret; }
/******************************************************************************* ** InitializeVGProfiler ** ** Initialize the profiler for the context provided. ** ** Arguments: ** ** VGContext Context ** Pointer to a new VGContext object. */ void InitializeVGProfiler( _VGContext * Context ) { gceSTATUS status; gctUINT rev; char *env; status = gcoPROFILER_Initialize(Context->hal); if (gcmIS_ERROR(status)) { Context->profiler.enable = gcvFALSE; return; } /* Clear the profiler. */ gcmVERIFY_OK( gcoOS_ZeroMemory(&Context->profiler, gcmSIZEOF(Context->profiler))); gcoOS_GetEnv(Context->os, "VP_COUNTER_FILTER", &env); if ((env == gcvNULL) || (env[0] ==0)) { Context->profiler.drvEnable = Context->profiler.timeEnable = Context->profiler.memEnable = gcvTRUE; } else { gctSIZE_T bitsLen; gcoOS_StrLen(env, &bitsLen); if (bitsLen > 0) { Context->profiler.timeEnable = (env[0] == '1'); } else { Context->profiler.timeEnable = gcvTRUE; } if (bitsLen > 1) { Context->profiler.memEnable = (env[1] == '1'); } else { Context->profiler.memEnable = gcvTRUE; } if (bitsLen > 4) { Context->profiler.drvEnable = (env[4] == '1'); } else { Context->profiler.drvEnable = gcvTRUE; } } Context->profiler.enable = gcvTRUE; #if gcdNEW_PROFILER_FILE { /* Write Generic Info. */ char* infoCompany = "Vivante Corporation"; char* infoVersion = "1.0"; char infoRevision[255] = {'\0'}; /* read from hw */ char* infoRenderer = Context->chipName; char* infoDriver = "OpenVG 1.1"; gctUINT offset = 0; rev = Context->revision; #define BCD(digit) ((rev >> (digit * 4)) & 0xF) gcoOS_MemFill(infoRevision, 0, gcmSIZEOF(infoRevision)); gcoOS_MemFill(infoRevision, 0, gcmSIZEOF(infoRevision)); if (BCD(3) == 0) { /* Old format. */ gcoOS_PrintStrSafe(infoRevision, gcmSIZEOF(infoRevision), &offset, "revision=\"%d.%d\" ", BCD(1), BCD(0)); } else { /* New format. */ gcoOS_PrintStrSafe(infoRevision, gcmSIZEOF(infoRevision), &offset, "revision=\"%d.%d.%d_rc%d\" ", BCD(3), BCD(2), BCD(1), BCD(0)); } gcmWRITE_CONST(VPG_INFO); gcmWRITE_CONST(VPC_INFOCOMPANY); gcmWRITE_STRING(infoCompany); gcmWRITE_CONST(VPC_INFOVERSION); gcmWRITE_STRING(infoVersion); gcmWRITE_CONST(VPC_INFORENDERER); gcmWRITE_STRING(infoRenderer); gcmWRITE_CONST(VPC_INFOREVISION); gcmWRITE_STRING(infoRevision); gcmWRITE_CONST(VPC_INFODRIVER); gcmWRITE_STRING(infoDriver); gcmWRITE_CONST(VPG_END); } #else /* Print generic info */ _Print(Context, "<GenericInfo company=\"Vivante Corporation\" " "version=\"%d.%d\" renderer=\"%s\" ", 1, 0, Context->chipName); rev = Context->revision; #define BCD(digit) ((rev >> (digit * 4)) & 0xF) if (BCD(3) == 0) { /* Old format. */ _Print(Context, "revision=\"%d.%d\" ", BCD(1), BCD(0)); } else { /* New format. */ _Print(Context, "revision=\"%d.%d.%d_rc%d\" ", BCD(3), BCD(2), BCD(1), BCD(0)); } _Print(Context, "driver=\"%s\" />\n", "OpenVG 1.1"); #endif gcoOS_GetTime(&Context->profiler.frameStart); Context->profiler.frameStartTimeusec = Context->profiler.frameStart; Context->profiler.primitiveStartTimeusec = Context->profiler.frameStart; gcoOS_GetCPUTime(&Context->profiler.frameStartCPUTimeusec); }
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; }
gceSTATUS gcoPROFILER_EndDraw( IN gcoHAL Hal, IN gctBOOL FirstDraw ) { /*#if (PROFILE_HAL_COUNTERS || PROFILE_HW_COUNTERS)*/ gcsHAL_INTERFACE iface; gceSTATUS status; static gcsPROFILER previous; static gcsPROFILER_COUNTERS precounters; /*#endif*/ gcmHEADER(); if (!gcPLS.hal->profiler.enable) { gcmFOOTER_NO(); return gcvSTATUS_OK; } /*#if PROFILE_HAL_COUNTERS*/ if (gcPLS.hal->profiler.enableHal) { #if gcdNEW_PROFILER_FILE if(FirstDraw == gcvTRUE) { gcoOS_ZeroMemory(&previous, gcmSIZEOF(previous)); } gcmWRITE_CONST(VPG_HAL); gcmWRITE_COUNTER(VPC_HALVERTBUFNEWBYTEALLOC, gcPLS.hal->profiler.vertexBufferNewBytesAlloc-previous.vertexBufferNewBytesAlloc); gcmWRITE_COUNTER(VPC_HALVERTBUFTOTALBYTEALLOC, gcPLS.hal->profiler.vertexBufferTotalBytesAlloc-previous.vertexBufferTotalBytesAlloc); gcmWRITE_COUNTER(VPC_HALVERTBUFNEWOBJALLOC, gcPLS.hal->profiler.vertexBufferNewObjectsAlloc-previous.vertexBufferNewObjectsAlloc); gcmWRITE_COUNTER(VPC_HALVERTBUFTOTALOBJALLOC, gcPLS.hal->profiler.vertexBufferTotalObjectsAlloc-previous.vertexBufferTotalObjectsAlloc); gcmWRITE_COUNTER(VPC_HALINDBUFNEWBYTEALLOC, gcPLS.hal->profiler.indexBufferNewBytesAlloc-previous.indexBufferNewBytesAlloc); gcmWRITE_COUNTER(VPC_HALINDBUFTOTALBYTEALLOC, gcPLS.hal->profiler.indexBufferTotalBytesAlloc-previous.indexBufferTotalBytesAlloc); gcmWRITE_COUNTER(VPC_HALINDBUFNEWOBJALLOC, gcPLS.hal->profiler.indexBufferNewObjectsAlloc-previous.indexBufferNewObjectsAlloc); gcmWRITE_COUNTER(VPC_HALINDBUFTOTALOBJALLOC, gcPLS.hal->profiler.indexBufferTotalObjectsAlloc-previous.indexBufferTotalObjectsAlloc); gcmWRITE_COUNTER(VPC_HALTEXBUFNEWBYTEALLOC, gcPLS.hal->profiler.textureBufferNewBytesAlloc-previous.textureBufferNewBytesAlloc); gcmWRITE_COUNTER(VPC_HALTEXBUFTOTALBYTEALLOC, gcPLS.hal->profiler.textureBufferTotalBytesAlloc-previous.textureBufferTotalBytesAlloc); gcmWRITE_COUNTER(VPC_HALTEXBUFNEWOBJALLOC, gcPLS.hal->profiler.textureBufferNewObjectsAlloc-previous.textureBufferNewObjectsAlloc); gcmWRITE_COUNTER(VPC_HALTEXBUFTOTALOBJALLOC, gcPLS.hal->profiler.textureBufferTotalObjectsAlloc-previous.textureBufferTotalObjectsAlloc); gcmWRITE_CONST(VPG_END); gcoOS_MemCopy(&previous,&gcPLS.hal->profiler,gcmSIZEOF(gcsPROFILER)); #else gcmWRITE_STRING("<HALCounters>\n"); gcmPRINT_XML_COUNTER(vertexBufferNewBytesAlloc); gcmPRINT_XML_COUNTER(vertexBufferTotalBytesAlloc); gcmPRINT_XML_COUNTER(vertexBufferNewObjectsAlloc); gcmPRINT_XML_COUNTER(vertexBufferTotalObjectsAlloc); gcmPRINT_XML_COUNTER(indexBufferNewBytesAlloc); gcmPRINT_XML_COUNTER(indexBufferTotalBytesAlloc); gcmPRINT_XML_COUNTER(indexBufferNewObjectsAlloc); gcmPRINT_XML_COUNTER(indexBufferTotalObjectsAlloc); gcmPRINT_XML_COUNTER(textureBufferNewBytesAlloc); gcmPRINT_XML_COUNTER(textureBufferTotalBytesAlloc); gcmPRINT_XML_COUNTER(textureBufferNewObjectsAlloc); gcmPRINT_XML_COUNTER(textureBufferTotalObjectsAlloc); gcmWRITE_STRING("</HALCounters>\n"); #endif /* Reset per-frame counters. */ } /*#endif*/ /*#if PROFILE_HW_COUNTERS*/ /* gcvHAL_READ_ALL_PROFILE_REGISTERS. */ if (gcPLS.hal->profiler.enableHW) { if (gcPLS.hal->profiler.isSyncMode) gcoHAL_Commit(gcvNULL, gcvTRUE); #if VIVANTE_PROFILER_PERDRAW /* Set Register clear Flag. */ iface.command = gcvHAL_READ_PROFILER_REGISTER_SETTING; iface.u.SetProfilerRegisterClear.bclear = gcvFALSE; /* Call the kernel. */ status = gcoOS_DeviceControl(gcvNULL, IOCTL_GCHAL_INTERFACE, &iface, gcmSIZEOF(iface), &iface, gcmSIZEOF(iface)); /* Verify result. */ if (gcmIS_ERROR(status)) return gcvSTATUS_GENERIC_IO; #endif iface.command = gcvHAL_READ_ALL_PROFILE_REGISTERS; /* Call the kernel. */ status = gcoOS_DeviceControl(gcvNULL, IOCTL_GCHAL_INTERFACE, &iface, gcmSIZEOF(iface), &iface, gcmSIZEOF(iface)); /* Verify result. */ if (gcmNO_ERROR(status)) { #define gcmCOUNTERCOMPARE(name) ((iface.u.RegisterProfileData.counters.name) - (precounters.name)) #define gcmDRAWCOUNTERPRE(name) (precounters.name) #if gcdNEW_PROFILER_FILE if(FirstDraw == gcvFALSE) { gcoOS_ZeroMemory(&precounters, gcmSIZEOF(precounters)); gcmDRAWCOUNTERPRE(vs_inst_counter) = gcPLS.hal->profiler.prevVSInstCount; gcmDRAWCOUNTERPRE(vtx_branch_inst_counter) = gcPLS.hal->profiler.prevVSBranchInstCount ; gcmDRAWCOUNTERPRE(vtx_texld_inst_counter) = gcPLS.hal->profiler.prevVSTexInstCount; gcmDRAWCOUNTERPRE(rendered_vertice_counter) = gcPLS.hal->profiler.prevVSVertexCount; gcmDRAWCOUNTERPRE(ps_inst_counter) =gcPLS.hal->profiler.prevPSInstCount; gcmDRAWCOUNTERPRE(pxl_branch_inst_counter) = gcPLS.hal->profiler.prevPSBranchInstCount; gcmDRAWCOUNTERPRE(pxl_texld_inst_counter) = gcPLS.hal->profiler.prevPSTexInstCount; gcmDRAWCOUNTERPRE(rendered_pixel_counter) = gcPLS.hal->profiler.prevPSPixelCount; } gcmWRITE_CONST(VPG_HW); gcmWRITE_CONST(VPG_GPU); gcmWRITE_COUNTER(VPC_GPUREAD64BYTE, gcmCOUNTERCOMPARE(gpuTotalRead64BytesPerFrame)); gcmWRITE_COUNTER(VPC_GPUWRITE64BYTE, gcmCOUNTERCOMPARE(gpuTotalWrite64BytesPerFrame)); gcmWRITE_COUNTER(VPC_GPUCYCLES, gcmCOUNTERCOMPARE(gpuCyclesCounter)); gcmWRITE_COUNTER(VPC_GPUTOTALCYCLES, gcmCOUNTERCOMPARE(gpuTotalCyclesCounter)); gcmWRITE_COUNTER(VPC_GPUIDLECYCLES, gcmCOUNTERCOMPARE(gpuIdleCyclesCounter)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_VS); gcmWRITE_COUNTER(VPC_VSINSTCOUNT, gcmCOUNTERCOMPARE(vs_inst_counter)); gcmWRITE_COUNTER(VPC_VSBRANCHINSTCOUNT, gcmCOUNTERCOMPARE(vtx_branch_inst_counter)); gcmWRITE_COUNTER(VPC_VSTEXLDINSTCOUNT, gcmCOUNTERCOMPARE(vtx_texld_inst_counter)); gcmWRITE_COUNTER(VPC_VSRENDEREDVERTCOUNT, gcmCOUNTERCOMPARE(rendered_vertice_counter)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_PA); gcmWRITE_COUNTER(VPC_PAINVERTCOUNT, gcmCOUNTERCOMPARE(pa_input_vtx_counter)); gcmWRITE_COUNTER(VPC_PAINPRIMCOUNT, gcmCOUNTERCOMPARE(pa_input_prim_counter)); gcmWRITE_COUNTER(VPC_PAOUTPRIMCOUNT, gcmCOUNTERCOMPARE(pa_output_prim_counter)); gcmWRITE_COUNTER(VPC_PADEPTHCLIPCOUNT, gcmCOUNTERCOMPARE(pa_depth_clipped_counter)); gcmWRITE_COUNTER(VPC_PATRIVIALREJCOUNT, gcmCOUNTERCOMPARE(pa_trivial_rejected_counter)); gcmWRITE_COUNTER(VPC_PACULLCOUNT, gcmCOUNTERCOMPARE(pa_culled_counter)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_SETUP); gcmWRITE_COUNTER(VPC_SETRIANGLECOUNT, gcmCOUNTERCOMPARE(se_culled_triangle_count)); gcmWRITE_COUNTER(VPC_SELINECOUNT, gcmCOUNTERCOMPARE(se_culled_lines_count)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_RA); gcmWRITE_COUNTER(VPC_RAVALIDPIXCOUNT, gcmCOUNTERCOMPARE(ra_valid_pixel_count)); gcmWRITE_COUNTER(VPC_RATOTALQUADCOUNT, gcmCOUNTERCOMPARE(ra_total_quad_count)); gcmWRITE_COUNTER(VPC_RAVALIDQUADCOUNTEZ, gcmCOUNTERCOMPARE(ra_valid_quad_count_after_early_z)); gcmWRITE_COUNTER(VPC_RATOTALPRIMCOUNT, gcmCOUNTERCOMPARE(ra_total_primitive_count)); gcmWRITE_COUNTER(VPC_RAPIPECACHEMISSCOUNT, gcmCOUNTERCOMPARE(ra_pipe_cache_miss_counter)); gcmWRITE_COUNTER(VPC_RAPREFCACHEMISSCOUNT, gcmCOUNTERCOMPARE(ra_prefetch_cache_miss_counter)); gcmWRITE_COUNTER(VPC_RAEEZCULLCOUNT, gcmCOUNTERCOMPARE(ra_eez_culled_counter)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_TX); gcmWRITE_COUNTER(VPC_TXTOTBILINEARREQ, gcmCOUNTERCOMPARE(tx_total_bilinear_requests)); gcmWRITE_COUNTER(VPC_TXTOTTRILINEARREQ, gcmCOUNTERCOMPARE(tx_total_trilinear_requests)); gcmWRITE_COUNTER(VPC_TXTOTTEXREQ, gcmCOUNTERCOMPARE(tx_total_texture_requests)); gcmWRITE_COUNTER(VPC_TXMEMREADCOUNT, gcmCOUNTERCOMPARE(tx_mem_read_count)); gcmWRITE_COUNTER(VPC_TXMEMREADIN8BCOUNT, gcmCOUNTERCOMPARE(tx_mem_read_in_8B_count)); gcmWRITE_COUNTER(VPC_TXCACHEMISSCOUNT, gcmCOUNTERCOMPARE(tx_cache_miss_count)); gcmWRITE_COUNTER(VPC_TXCACHEHITTEXELCOUNT, gcmCOUNTERCOMPARE(tx_cache_hit_texel_count)); gcmWRITE_COUNTER(VPC_TXCACHEMISSTEXELCOUNT, gcmCOUNTERCOMPARE(tx_cache_miss_texel_count)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_PS); gcmWRITE_COUNTER(VPC_PSINSTCOUNT, gcmCOUNTERCOMPARE(ps_inst_counter)); gcmWRITE_COUNTER(VPC_PSBRANCHINSTCOUNT, gcmCOUNTERCOMPARE(pxl_branch_inst_counter)); gcmWRITE_COUNTER(VPC_PSTEXLDINSTCOUNT, gcmCOUNTERCOMPARE(pxl_texld_inst_counter)); gcmWRITE_COUNTER(VPC_PSRENDEREDPIXCOUNT, gcmCOUNTERCOMPARE(rendered_pixel_counter)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_PE); gcmWRITE_COUNTER(VPC_PEKILLEDBYCOLOR, gcmCOUNTERCOMPARE(pe_pixel_count_killed_by_color_pipe)); gcmWRITE_COUNTER(VPC_PEKILLEDBYDEPTH, gcmCOUNTERCOMPARE(pe_pixel_count_killed_by_depth_pipe)); gcmWRITE_COUNTER(VPC_PEDRAWNBYCOLOR, gcmCOUNTERCOMPARE(pe_pixel_count_drawn_by_color_pipe)); gcmWRITE_COUNTER(VPC_PEDRAWNBYDEPTH, gcmCOUNTERCOMPARE(pe_pixel_count_drawn_by_depth_pipe)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_MC); gcmWRITE_COUNTER(VPC_MCREADREQ8BPIPE, gcmCOUNTERCOMPARE(mc_total_read_req_8B_from_pipeline)); gcmWRITE_COUNTER(VPC_MCREADREQ8BIP, gcmCOUNTERCOMPARE(mc_total_read_req_8B_from_IP)); gcmWRITE_COUNTER(VPC_MCWRITEREQ8BPIPE, gcmCOUNTERCOMPARE(mc_total_write_req_8B_from_pipeline)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_AXI); gcmWRITE_COUNTER(VPC_AXIREADREQSTALLED, gcmCOUNTERCOMPARE(hi_axi_cycles_read_request_stalled)); gcmWRITE_COUNTER(VPC_AXIWRITEREQSTALLED, gcmCOUNTERCOMPARE(hi_axi_cycles_write_request_stalled)); gcmWRITE_COUNTER(VPC_AXIWRITEDATASTALLED, gcmCOUNTERCOMPARE(hi_axi_cycles_write_data_stalled)); gcmWRITE_CONST(VPG_END); gcmWRITE_CONST(VPG_END); gcoOS_MemCopy(&precounters,&iface.u.RegisterProfileData.counters,gcmSIZEOF(precounters)); #else gcmWRITE_STRING("<HWCounters>\n"); gcmPRINT_XML("<read_64Byte value=\"%u\"/>\n", gcmCOUNTER(gpuTotalRead64BytesPerFrame)); gcmPRINT_XML("<write_64Byte value=\"%u\"/>\n", gcmCOUNTER(gpuTotalWrite64BytesPerFrame)); gcmPRINT_XML("<gpu_cycles value=\"%u\"/>\n", gcmCOUNTER(gpuCyclesCounter)); gcmPRINT_XML("<pe_pixel_count_killed_by_color_pipe value=\"%u\"/>\n", gcmCOUNTER(pe_pixel_count_killed_by_color_pipe)); gcmPRINT_XML("<pe_pixel_count_killed_by_depth_pipe value=\"%u\"/>\n", gcmCOUNTER(pe_pixel_count_killed_by_depth_pipe)); gcmPRINT_XML("<pe_pixel_count_drawn_by_color_pipe value=\"%u\"/>\n", gcmCOUNTER(pe_pixel_count_drawn_by_color_pipe)); gcmPRINT_XML("<pe_pixel_count_drawn_by_depth_pipe value=\"%u\"/>\n", gcmCOUNTER(pe_pixel_count_drawn_by_depth_pipe)); gcmPRINT_XML("<ps_inst_counter value=\"%u\"/>\n", gcmCOUNTER(ps_inst_counter)); gcmPRINT_XML("<rendered_pixel_counter value=\"%u\"/>\n", gcmCOUNTER(rendered_pixel_counter)); gcmPRINT_XML("<vs_inst_counter value=\"%u\"/>\n", gcmCOUNTER(vs_inst_counter)); gcmPRINT_XML("<rendered_vertice_counter value=\"%u\"/>\n", gcmCOUNTER(rendered_vertice_counter)); gcmPRINT_XML("<vtx_branch_inst_counter value=\"%u\"/>\n", gcmCOUNTER(vtx_branch_inst_counter)); gcmPRINT_XML("<vtx_texld_inst_counter value=\"%u\"/>\n", gcmCOUNTER(vtx_texld_inst_counter)); gcmPRINT_XML("<pxl_branch_inst_counter value=\"%u\"/>\n", gcmCOUNTER(pxl_branch_inst_counter)); gcmPRINT_XML("<pxl_texld_inst_counter value=\"%u\"/>\n", gcmCOUNTER(pxl_texld_inst_counter)); gcmPRINT_XML("<pa_input_vtx_counter value=\"%u\"/>\n", gcmCOUNTER(pa_input_vtx_counter)); gcmPRINT_XML("<pa_input_prim_counter value=\"%u\"/>\n", gcmCOUNTER(pa_input_prim_counter)); gcmPRINT_XML("<pa_output_prim_counter value=\"%u\"/>\n", gcmCOUNTER(pa_output_prim_counter)); gcmPRINT_XML("<pa_depth_clipped_counter value=\"%u\"/>\n", gcmCOUNTER(pa_depth_clipped_counter)); gcmPRINT_XML("<pa_trivial_rejected_counter value=\"%u\"/>\n", gcmCOUNTER(pa_trivial_rejected_counter)); gcmPRINT_XML("<pa_culled_counter value=\"%u\"/>\n", gcmCOUNTER(pa_culled_counter)); gcmPRINT_XML("<se_culled_triangle_count value=\"%u\"/>\n", gcmCOUNTER(se_culled_triangle_count)); gcmPRINT_XML("<se_culled_lines_count value=\"%u\"/>\n", gcmCOUNTER(se_culled_lines_count)); gcmPRINT_XML("<ra_valid_pixel_count value=\"%u\"/>\n", gcmCOUNTER(ra_valid_pixel_count)); gcmPRINT_XML("<ra_total_quad_count value=\"%u\"/>\n", gcmCOUNTER(ra_total_quad_count)); gcmPRINT_XML("<ra_valid_quad_count_after_early_z value=\"%u\"/>\n", gcmCOUNTER(ra_valid_quad_count_after_early_z)); gcmPRINT_XML("<ra_total_primitive_count value=\"%u\"/>\n", gcmCOUNTER(ra_total_primitive_count)); gcmPRINT_XML("<ra_pipe_cache_miss_counter value=\"%u\"/>\n", gcmCOUNTER(ra_pipe_cache_miss_counter)); gcmPRINT_XML("<ra_prefetch_cache_miss_counter value=\"%u\"/>\n", gcmCOUNTER(ra_prefetch_cache_miss_counter)); gcmPRINT_XML("<ra_eez_culled_counter value=\"%u\"/>\n", gcmCOUNTER(ra_eez_culled_counter)); gcmPRINT_XML("<tx_total_bilinear_requests value=\"%u\"/>\n", gcmCOUNTER(tx_total_bilinear_requests)); gcmPRINT_XML("<tx_total_trilinear_requests value=\"%u\"/>\n", gcmCOUNTER(tx_total_trilinear_requests)); gcmPRINT_XML("<tx_total_discarded_texture_requests value=\"%u\"/>\n", gcmCOUNTER(tx_total_discarded_texture_requests)); gcmPRINT_XML("<tx_total_texture_requests value=\"%u\"/>\n", gcmCOUNTER(tx_total_texture_requests)); gcmPRINT_XML("<tx_mem_read_count value=\"%u\"/>\n", gcmCOUNTER(tx_mem_read_count)); gcmPRINT_XML("<tx_mem_read_in_8B_count value=\"%u\"/>\n", gcmCOUNTER(tx_mem_read_in_8B_count)); gcmPRINT_XML("<tx_cache_miss_count value=\"%u\"/>\n", gcmCOUNTER(tx_cache_miss_count)); gcmPRINT_XML("<tx_cache_hit_texel_count value=\"%u\"/>\n", gcmCOUNTER(tx_cache_hit_texel_count)); gcmPRINT_XML("<tx_cache_miss_texel_count value=\"%u\"/>\n", gcmCOUNTER(tx_cache_miss_texel_count)); gcmPRINT_XML("<mc_total_read_req_8B_from_pipeline value=\"%u\"/>\n", gcmCOUNTER(mc_total_read_req_8B_from_pipeline)); gcmPRINT_XML("<mc_total_read_req_8B_from_IP value=\"%u\"/>\n", gcmCOUNTER(mc_total_read_req_8B_from_IP)); gcmPRINT_XML("<mc_total_write_req_8B_from_pipeline value=\"%u\"/>\n", gcmCOUNTER(mc_total_write_req_8B_from_pipeline)); gcmPRINT_XML("<hi_axi_cycles_read_request_stalled value=\"%u\"/>\n", gcmCOUNTER(hi_axi_cycles_read_request_stalled)); gcmPRINT_XML("<hi_axi_cycles_write_request_stalled value=\"%u\"/>\n", gcmCOUNTER(hi_axi_cycles_write_request_stalled)); gcmPRINT_XML("<hi_axi_cycles_write_data_stalled value=\"%u\"/>\n", gcmCOUNTER(hi_axi_cycles_write_data_stalled)); gcmWRITE_STRING("</HWCounters>\n"); #endif } } /*#endif*/ /* Success. */ gcmFOOTER_NO(); return gcvSTATUS_OK; }
static int gpu_resume(struct platform_device *dev) { gceSTATUS status; gckGALDEVICE device; gctINT i; gceCHIPPOWERSTATE statesStored; device = platform_get_drvdata(dev); if (!device) { return -1; } for (i = 0; i < gcdMAX_GPU_COUNT; i++) { if (device->kernels[i] != gcvNULL) { #if gcdENABLE_VG if (i == gcvCORE_VG) { status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON); } else #endif { status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON); } if (gcmIS_ERROR(status)) { return -1; } /* Convert global state to crossponding internal state. */ switch(device->statesStored[i]) { case gcvPOWER_OFF: statesStored = gcvPOWER_OFF_BROADCAST; break; case gcvPOWER_IDLE: statesStored = gcvPOWER_IDLE_BROADCAST; break; case gcvPOWER_SUSPEND: statesStored = gcvPOWER_SUSPEND_BROADCAST; break; case gcvPOWER_ON: statesStored = gcvPOWER_ON_AUTO; break; default: statesStored = device->statesStored[i]; break; } /* Restore states. */ #if gcdENABLE_VG if (i == gcvCORE_VG) { status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored); } else #endif { status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, statesStored); } if (gcmIS_ERROR(status)) { return -1; } } } return 0; }
gctINT slScanIdentifier( IN sloCOMPILER Compiler, IN gctUINT LineNo, IN gctUINT StringNo, IN gctSTRING Symbol, OUT slsLexToken * Token ) { gceSTATUS status; gctINT tokenType; sleSHADER_TYPE shaderType; sltPOOL_STRING symbolInPool; slsNAME * typeName; gcmTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_COMPILER, "LineNo=%u", LineNo); gcmTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_COMPILER, "StringNo=%u", StringNo); gcmTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_COMPILER, "Symbol=%s", gcmOPT_STRING(Symbol)); gcmASSERT(Token); gcmVERIFY_OK(sloCOMPILER_GetShaderType(Compiler, &shaderType)); Token->lineNo = LineNo; Token->stringNo = StringNo; /* Check as a reserved keyword */ tokenType = _SearchKeyword(Symbol); if (tokenType == T_RESERVED_KEYWORD) { Token->type = T_RESERVED_KEYWORD; gcmVERIFY_OK(sloCOMPILER_Report( Compiler, LineNo, StringNo, slvREPORT_ERROR, "reserved keyword : '%s'", Symbol)); return T_RESERVED_KEYWORD; } else if (tokenType != T_NOT_KEYWORD) { Token->type = tokenType; switch (tokenType) { case T_CONST: Token->u.qualifier = slvQUALIFIER_CONST; break; case T_UNIFORM: Token->u.qualifier = slvQUALIFIER_UNIFORM; break; case T_ATTRIBUTE: if (shaderType != slvSHADER_TYPE_VERTEX) { gcmVERIFY_OK(sloCOMPILER_Report( Compiler, LineNo, StringNo, slvREPORT_ERROR, "'attribute' is only for the vertex shaders", Symbol)); } Token->u.qualifier = slvQUALIFIER_ATTRIBUTE; break; case T_VARYING: Token->u.qualifier = (shaderType == slvSHADER_TYPE_VERTEX)? slvQUALIFIER_VARYING_OUT : slvQUALIFIER_VARYING_IN; break; case T_INVARIANT: Token->u.qualifier = (shaderType == slvSHADER_TYPE_VERTEX)? slvQUALIFIER_INVARIANT_VARYING_OUT : slvQUALIFIER_INVARIANT_VARYING_IN; break; case T_IN: Token->u.qualifier = slvQUALIFIER_IN; break; case T_OUT: Token->u.qualifier = slvQUALIFIER_OUT; break; case T_INOUT: Token->u.qualifier = slvQUALIFIER_INOUT; break; case T_HIGH_PRECISION: Token->u.precision = slvPRECISION_HIGH; break; case T_MEDIUM_PRECISION: Token->u.precision = slvPRECISION_MEDIUM; break; case T_LOW_PRECISION: Token->u.precision = slvPRECISION_LOW; break; } gcmVERIFY_OK(sloCOMPILER_Dump( Compiler, slvDUMP_SCANNER, "<TOKEN line=\"%d\" string=\"%d\" type=\"keyword\" symbol=\"%s\" />", LineNo, StringNo, Symbol)); return tokenType; } status = sloCOMPILER_AllocatePoolString( Compiler, Symbol, &symbolInPool); if (gcmIS_ERROR(status)) return T_EOF; if (sloCOMPILER_GetScannerState(Compiler) == slvSCANNER_NOMRAL) { /* Check as a type name */ status = sloCOMPILER_SearchName( Compiler, symbolInPool, gcvTRUE, &typeName); if (status == gcvSTATUS_OK && typeName->type == slvSTRUCT_NAME) { Token->type = T_TYPE_NAME; Token->u.typeName = typeName; gcmVERIFY_OK(sloCOMPILER_Dump( Compiler, slvDUMP_SCANNER, "<TOKEN line=\"%d\" string=\"%d\" type=\"typeName\" symbol=\"%s\" />", LineNo, StringNo, symbolInPool)); return T_TYPE_NAME; } } /* Treat as an identifier */ Token->type = T_IDENTIFIER; Token->u.identifier = symbolInPool; gcmVERIFY_OK(sloCOMPILER_Dump( Compiler, slvDUMP_SCANNER, "<TOKEN line=\"%d\" string=\"%d\" type=\"identifier\" symbol=\"%s\" />", LineNo, StringNo, Token->u.identifier)); return T_IDENTIFIER; }
gceSTATUS gcoPROFILER_Initialize( IN gcoHAL Hal ) { gceSTATUS status = gcvSTATUS_OK; char* fileName; char* filter = gcvNULL; gctSTRING portName; gctINT port; gcsHAL_INTERFACE iface; gcmHEADER(); /* Check if already initialized. */ if (gcPLS.hal->profiler.enable) { gcPLS.hal->profiler.enable++; gcmFOOTER(); return status; } /* Get profile setting. */ iface.command = gcvHAL_GET_PROFILE_SETTING; /* Call the kernel. */ status = gcoOS_DeviceControl(gcvNULL, IOCTL_GCHAL_INTERFACE, &iface, gcmSIZEOF(iface), &iface, gcmSIZEOF(iface)); if (gcmIS_ERROR(status) || !iface.u.GetProfileSetting.enable) { gcPLS.hal->profiler.enable = 0; status = gcvSTATUS_GENERIC_IO; gcmFOOTER(); return status; } gcmVERIFY_OK(gcoOS_ZeroMemory(&gcPLS.hal->profiler, gcmSIZEOF(gcPLS.hal->profiler))); gcoOS_GetEnv(gcvNULL, "VP_COUNTER_FILTER", &filter); /* Enable/Disable specific counters. */ if ((filter != gcvNULL)) { gctSIZE_T bitsLen; gcoOS_StrLen(filter, &bitsLen); if (bitsLen > 2) { gcPLS.hal->profiler.enableHal = (filter[2] == '1'); } else { gcPLS.hal->profiler.enableHal = gcvTRUE; } if (bitsLen > 3) { gcPLS.hal->profiler.enableHW = (filter[3] == '1'); } else { gcPLS.hal->profiler.enableHW = gcvTRUE; } if (bitsLen > 8) { gcPLS.hal->profiler.enableSH = (filter[8] == '1'); } else { gcPLS.hal->profiler.enableSH = gcvTRUE; } } else { gcPLS.hal->profiler.enableHal = gcvTRUE; gcPLS.hal->profiler.enableHW = gcvTRUE; gcPLS.hal->profiler.enableSH = gcvTRUE; } gcoOS_GetEnv(gcvNULL, "VPROFILER_OUTPUT", &fileName); gcPLS.hal->profiler.useSocket = gcvFALSE; if (fileName && *fileName != '\0' && *fileName != ' ') { /* Extract port info. */ gcoOS_StrFindReverse(fileName, ':', &portName); if (portName) { gcoOS_StrToInt(portName + 1, &port); if (port > 0) { /*status = gcoOS_Socket(gcvNULL, AF_INET, SOCK_STREAM, 0, &gcPLS.hal->profiler.sockFd);*/ status = gcoOS_Socket(gcvNULL, 2, 1, 0, &gcPLS.hal->profiler.sockFd); if (gcmIS_SUCCESS(status)) { *portName = '\0'; status = gcoOS_Connect(gcvNULL, gcPLS.hal->profiler.sockFd, fileName, port); *portName = ':'; if (gcmIS_SUCCESS(status)) { gcPLS.hal->profiler.useSocket = gcvTRUE; } } } } } else { fileName = iface.u.GetProfileSetting.fileName; } if (! gcPLS.hal->profiler.useSocket) { status = gcoOS_Open(gcvNULL, fileName, #ifdef gcdNEW_PROFILER_FILE gcvFILE_CREATE, #else gcvFILE_CREATETEXT, #endif &gcPLS.hal->profiler.file); } if (gcmIS_ERROR(status)) { gcPLS.hal->profiler.enable = 0; status = gcvSTATUS_GENERIC_IO; gcmFOOTER(); return status; } gcPLS.hal->profiler.enable = 1; gcoOS_GetTime(&gcPLS.hal->profiler.frameStart); gcPLS.hal->profiler.frameStartTimeusec = gcPLS.hal->profiler.frameStart; gcPLS.hal->profiler.prevVSInstCount = 0; gcPLS.hal->profiler.prevVSBranchInstCount = 0; gcPLS.hal->profiler.prevVSTexInstCount = 0; gcPLS.hal->profiler.prevVSVertexCount = 0; gcPLS.hal->profiler.prevPSInstCount = 0; gcPLS.hal->profiler.prevPSBranchInstCount = 0; gcPLS.hal->profiler.prevPSTexInstCount = 0; gcPLS.hal->profiler.prevPSPixelCount = 0; #if gcdNEW_PROFILER_FILE gcmWRITE_CONST(VPHEADER); gcmWRITE_BUFFER(4, "VP12"); #else gcmWRITE_STRING("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<VProfile>\n"); #endif /* Success. */ gcmFOOTER(); return status; }
/******************************************************************************* ** ** gckCOMMAND_Stall ** ** The calling thread will be suspended until the command queue has been ** completed. ** ** INPUT: ** ** gckCOMMAND Command ** Pointer to an gckCOMMAND object. ** ** OUTPUT: ** ** Nothing. */ gceSTATUS gckCOMMAND_Stall( IN gckCOMMAND Command ) { gckOS os; gckHARDWARE hardware; gckEVENT event; gceSTATUS status; gctSIGNAL signal = gcvNULL; gcmkHEADER_ARG("Command=0x%x", Command); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND); #if gcdNULL_DRIVER == 2 /* Do nothing with infinite hardware. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; #endif /* Extract the gckOS object pointer. */ os = Command->os; gcmkVERIFY_OBJECT(os, gcvOBJ_OS); /* Extract the gckHARDWARE object pointer. */ hardware = Command->kernel->hardware; gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE); /* Extract the gckEVENT object pointer. */ event = Command->kernel->event; gcmkVERIFY_OBJECT(event, gcvOBJ_EVENT); /* Allocate the signal. */ gcmkONERROR( gckOS_CreateSignal(os, gcvTRUE, &signal)); /* Append the EVENT command to trigger the signal. */ gcmkONERROR(gckEVENT_Signal(event, signal, gcvKERNEL_PIXEL, gcvFALSE)); /* Submit the event queue. */ gcmkONERROR(gckEVENT_Submit(event, gcvTRUE, gcvFALSE)); #if gcdDUMP_COMMAND gcmkPRINT("@[kernel.stall]"); #endif if (status == gcvSTATUS_CHIP_NOT_READY) { /* Error. */ goto OnError; } do { /* Wait for the signal. */ status = gckOS_WaitSignal(os, signal, gcvINFINITE); if (status == gcvSTATUS_TIMEOUT) { #if gcdDEBUG gctUINT32 idle; /* IDLE */ gckOS_ReadRegister(Command->os, 0x0004, &idle); gcmkTRACE(gcvLEVEL_ERROR, "%s(%d): idle=%08x", __FUNCTION__, __LINE__, idle); gckOS_Log(_GFX_LOG_WARNING_, "%s : %d : idle register = 0x%08x \n", __FUNCTION__, __LINE__, idle); #endif #if MRVL_PRINT_CMD_BUFFER { gctUINT i; gctUINT32 idle; gctUINT32 intAck; gctUINT32 prevAddr = 0; gctUINT32 currAddr; gctBOOL changeDetected; changeDetected = gcvFALSE; /* IDLE */ gckOS_ReadRegister(Command->os, 0x0004, &idle); /* INT ACK */ gckOS_ReadRegister(Command->os, 0x0010, &intAck); /* DMA POS */ for (i = 0; i < 300; i += 1) { gckOS_ReadRegister(Command->os, 0x0664, &currAddr); if ((i > 0) && (prevAddr != currAddr)) { changeDetected = gcvTRUE; } prevAddr = currAddr; } gcmTRACE(0, "\n%s(%d):\n" " idle = 0x%08X\n" " int = 0x%08X\n" " dma = 0x%08X (change=%d)\n", __FUNCTION__, __LINE__, idle, intAck, currAddr, changeDetected ); _PrintCmdBuffer(Command, currAddr); _PrintLinkChain(); } #endif #if MRVL_LOW_POWER_MODE_DEBUG { int i = 0; printk(">>>>>>>>>>>>galDevice->kernel->kernelMSG\n"); printk("galDevice->kernel->msgLen=%d\n",Command->kernel->msgLen); for(i=0;i<Command->kernel->msgLen;i+=1024) { Command->kernel->kernelMSG[i+1023] = '\0'; printk("%s\n",(char*)Command->kernel->kernelMSG + i); } } #endif #ifdef __QNXNTO__ gctUINT32 reg_cmdbuf_fetch; gctUINT32 reg_intr; gcmkVERIFY_OK( gckOS_ReadRegister(Command->kernel->hardware->os, 0x0664, ®_cmdbuf_fetch)); if (idle == 0x7FFFFFFE) { /* * GPU is idle so there should not be pending interrupts. * Just double check. * * Note that reading interrupt register clears it. * That's why we don't read it in all cases. */ gcmkVERIFY_OK( gckOS_ReadRegister(Command->kernel->hardware->os, 0x10, ®_intr)); slogf( _SLOG_SETCODE(1, 0), _SLOG_CRITICAL, "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X, interrupt = 0x%X)", idle, reg_cmdbuf_fetch, reg_intr); } else { slogf( _SLOG_SETCODE(1, 0), _SLOG_CRITICAL, "GALcore: Stall timeout (idle = 0x%X, command buffer fetch = 0x%X)", idle, reg_cmdbuf_fetch); } #endif gcmkVERIFY_OK( gckOS_MemoryBarrier(os, gcvNULL)); } } while (gcmIS_ERROR(status)); /* Delete the signal. */ gcmkVERIFY_OK(gckOS_DestroySignal(os, signal)); /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; OnError: /* Free the signal. */ if (signal != gcvNULL) { gcmkVERIFY_OK(gckOS_DestroySignal(os, signal)); } /* Return the status. */ gcmkFOOTER(); return status; }