diff options
author | Loren Huang <b02279@freescale.com> | 2012-03-28 17:56:48 +0800 |
---|---|---|
committer | Jason Liu <r64343@freescale.com> | 2012-07-20 13:24:41 +0800 |
commit | 1b68b2205445a3954f6ef487b88440d2da8b1b5e (patch) | |
tree | 8dffc6171e13a07a48ac70adeda387ad0d2e6df7 /drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c | |
parent | 6aaf2a69e13ae84980a90cebce70a86c2a09f404 (diff) |
ENGR00177264 Merge vivante 4.6.6p2 kernel part code
Merge vivante 4.6.6p2 kernel part code
Signed-off-by: Loren Huang <b02279@freescale.com>
Acked-by: Lily Zhang
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c')
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c | 597 |
1 files changed, 296 insertions, 301 deletions
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c index 8b6fcf14a850..c83f63074b61 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c @@ -1797,6 +1797,8 @@ gckEVENT_Notify( for (;;) { + gcsEVENT_PTR record; + /* Suspend interrupts. */ gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core)); suspended = gcvTRUE; @@ -1926,11 +1928,46 @@ gckEVENT_Notify( #endif } + /* Suspend interrupts. */ + gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core)); + suspended = gcvTRUE; + + /* Mark pending interrupt as handled. */ +#if gcdSMP + gckOS_AtomClearMask(Event->pending, mask); +#elif defined(__QNXNTO__) + atomic_clr(&Event->pending, mask); +#else + Event->pending &= ~mask; +#endif + + /* Resume interrupts. */ + gcmkONERROR(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core)); + suspended = gcvFALSE; + + /* Grab the mutex queue. */ + gcmkONERROR(gckOS_AcquireMutex(Event->os, + Event->eventQueueMutex, + gcvINFINITE)); + acquired = gcvTRUE; + + /* Grab the event head. */ + record = queue->head; + + /* Now quickly clear its event list. */ + queue->head = gcvNULL; + + /* Release the mutex queue. */ + gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex)); + acquired = gcvFALSE; + + /* Increase the number of free events. */ + gcmkONERROR(gckOS_AtomIncrement(Event->os, Event->freeAtom, &free)); + /* Walk all events for this interrupt. */ - for (;;) + while (record != gcvNULL) { - gcsEVENT_PTR record; - gcsEVENT_PTR recordNext = gcvNULL; + gcsEVENT_PTR recordNext; #ifndef __QNXNTO__ gctPOINTER logical; #endif @@ -1938,378 +1975,336 @@ gckEVENT_Notify( gctSIZE_T bytes; #endif - /* Grab the mutex queue. */ - gcmkONERROR(gckOS_AcquireMutex(Event->os, - Event->eventQueueMutex, - gcvINFINITE)); - acquired = gcvTRUE; - - /* Grab the event head. */ - record = queue->head; - - if (record != gcvNULL) - { - queue->head = record->next; - recordNext = record->next; - } - - /* Release the mutex queue. */ - gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventQueueMutex)); - acquired = gcvFALSE; + /* Grab next record. */ + recordNext = record->next; - /* Dispatch on event type. */ - if (record != gcvNULL) - { #ifdef __QNXNTO__ - /* Assign record->processID as the pid for this galcore thread. - * Used in OS calls like gckOS_UnlockMemory() which do not take a pid. - */ - drv_thread_specific_key_assign(record->processID, 0); + /* Assign record->processID as the pid for this galcore thread. + * Used in OS calls like gckOS_UnlockMemory() which do not take a pid. + */ + drv_thread_specific_key_assign(record->processID, 0); #endif #if gcdSECURE_USER - /* Get the cache that belongs to this process. */ - gcmkONERROR(gckKERNEL_GetProcessDBCache(Event->kernel, - record->processID, - &cache)); + /* Get the cache that belongs to this process. */ + gcmkONERROR(gckKERNEL_GetProcessDBCache(Event->kernel, + record->processID, + &cache)); #endif - gcmkTRACE_ZONE_N( - gcvLEVEL_INFO, gcvZONE_EVENT, - gcmSIZEOF(record->info.command), - "Processing event type: %d", - record->info.command - ); + gcmkTRACE_ZONE_N( + gcvLEVEL_INFO, gcvZONE_EVENT, + gcmSIZEOF(record->info.command), + "Processing event type: %d", + record->info.command + ); - switch (record->info.command) + switch (record->info.command) + { + case gcvHAL_FREE_NON_PAGED_MEMORY: + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, + "gcvHAL_FREE_NON_PAGED_MEMORY: 0x%x", + record->info.u.FreeNonPagedMemory.physical); + + /* Free non-paged memory. */ + status = gckOS_FreeNonPagedMemory( + Event->os, + record->info.u.FreeNonPagedMemory.bytes, + record->info.u.FreeNonPagedMemory.physical, + record->info.u.FreeNonPagedMemory.logical); + + if (gcmIS_SUCCESS(status)) { - case gcvHAL_FREE_NON_PAGED_MEMORY: - gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, - "gcvHAL_FREE_NON_PAGED_MEMORY: 0x%x", - record->info.u.FreeNonPagedMemory.physical); - - /* Free non-paged memory. */ - status = gckOS_FreeNonPagedMemory( - Event->os, - record->info.u.FreeNonPagedMemory.bytes, - record->info.u.FreeNonPagedMemory.physical, - record->info.u.FreeNonPagedMemory.logical); - - if (gcmIS_SUCCESS(status)) - { #if gcdSECURE_USER - gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( - Event->kernel, - cache, - record->event.u.FreeNonPagedMemory.logical, - record->event.u.FreeNonPagedMemory.bytes)); + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( + Event->kernel, + cache, + record->event.u.FreeNonPagedMemory.logical, + record->event.u.FreeNonPagedMemory.bytes)); #endif - } - break; + } + break; - case gcvHAL_FREE_CONTIGUOUS_MEMORY: - gcmkTRACE_ZONE( - gcvLEVEL_VERBOSE, gcvZONE_EVENT, - "gcvHAL_FREE_CONTIGUOUS_MEMORY: 0x%x", - record->info.u.FreeContiguousMemory.physical); + case gcvHAL_FREE_CONTIGUOUS_MEMORY: + gcmkTRACE_ZONE( + gcvLEVEL_VERBOSE, gcvZONE_EVENT, + "gcvHAL_FREE_CONTIGUOUS_MEMORY: 0x%x", + record->info.u.FreeContiguousMemory.physical); - /* Unmap the user memory. */ - status = gckOS_FreeContiguous( - Event->os, - record->info.u.FreeContiguousMemory.physical, - record->info.u.FreeContiguousMemory.logical, - record->info.u.FreeContiguousMemory.bytes); + /* Unmap the user memory. */ + status = gckOS_FreeContiguous( + Event->os, + record->info.u.FreeContiguousMemory.physical, + record->info.u.FreeContiguousMemory.logical, + record->info.u.FreeContiguousMemory.bytes); - if (gcmIS_SUCCESS(status)) - { + if (gcmIS_SUCCESS(status)) + { #if gcdSECURE_USER - gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( - Event->kernel, - cache, - event->event.u.FreeContiguousMemory.logical, - event->event.u.FreeContiguousMemory.bytes)); + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( + Event->kernel, + cache, + event->event.u.FreeContiguousMemory.logical, + event->event.u.FreeContiguousMemory.bytes)); #endif - } - break; + } + break; - case gcvHAL_FREE_VIDEO_MEMORY: - gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, - "gcvHAL_FREE_VIDEO_MEMORY: 0x%x", - record->info.u.FreeVideoMemory.node); + case gcvHAL_FREE_VIDEO_MEMORY: + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, + "gcvHAL_FREE_VIDEO_MEMORY: 0x%x", + record->info.u.FreeVideoMemory.node); #ifdef __QNXNTO__ - node = record->info.u.FreeVideoMemory.node; + node = record->info.u.FreeVideoMemory.node; #if gcdUSE_VIDMEM_PER_PID - /* Check if the VidMem object still exists. */ - if (gckKERNEL_GetVideoMemoryPoolPid(record->kernel, - gcvPOOL_SYSTEM, - record->processID, - gcvNULL) == gcvSTATUS_NOT_FOUND) - { - /*printf("Vidmem not found for process:%d\n", queue->processID);*/ - status = gcvSTATUS_OK; - break; - } + /* Check if the VidMem object still exists. */ + if (gckKERNEL_GetVideoMemoryPoolPid(record->kernel, + gcvPOOL_SYSTEM, + record->processID, + gcvNULL) == gcvSTATUS_NOT_FOUND) + { + /*printf("Vidmem not found for process:%d\n", queue->processID);*/ + status = gcvSTATUS_OK; + break; + } #else - if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - && (node->VidMem.logical != gcvNULL) - ) - { - gcmkERR_BREAK( - gckKERNEL_UnmapVideoMemory(record->kernel, - node->VidMem.logical, - record->processID, - node->VidMem.bytes)); - node->VidMem.logical = gcvNULL; - } + if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + && (node->VidMem.logical != gcvNULL) + ) + { + gcmkERR_BREAK( + gckKERNEL_UnmapVideoMemory(record->kernel, + node->VidMem.logical, + record->processID, + node->VidMem.bytes)); + node->VidMem.logical = gcvNULL; + } #endif #endif - /* Free video memory. */ - status = - gckVIDMEM_Free(record->info.u.FreeVideoMemory.node); + /* Free video memory. */ + status = + gckVIDMEM_Free(record->info.u.FreeVideoMemory.node); - break; + break; - case gcvHAL_WRITE_DATA: + case gcvHAL_WRITE_DATA: #ifndef __QNXNTO__ - /* Convert physical into logical address. */ - gcmkERR_BREAK( - gckOS_MapPhysical(Event->os, - record->info.u.WriteData.address, - gcmSIZEOF(gctUINT32), - &logical)); - - /* Write data. */ - gcmkERR_BREAK( - gckOS_WriteMemory(Event->os, - logical, - record->info.u.WriteData.data)); - - /* Unmap the physical memory. */ - gcmkERR_BREAK( - gckOS_UnmapPhysical(Event->os, - logical, - gcmSIZEOF(gctUINT32))); + /* Convert physical into logical address. */ + gcmkERR_BREAK( + gckOS_MapPhysical(Event->os, + record->info.u.WriteData.address, + gcmSIZEOF(gctUINT32), + &logical)); + + /* Write data. */ + gcmkERR_BREAK( + gckOS_WriteMemory(Event->os, + logical, + record->info.u.WriteData.data)); + + /* Unmap the physical memory. */ + gcmkERR_BREAK( + gckOS_UnmapPhysical(Event->os, + logical, + gcmSIZEOF(gctUINT32))); #else - /* Write data. */ - gcmkERR_BREAK( - gckOS_WriteMemory(Event->os, - (gctPOINTER) - record->info.u.WriteData.address, - record->info.u.WriteData.data)); + /* Write data. */ + gcmkERR_BREAK( + gckOS_WriteMemory(Event->os, + (gctPOINTER) + record->info.u.WriteData.address, + record->info.u.WriteData.data)); #endif - break; + break; - case gcvHAL_UNLOCK_VIDEO_MEMORY: - gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, - "gcvHAL_UNLOCK_VIDEO_MEMORY: 0x%x", - record->info.u.UnlockVideoMemory.node); + case gcvHAL_UNLOCK_VIDEO_MEMORY: + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, + "gcvHAL_UNLOCK_VIDEO_MEMORY: 0x%x", + record->info.u.UnlockVideoMemory.node); - /* Save node information before it disappears. */ + /* Save node information before it disappears. */ #if gcdSECURE_USER - node = event->event.u.UnlockVideoMemory.node; - if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) - { - logical = gcvNULL; - bytes = 0; - } - else - { - logical = node->Virtual.logical; - bytes = node->Virtual.bytes; - } + node = event->event.u.UnlockVideoMemory.node; + if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + { + logical = gcvNULL; + bytes = 0; + } + else + { + logical = node->Virtual.logical; + bytes = node->Virtual.bytes; + } #endif - /* Unlock. */ - status = gckVIDMEM_Unlock( - Event->kernel, - record->info.u.UnlockVideoMemory.node, - record->info.u.UnlockVideoMemory.type, - gcvNULL); + /* Unlock. */ + status = gckVIDMEM_Unlock( + Event->kernel, + record->info.u.UnlockVideoMemory.node, + record->info.u.UnlockVideoMemory.type, + gcvNULL); #if gcdSECURE_USER - if (gcmIS_SUCCESS(status) && (logical != gcvNULL)) - { - gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( - Event->kernel, - cache, - logical, - bytes)); - } + if (gcmIS_SUCCESS(status) && (logical != gcvNULL)) + { + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( + Event->kernel, + cache, + logical, + bytes)); + } #endif - break; + break; - case gcvHAL_SIGNAL: - gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, - "gcvHAL_SIGNAL: 0x%x", - record->info.u.Signal.signal); + case gcvHAL_SIGNAL: + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, + "gcvHAL_SIGNAL: 0x%x", + record->info.u.Signal.signal); #ifdef __QNXNTO__ - if ((record->info.u.Signal.coid == 0) - && (record->info.u.Signal.rcvid == 0) - ) - { - /* Kernel signal. */ - gcmkERR_BREAK( - gckOS_Signal(Event->os, + if ((record->info.u.Signal.coid == 0) + && (record->info.u.Signal.rcvid == 0) + ) + { + /* Kernel signal. */ + gcmkERR_BREAK( + gckOS_Signal(Event->os, + record->info.u.Signal.signal, + gcvTRUE)); + } + else + { + /* User signal. */ + gcmkERR_BREAK( + gckOS_UserSignal(Event->os, record->info.u.Signal.signal, - gcvTRUE)); - } - else - { - /* User signal. */ - gcmkERR_BREAK( - gckOS_UserSignal(Event->os, - record->info.u.Signal.signal, - record->info.u.Signal.rcvid, - record->info.u.Signal.coid)); - } + record->info.u.Signal.rcvid, + record->info.u.Signal.coid)); + } #else - /* Set signal. */ - if (record->info.u.Signal.process == gcvNULL) - { - /* Kernel signal. */ - gcmkERR_BREAK( - gckOS_Signal(Event->os, + /* Set signal. */ + if (record->info.u.Signal.process == gcvNULL) + { + /* Kernel signal. */ + gcmkERR_BREAK( + gckOS_Signal(Event->os, + record->info.u.Signal.signal, + gcvTRUE)); + } + else + { + /* User signal. */ + gcmkERR_BREAK( + gckOS_UserSignal(Event->os, record->info.u.Signal.signal, - gcvTRUE)); - } - else - { - /* User signal. */ - gcmkERR_BREAK( - gckOS_UserSignal(Event->os, - record->info.u.Signal.signal, - record->info.u.Signal.process)); - } + record->info.u.Signal.process)); + } - gcmkASSERT(record->info.u.Signal.auxSignal == gcvNULL); + gcmkASSERT(record->info.u.Signal.auxSignal == gcvNULL); #endif - break; + break; - case gcvHAL_UNMAP_USER_MEMORY: - gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, - "gcvHAL_UNMAP_USER_MEMORY: 0x%x", - record->info.u.UnmapUserMemory.info); + case gcvHAL_UNMAP_USER_MEMORY: + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, + "gcvHAL_UNMAP_USER_MEMORY: 0x%x", + record->info.u.UnmapUserMemory.info); - /* Unmap the user memory. */ - status = gckOS_UnmapUserMemoryEx( - Event->os, - Event->kernel->core, - record->info.u.UnmapUserMemory.memory, - record->info.u.UnmapUserMemory.size, - record->info.u.UnmapUserMemory.info, - record->info.u.UnmapUserMemory.address); + /* Unmap the user memory. */ + status = gckOS_UnmapUserMemoryEx( + Event->os, + Event->kernel->core, + record->info.u.UnmapUserMemory.memory, + record->info.u.UnmapUserMemory.size, + record->info.u.UnmapUserMemory.info, + record->info.u.UnmapUserMemory.address); #if gcdSECURE_USER - if (gcmIS_SUCCESS(status)) - { - gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( - Event->kernel, - cache, - event->event.u.UnmapUserMemory.memory, - event->event.u.UnmapUserMemory.size)); - } + if (gcmIS_SUCCESS(status)) + { + gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( + Event->kernel, + cache, + event->event.u.UnmapUserMemory.memory, + event->event.u.UnmapUserMemory.size)); + } #endif - gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( - Event->kernel, - record->processID, gcvDB_MAP_USER_MEMORY, - record->info.u.UnmapUserMemory.memory)); - break; + gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB( + Event->kernel, + record->processID, gcvDB_MAP_USER_MEMORY, + record->info.u.UnmapUserMemory.memory)); + break; - case gcvHAL_TIMESTAMP: - gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, - "gcvHAL_TIMESTAMP: %d %d", - record->info.u.TimeStamp.timer, - record->info.u.TimeStamp.request); + case gcvHAL_TIMESTAMP: + gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, + "gcvHAL_TIMESTAMP: %d %d", + record->info.u.TimeStamp.timer, + record->info.u.TimeStamp.request); - /* Process the timestamp. */ - switch (record->info.u.TimeStamp.request) - { - case 0: - status = gckOS_GetTime(&Event->kernel->timers[ - record->info.u.TimeStamp.timer]. - stopTime); - break; - - case 1: - status = gckOS_GetTime(&Event->kernel->timers[ - record->info.u.TimeStamp.timer]. - startTime); - break; - - default: - gcmkTRACE_ZONE_N( - gcvLEVEL_ERROR, gcvZONE_EVENT, - gcmSIZEOF(record->info.u.TimeStamp.request), - "Invalid timestamp request: %d", - record->info.u.TimeStamp.request - ); - - status = gcvSTATUS_INVALID_ARGUMENT; - break; - } + /* Process the timestamp. */ + switch (record->info.u.TimeStamp.request) + { + case 0: + status = gckOS_GetTime(&Event->kernel->timers[ + record->info.u.TimeStamp.timer]. + stopTime); break; - case gcvHAL_COMMIT_DONE: + case 1: + status = gckOS_GetTime(&Event->kernel->timers[ + record->info.u.TimeStamp.timer]. + startTime); break; default: - /* Invalid argument. */ gcmkTRACE_ZONE_N( gcvLEVEL_ERROR, gcvZONE_EVENT, - gcmSIZEOF(record->info.command), - "Unknown event type: %d", - record->info.command + gcmSIZEOF(record->info.u.TimeStamp.request), + "Invalid timestamp request: %d", + record->info.u.TimeStamp.request ); status = gcvSTATUS_INVALID_ARGUMENT; break; } + break; - /* Make sure there are no errors generated. */ - if (gcmIS_ERROR(status)) - { - gcmkTRACE_ZONE_N( - gcvLEVEL_WARNING, gcvZONE_EVENT, - gcmSIZEOF(status), - "Event produced status: %d(%s)", - status, gckOS_DebugStatus2Name(status)); - } + case gcvHAL_COMMIT_DONE: + break; + + default: + /* Invalid argument. */ + gcmkTRACE_ZONE_N( + gcvLEVEL_ERROR, gcvZONE_EVENT, + gcmSIZEOF(record->info.command), + "Unknown event type: %d", + record->info.command + ); - /* Free the event. */ - gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record)); + status = gcvSTATUS_INVALID_ARGUMENT; + break; } - if (recordNext == gcvNULL) + /* Make sure there are no errors generated. */ + if (gcmIS_ERROR(status)) { - break; + gcmkTRACE_ZONE_N( + gcvLEVEL_WARNING, gcvZONE_EVENT, + gcmSIZEOF(status), + "Event produced status: %d(%s)", + status, gckOS_DebugStatus2Name(status)); } - } - /* Increase the number of free events. */ - gcmkONERROR(gckOS_AtomIncrement(Event->os, Event->freeAtom, &free)); + /* Free the event. */ + gcmkVERIFY_OK(gckEVENT_FreeRecord(Event, record)); + + /* Advance to next record. */ + record = recordNext; + } gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT, "Handled interrupt 0x%x", mask); - - /* Suspend interrupts. */ - gcmkONERROR(gckOS_SuspendInterruptEx(Event->os, Event->kernel->core)); - suspended = gcvTRUE; - - /* Mark pending interrupt as handled. */ -#if gcdSMP - gckOS_AtomClearMask(Event->pending, mask); -#elif defined(__QNXNTO__) - atomic_clr(&Event->pending, mask); -#else - Event->pending &= ~mask; -#endif - - /* Resume interrupts. */ - gcmkONERROR(gckOS_ResumeInterruptEx(Event->os, Event->kernel->core)); - suspended = gcvFALSE; } if (IDs == 0) |