]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR0017124 Merge vivante 4.6.4 kernel driver
authorLoren Huang <b02279@freescale.com>
Wed, 4 Jan 2012 10:47:33 +0000 (18:47 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:33:45 +0000 (08:33 +0200)
Signed-off-by: Loren Huang <b02279@freescale.com>
Acked-by: Lily Zhang
22 files changed:
drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.h
drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h

index 296b333cd763d052b139c6a594bb06f6894bdb92..a9aec1484508fa1c23ca1a1631a914df465edfb0 100644 (file)
@@ -139,16 +139,21 @@ _TimeIdleThread(
     /* Cast the object. */
     gckVGHARDWARE hardware = (gckVGHARDWARE) ThreadParameter;
 
+    gcmkVERIFY_OK(gckOS_AcquireSemaphore(
+        hardware->os,
+        hardware->idleSemaphore));
+
     while(gcvTRUE)
     {
-        gcmkVERIFY_OK(gckOS_WaitSignal(hardware->os,
-            hardware->idleSignal, gcvINFINITE));
-
         if (hardware->killThread)
         {
             break;
         }
 
+        gcmkVERIFY_OK(gckOS_AcquireSemaphore(
+            hardware->os,
+            hardware->idleSemaphore));
+
         do
         {
             gcmkVERIFY_OK(gckOS_GetTicks(&currentTime));
@@ -240,7 +245,7 @@ gckVGHARDWARE_Construct(
         hardware->chipMinorFeatures2 = chipMinorFeatures2;
 
         hardware->powerMutex            = gcvNULL;
-        hardware->idleSignal            = gcvNULL;
+        hardware->idleSemaphore         = gcvNULL;
         hardware->chipPowerState        = gcvPOWER_OFF;
         hardware->chipPowerStateGlobal  = gcvPOWER_ON;
         hardware->clockState            = gcvTRUE;
@@ -265,7 +270,8 @@ gckVGHARDWARE_Construct(
         gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1));
 
         gcmkERR_BREAK(gckOS_CreateMutex(Os, &hardware->powerMutex));
-        gcmkERR_BREAK(gckOS_CreateSignal(Os, gcvTRUE, &hardware->idleSignal));
+
+        gcmkERR_BREAK(gckOS_CreateSemaphore(Os, &hardware->idleSemaphore));
 #if gcdPOWER_MANAGEMENT
         gcmkERR_BREAK(gckOS_StartThread(
             hardware->os,
@@ -320,7 +326,6 @@ gckVGHARDWARE_Destroy(
 
 #if gcdPOWER_MANAGEMENT
     Hardware->killThread  = gcvTRUE;
-    gcmkVERIFY_OK(gckOS_Signal(Hardware->os, Hardware->idleSignal, gcvTRUE));
     gcmkVERIFY_OK(gckOS_StopThread(Hardware->os, Hardware->timeIdleThread));
 #endif
     /* Mark the object as unknown. */
@@ -332,10 +337,10 @@ gckVGHARDWARE_Destroy(
             Hardware->os, Hardware->powerMutex));
     }
 
-    if (Hardware->idleSignal != gcvNULL)
+    if (Hardware->idleSemaphore != gcvNULL)
     {
-        gcmkVERIFY_OK(gckOS_DestroySignal(
-            Hardware->os, Hardware->idleSignal));
+        gcmkVERIFY_OK(gckOS_DestroySemaphore(
+            Hardware->os, Hardware->idleSemaphore));
     }
 
     /* Free the object. */
@@ -1785,7 +1790,7 @@ gckVGHARDWARE_SetPowerManagementState(
 
     if (State == gcvPOWER_IDLE)
     {
-        gcmkVERIFY_OK(gckOS_Signal(os, Hardware->idleSignal, gcvTRUE));
+        gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->idleSemaphore));
     }
         /* Reset power off time */
     gcmkVERIFY_OK(gckOS_GetTicks(&currentTime));
index cff634f8bbecfd390204f86f89360483f875a95a..a4ec3eb05afc73ed018ea7ded71d957368d99232 100644 (file)
@@ -57,7 +57,7 @@ struct _gckVGHARDWARE
     gctBOOL                     clockState;
     gctBOOL                     powerState;
     gctPOINTER                  powerMutex;
-    gctSIGNAL                   idleSignal;
+    gctSEMAPHORE                idleSemaphore;
     gctUINT32                   powerProcess;
     gctUINT32                   powerThread;
     gceCHIPPOWERSTATE           chipPowerState;
index 5321a2d68a9831a096f68904574f2627c3bdb9f4..edf4354167ad122c4defac94fe73470ea33e0dbd 100644 (file)
@@ -720,7 +720,6 @@ gckHARDWARE_InitializeHardware(
                                       0x00428,
                                       baseAddress));
 
-#ifndef VIVANTE_NO_3D
     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
                                       Hardware->core,
                                       0x00420,
@@ -730,7 +729,6 @@ gckHARDWARE_InitializeHardware(
                                       Hardware->core,
                                       0x00424,
                                       baseAddress));
-#endif
 
 #if !VIVANTE_PROFILER && 1
     {
@@ -785,19 +783,83 @@ gckHARDWARE_InitializeHardware(
                                       + 0x00104,
                                       data));
         }
+
+        /* Disable SE clock gating on imx6 (bug #3383). */
+        if ((Hardware->identity.chipModel == gcv2000)
+        &&  (Hardware->identity.chipRevision  == 0x5108))
+        {
+            gcmkONERROR(
+                gckOS_ReadRegisterEx(Hardware->os,
+                                     Hardware->core,
+                                     Hardware->powerBaseAddress
+                                     + 0x00104,
+                                     &data));
+
+            /* Disable RA clock gating. */
+            data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+
+            /* Disable PE clock gating. */
+           data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
+
+            /* Disable TX clock gating. */
+            data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
+
+            gcmkONERROR(
+                gckOS_WriteRegisterEx(Hardware->os,
+                                      Hardware->core,
+                                      Hardware->powerBaseAddress
+                                      + 0x00104,
+                                      data));
+
+            gcmkONERROR(
+                gckOS_ReadRegisterEx(Hardware->os,
+                                     Hardware->core,
+                                     Hardware->powerBaseAddress
+                                     + 0x00100,
+                                     &data));
+
+            /* change turnon counter value to 1. */
+            data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1))))))) << (0 ? 7:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1))))))) << (0 ? 7:4)));
+
+            /* change turnoff counter value to 1. */
+            data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16)));
+
+            gcmkONERROR(
+                gckOS_WriteRegisterEx(Hardware->os,
+                                      Hardware->core,
+                                      Hardware->powerBaseAddress
+                                      + 0x00100,
+                                      data));
+
+        }
 #endif
     }
 #endif
 
+    /* Special workaround for HiSi
+    ** Make sure pulse eater kicks in only when SH is idle */
+    if (Hardware->identity.chipModel == gcv4000 &&
+        Hardware->identity.chipRevision == 0x5208)
+    {
+               gcmkONERROR(
+            gckOS_WriteRegisterEx(Hardware->os,
+                                  Hardware->core,
+                                  0x0010C,
+                                  ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23)))));
+    }
+
     /* Test if MMU is initialized. */
     if ((Hardware->kernel      != gcvNULL)
     &&  (Hardware->kernel->mmu != gcvNULL)
     )
     {
         /* Reset MMU. */
-        gcmkONERROR(
-            gckHARDWARE_SetMMU(Hardware,
-                               Hardware->kernel->mmu->pageTableLogical));
+        if (Hardware->mmuVersion == 0)
+        {
+            gcmkONERROR(
+                    gckHARDWARE_SetMMU(Hardware,
+                        Hardware->kernel->mmu->pageTableLogical));
+        }
     }
 
     /* Success. */
@@ -2744,14 +2806,13 @@ gckHARDWARE_SetMMU(
                               0x00410,
                               address + baseAddress));
 
-#ifndef VIVANTE_NO_3D
     /* Write the AQMemoryTxPageTable register. */
     gcmkONERROR(
         gckOS_WriteRegisterEx(Hardware->os,
                               Hardware->core,
                               0x00404,
                               address + baseAddress));
-#endif
+
 
     /* Write the AQMemoryPePageTable register. */
     gcmkONERROR(
@@ -2760,14 +2821,12 @@ gckHARDWARE_SetMMU(
                               0x00408,
                               address + baseAddress));
 
-#ifndef VIVANTE_NO_3D
     /* Write the AQMemoryPezPageTable register. */
     gcmkONERROR(
         gckOS_WriteRegisterEx(Hardware->os,
                               Hardware->core,
                               0x0040C,
                               address + baseAddress));
-#endif
 
     /* Return the status. */
     gcmkFOOTER_NO();
@@ -2897,7 +2956,8 @@ gckHARDWARE_SetMMUv2(
     IN gctBOOL Enable,
     IN gctPOINTER MtlbAddress,
     IN gceMMU_MODE Mode,
-    IN gctPOINTER SafeAddress
+    IN gctPOINTER SafeAddress,
+    IN gctBOOL FromPower
     )
 {
     gceSTATUS status;
@@ -2955,7 +3015,7 @@ gckHARDWARE_SetMMUv2(
     command = Hardware->kernel->command;
 
     /* Acquire the command queue. */
-    gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
+    gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
     commitEntered = gcvTRUE;
 
     gcmkONERROR(gckCOMMAND_Reserve(
@@ -2984,13 +3044,13 @@ gckHARDWARE_SetMMUv2(
     gcmkONERROR(gckCOMMAND_Execute(command, 16));
 
     /* Release the command queue. */
-    gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
+    gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
     commitEntered = gcvFALSE;
 
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
         "call gckCOMMAND_Stall to make sure the config is done.\n ");
 
-    gcmkONERROR(gckCOMMAND_Stall(command, gcvFALSE));
+    gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
 
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
         "Enable MMU through GCREG_MMU_CONTROL.");
@@ -3005,7 +3065,7 @@ gckHARDWARE_SetMMUv2(
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
         "call gckCOMMAND_Stall to check MMU available.\n");
 
-    gcmkONERROR(gckCOMMAND_Stall(command, gcvFALSE));
+    gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
 
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
         "The MMU is available.\n");
@@ -3293,6 +3353,25 @@ gckHARDWARE_SetFastClear(
                        "FastClear=%d Compression=%d", Enable, Compression);
     }
 
+    /* Special patch for 0x320 0x5220. */
+    if (Hardware->identity.chipRevision == 0x5220 && Hardware->identity.chipModel == gcv320)
+    {
+        gctUINT32 debug;
+
+        /* Read AQMemoryDebug register. */
+        gcmkONERROR(
+                gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &debug));
+
+        debug |= 8;
+
+        /* Write back AQMemoryDebug register. */
+        gcmkONERROR(
+                gckOS_WriteRegisterEx(Hardware->os,
+                    Hardware->core,
+                    0x00414,
+                    debug));
+    }
+
     /* Success. */
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
@@ -3919,6 +3998,20 @@ gckHARDWARE_SetPowerManagementState(
 
         /* Start the Isr. */
         gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
+
+        /* Set NEW MMU. */
+        if (Hardware->mmuVersion != 0)
+        {
+            gcmkONERROR(
+                    gckHARDWARE_SetMMUv2(
+                        Hardware,
+                        gcvTRUE,
+                        Hardware->kernel->mmu->pageTableLogical,
+                        gcvMMU_MODE_4K,
+                        (gctUINT8_PTR)Hardware->kernel->mmu->pageTableLogical + gcdMMU_MTLB_SIZE,
+                        gcvTRUE
+                        ));
+        }
     }
 
     /* Get time until started. */
index 8dac7a682950ebddc34cdb44bbc36ac15e29c0a2..b3228d7bae9116336eb1325344187a7236772a6f 100644 (file)
 extern "C" {
 #endif
 
+
+/*******************************************************************************
+***** New MMU Defination *******************************************************/
+#define gcdMMU_MTLB_SHIFT           22
+#define gcdMMU_STLB_4K_SHIFT        12
+#define gcdMMU_STLB_64K_SHIFT       16
+
+#define gcdMMU_MTLB_BITS            (32 - gcdMMU_MTLB_SHIFT)
+#define gcdMMU_PAGE_4K_BITS         gcdMMU_STLB_4K_SHIFT
+#define gcdMMU_STLB_4K_BITS         (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_4K_BITS)
+#define gcdMMU_PAGE_64K_BITS        gcdMMU_STLB_64K_SHIFT
+#define gcdMMU_STLB_64K_BITS        (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_64K_BITS)
+
+#define gcdMMU_MTLB_ENTRY_NUM       (1 << gcdMMU_MTLB_BITS)
+#define gcdMMU_MTLB_SIZE            (gcdMMU_MTLB_ENTRY_NUM << 2)
+#define gcdMMU_STLB_4K_ENTRY_NUM    (1 << gcdMMU_STLB_4K_BITS)
+#define gcdMMU_STLB_4K_SIZE         (gcdMMU_STLB_4K_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_4K_SIZE         (1 << gcdMMU_STLB_4K_SHIFT)
+#define gcdMMU_STLB_64K_ENTRY_NUM   (1 << gcdMMU_STLB_64K_BITS)
+#define gcdMMU_STLB_64K_SIZE        (gcdMMU_STLB_64K_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_64K_SIZE        (1 << gcdMMU_STLB_64K_SHIFT)
+
+#define gcdMMU_MTLB_MASK            (~((1U << gcdMMU_MTLB_SHIFT)-1))
+#define gcdMMU_STLB_4K_MASK         ((~0U << gcdMMU_STLB_4K_SHIFT) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_4K_MASK         (gcdMMU_PAGE_4K_SIZE - 1)
+#define gcdMMU_STLB_64K_MASK        ((~((1U << gcdMMU_STLB_64K_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_64K_MASK        (gcdMMU_PAGE_64K_SIZE - 1)
+
 /*******************************************************************************
 ***** Process Secure Cache ****************************************************/
 
@@ -311,6 +339,10 @@ struct _gckKERNEL
 #if gcdENABLE_VG
     gckVGKERNEL                 vg;
 #endif
+
+#if gcdMULTICORE_MAPPING
+    gckKERNEL                   anotherKernel;
+#endif
 };
 
 /* gckCOMMAND object. */
@@ -552,6 +584,10 @@ typedef union _gcuVIDMEM_NODE
 
         /* */
         gcsVIDMEM_NODE_SHARED_INFO sharedInfo;
+
+#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
+        gctPOINTER              kernelVirtual;
+#endif
     }
     VidMem;
 
index d9398ff054730f0e011e1017d944ffc965bcffc3..7f5cd4607352f45c8d70dc60dddcc993a10e5b8f 100644 (file)
@@ -697,6 +697,8 @@ _ScheduleTasks(
                 /* Copy tasks. */
                 do
                 {
+                    gcsTASK_HEADER_PTR taskHeader = (gcsTASK_HEADER_PTR) (userTask + 1);
+
                     gcmkTRACE_ZONE(
                         gcvLEVEL_VERBOSE, gcvZONE_COMMAND,
                         "    task ID = %d, size = %d\n",
@@ -704,9 +706,16 @@ _ScheduleTasks(
                         userTask->size
                         );
 
+#ifdef __QNXNTO__
+                    if (taskHeader->id == gcvTASK_SIGNAL)
+                    {
+                        ((gcsTASK_SIGNAL_PTR)taskHeader)->coid  = TaskTable->coid;
+                        ((gcsTASK_SIGNAL_PTR)taskHeader)->rcvid = TaskTable->rcvid;
+                    }
+#endif /* __QNXNTO__ */
                     /* Copy the task data. */
                     gcmkVERIFY_OK(gckOS_MemCopy(
-                        kernelTask, userTask + 1, userTask->size
+                        kernelTask, taskHeader, userTask->size
                         ));
 
                     /* Advance to the next task. */
@@ -791,10 +800,34 @@ _HardwareToKernel(
     gceSTATUS status;
     gckVIDMEM memory;
     gctUINT32 offset;
+#if gcdDYNAMIC_MAP_RESERVED_MEMORY
+    gctUINT32 nodePhysical;
+#endif
 
     /* Assume a non-virtual node and get the pool manager object. */
     memory = Node->VidMem.memory;
 
+#if gcdDYNAMIC_MAP_RESERVED_MEMORY
+    nodePhysical = memory->baseAddress
+                 + Node->VidMem.offset
+                 + Node->VidMem.alignment;
+
+    if (Node->VidMem.kernelVirtual == gcvNULL)
+    {
+        status = gckOS_MapReservedMemoryToKernel(Os,
+                        nodePhysical,
+                        Node->VidMem.bytes,
+                        (gctPOINTER *)&Node->VidMem.kernelVirtual);
+
+        if (gcmkIS_ERROR(status))
+        {
+            return status;
+        }
+    }
+
+    offset = Address - nodePhysical;
+    *KernelPointer = Node->VidMem.kernelVirtual + offset;
+#else
     /* Determine the header offset within the pool it is allocated in. */
     offset = Address - memory->baseAddress;
 
@@ -805,6 +838,7 @@ _HardwareToKernel(
         offset,
         KernelPointer
         );
+#endif
 
     /* Return status. */
     return status;
@@ -3307,6 +3341,11 @@ gckVGCOMMAND_Commit(
     gcmkVERIFY_ARGUMENT(Queue != gcvNULL);
     gcmkVERIFY_ARGUMENT(EntryCount > 1);
 
+#ifdef __QNXNTO__
+    TaskTable->coid     = Context->coid;
+    TaskTable->rcvid    = Context->rcvid;
+#endif /* __QNXNTO__ */
+
     do
     {
         gctBOOL haveFETasks;
index 1efdc5f10368a6fb18f8976950dd4410827ff56c..052be7de4487418a5265a593540e748b585d33d6 100644 (file)
@@ -828,8 +828,12 @@ gckEVENT_AddList(
     gcsEVENT_PTR record = gcvNULL;
     gcsEVENT_QUEUE_PTR queue;
 
-    gcmkHEADER_ARG("Event=0x%x Interface=0x%x FromWhere=%d AllocateAllowed=%d",
-                   Event, Interface, FromWhere, AllocateAllowed);
+    gcmkHEADER_ARG("Event=0x%x Interface=0x%x",
+                   Event, Interface);
+
+    gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, _GC_OBJ_ZONE,
+                    "FromWhere=%d AllocateAllowed=%d",
+                    FromWhere, AllocateAllowed);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
@@ -1799,7 +1803,7 @@ gckEVENT_Notify(
 
         /* Get current interrupts. */
 #if gcdSMP
-        gckOS_AtomGet(Event->os, Event->pending, &pending);
+        gckOS_AtomGet(Event->os, Event->pending, (gctINT32_PTR)&pending);
 #else
         pending = Event->pending;
 #endif
@@ -1877,7 +1881,7 @@ gckEVENT_Notify(
 #if gcdSMP
             gckOS_AtomClearMask(Event->pending, pending);
 #elif defined(__QNXNTO__)
-            atomic_set(&Event->pending, pending);
+            atomic_clr((gctUINT32_PTR)&Event->pending, pending);
 #else
             Event->pending &= ~pending;
 #endif
index cbc921a713b0a00b4e6ba72fa4dc9cbf6cb5aae3..ec5dd4c346b006f207e14c8c8cefdb9f68ec56b0 100644 (file)
@@ -759,10 +759,19 @@ gckVGINTERRUPT_Disable(
 **      Nothing.
 */
 
+#ifndef __QNXNTO__
 gceSTATUS
 gckVGINTERRUPT_Enque(
     IN gckVGINTERRUPT Interrupt
     )
+#else
+gceSTATUS
+gckVGINTERRUPT_Enque(
+    IN gckVGINTERRUPT Interrupt,
+    OUT gckOS *Os,
+    OUT gctSEMAPHORE *Semaphore
+    )
+#endif
 {
     gceSTATUS status;
     gctUINT32 triggered;
@@ -772,6 +781,11 @@ gckVGINTERRUPT_Enque(
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Interrupt, gcvOBJ_INTERRUPT);
 
+#ifdef __QNXNTO__
+    *Os = gcvNULL;
+    *Semaphore = gcvNULL;
+#endif
+
     do
     {
         /* Read interrupt status register. */
@@ -815,10 +829,15 @@ gckVGINTERRUPT_Enque(
             /* Set the new value. */
             Interrupt->fifo[Interrupt->head] = triggered;
 
+#ifndef __QNXNTO__
             /* Increment the FIFO semaphore. */
             gcmkERR_BREAK(gckOS_IncrementSemaphore(
                 Interrupt->os, Interrupt->fifoValid
                 ));
+#else
+            *Os = Interrupt->os;
+            *Semaphore = Interrupt->fifoValid;
+#endif
 
             /* Windows kills our threads prematurely when the application
                exists. Verify here that the thread is still alive. */
index 7ef88356a9b58ff5fe7e05daceef9acb15d5dabf..2f16004fb4ff030d1bfb449fd3c6240d7a8b6162 100644 (file)
@@ -35,31 +35,6 @@ gceMMU_TYPE;
 
 #define gcdMMU_TABLE_DUMP       0
 
-#define gcdMMU_MTLB_SHIFT           22
-#define gcdMMU_STLB_4K_SHIFT        12
-#define gcdMMU_STLB_64K_SHIFT       16
-
-#define gcdMMU_MTLB_BITS            (32 - gcdMMU_MTLB_SHIFT)
-#define gcdMMU_PAGE_4K_BITS         gcdMMU_STLB_4K_SHIFT
-#define gcdMMU_STLB_4K_BITS         (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_4K_BITS)
-#define gcdMMU_PAGE_64K_BITS        gcdMMU_STLB_64K_SHIFT
-#define gcdMMU_STLB_64K_BITS        (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_64K_BITS)
-
-#define gcdMMU_MTLB_ENTRY_NUM       (1 << gcdMMU_MTLB_BITS)
-#define gcdMMU_MTLB_SIZE            (gcdMMU_MTLB_ENTRY_NUM << 2)
-#define gcdMMU_STLB_4K_ENTRY_NUM    (1 << gcdMMU_STLB_4K_BITS)
-#define gcdMMU_STLB_4K_SIZE         (gcdMMU_STLB_4K_ENTRY_NUM << 2)
-#define gcdMMU_PAGE_4K_SIZE         (1 << gcdMMU_STLB_4K_SHIFT)
-#define gcdMMU_STLB_64K_ENTRY_NUM   (1 << gcdMMU_STLB_64K_BITS)
-#define gcdMMU_STLB_64K_SIZE        (gcdMMU_STLB_64K_ENTRY_NUM << 2)
-#define gcdMMU_PAGE_64K_SIZE        (1 << gcdMMU_STLB_64K_SHIFT)
-
-#define gcdMMU_MTLB_MASK            (~((1U << gcdMMU_MTLB_SHIFT)-1))
-#define gcdMMU_STLB_4K_MASK         ((~0U << gcdMMU_STLB_4K_SHIFT) ^ gcdMMU_MTLB_MASK)
-#define gcdMMU_PAGE_4K_MASK         (gcdMMU_PAGE_4K_SIZE - 1)
-#define gcdMMU_STLB_64K_MASK        ((~((1U << gcdMMU_STLB_64K_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
-#define gcdMMU_PAGE_64K_MASK        (gcdMMU_PAGE_64K_SIZE - 1)
-
 typedef struct _gcsMMU_STLB *gcsMMU_STLB_PTR;
 
 typedef struct _gcsMMU_STLB
@@ -1190,7 +1165,8 @@ gckMMU_Enable(
                 gcvTRUE,
                 Mmu->pageTableLogical,
                 gcvMMU_MODE_4K,
-                (gctUINT8_PTR)Mmu->pageTableLogical + gcdMMU_MTLB_SIZE
+                (gctUINT8_PTR)Mmu->pageTableLogical + gcdMMU_MTLB_SIZE,
+                gcvFALSE
                 ));
 
         Mmu->enabled = gcvTRUE;
index dd3c662609103dbca897e3cb00d7cb56682374e8..29d28e8fe34920c02ba15fafb863d73af24ecd91 100644 (file)
@@ -523,6 +523,21 @@ gceSTATUS gckVGKERNEL_Dispatch(
         break;
 
     case gcvHAL_FREE_VIDEO_MEMORY:
+#ifdef __QNXNTO__
+        /* Unmap the video memory */
+        node = Interface->u.FreeVideoMemory.node;
+
+        if ((node->VidMem.memory->object.type == gcvOBJ_VIDMEM) &&
+            (node->VidMem.logical != gcvNULL))
+        {
+            gckKERNEL_UnmapVideoMemory(Kernel,
+                                       node->VidMem.logical,
+                                       processID,
+                                       node->VidMem.bytes);
+            node->VidMem.logical = gcvNULL;
+        }
+#endif /* __QNXNTO__ */
+
         /* Free video memory. */
         gcmkERR_BREAK(gckVIDMEM_Free(
             Interface->u.FreeVideoMemory.node
index f3fdc7530c42097fb16fe0d483cd9ce659fb592b..33438b617bfe23c1172257cdb9d7116ea85d6790 100644 (file)
@@ -788,7 +788,15 @@ _FindNode(
 #if gcdENABLE_BANK_ALIGNMENT
     gctUINT32 bankAlignment;
     gceSTATUS status;
+#endif
+
+    if (Memory->sentinel[Bank].VidMem.nextFree == gcvNULL)
+    {
+        /* No free nodes left. */
+        return gcvNULL;
+    }
 
+#if gcdENABLE_BANK_ALIGNMENT
     /* Walk all free nodes until we have one that is big enough or we have
     ** reached the sentinel. */
     for (node = Memory->sentinel[Bank].VidMem.nextFree;
@@ -1077,6 +1085,10 @@ gckVIDMEM_AllocateLinear(
 
     node->VidMem.freePending = gcvFALSE;
 
+#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
+    node->VidMem.kernelVirtual = gcvNULL;
+#endif
+
     /* Release the mutex. */
     gcmkVERIFY_OK(gckOS_ReleaseMutex(Memory->os, Memory->mutex));
 
@@ -1182,6 +1194,18 @@ gckVIDMEM_Free(
         )
 #endif
         {
+#if gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
+            if (Node->VidMem.kernelVirtual)
+            {
+                gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                        "%s(%d) Unmap %x from kernel space.",
+                        __FUNCTION__, __LINE__,
+                        Node->VidMem.kernelVirtual);
+
+                gckOS_UnmapReservedMemoryFromKernel(Node->VidMem.kernelVirtual);
+                Node->VidMem.kernelVirtual = gcvNULL;
+            }
+#endif
             /* Update the number of free bytes. */
             memory->freeBytes += Node->VidMem.bytes;
 
@@ -1408,6 +1432,87 @@ OnError:
 }
 #endif
 
+/*******************************************************************************
+**
+** _NeedVirtualMapping
+**
+**  Whether setup GPU page table for video node.
+**
+**  INPUT:
+**      gckKERNEL Kernel
+**          Pointer to an gckKERNEL object.
+**
+**      gcuVIDMEM_NODE_PTR Node
+**          Pointer to a gcuVIDMEM_NODE union.
+**
+**      gceCORE  Core
+**          Id of current GPU.
+**
+**  OUTPUT:
+**      gctBOOL * NeedMapping
+**          A pointer hold the result whether Node should be mapping.
+*/
+static gceSTATUS
+_NeedVirtualMapping(
+    IN gckKERNEL Kernel,
+    IN gceCORE  Core,
+    IN gcuVIDMEM_NODE_PTR Node,
+    OUT gctBOOL * NeedMapping
+)
+{
+    gceSTATUS status;
+    gctUINT32 phys;
+    gctUINT32 end;
+    gcePOOL pool;
+    gctUINT32 offset;
+
+    gcmkHEADER_ARG("Node=0x%X", Node);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
+    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+    gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL);
+    gcmkVERIFY_ARGUMENT(Core < gcdCORE_COUNT);
+
+    if (Node->Virtual.contiguous)
+    {
+#if gcdENABLE_VG
+        if (Core == gcvCORE_VG)
+        {
+            *NeedMapping = gcvFALSE;
+        }
+        else
+#endif
+        {
+            /* For cores which can't access all physical address. */
+            gcmkONERROR(gckOS_GetPhysicalAddress(Kernel->os,
+                        Node->Virtual.logical,
+                        &phys));
+
+            /* If part of region is belong to gcvPOOL_VIRTUAL,
+            ** whole region has to be mapped. */
+            end = phys + Node->Virtual.bytes - 1;
+
+            gcmkONERROR(gckHARDWARE_SplitMemory(
+                        Kernel->hardware, end, &pool, &offset
+                        ));
+
+            *NeedMapping = (pool == gcvPOOL_VIRTUAL);
+        }
+    }
+    else
+    {
+        *NeedMapping = gcvTRUE;
+    }
+
+    gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping);
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
 /*******************************************************************************
 **
 **  gckVIDMEM_Lock
@@ -1439,6 +1544,7 @@ gckVIDMEM_Lock(
     gctBOOL acquired = gcvFALSE;
     gctBOOL locked = gcvFALSE;
     gckOS os = gcvNULL;
+    gctBOOL needMapping;
 
     gcmkHEADER_ARG("Node=0x%x", Node);
 
@@ -1527,7 +1633,9 @@ gckVIDMEM_Lock(
 
             locked = gcvTRUE;
 
-            if (Node->Virtual.contiguous)
+            gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, Node, &needMapping));
+
+            if (needMapping == gcvFALSE)
             {
                 /* Get physical address directly */
                  gcmkONERROR(gckOS_GetPhysicalAddress(os,
@@ -1549,33 +1657,66 @@ gckVIDMEM_Lock(
                 else
 #endif
                 {
-                    /* Allocate pages inside the MMU. */
-                    gcmkONERROR(
-                        gckMMU_AllocatePages(Kernel->mmu,
-                                             Node->Virtual.pageCount,
-                                             &Node->Virtual.pageTables[Kernel->core],
-                                             &Node->Virtual.addresses[Kernel->core]));
-                }
+                    if (Node->Virtual.pageTables[Kernel->core] == gcvNULL)
+                    {
+#if gcdMULTICORE_MAPPING
+                        gckKERNEL anotherKernel = Kernel->anotherKernel;
+#endif
 
-                Node->Virtual.lockKernels[Kernel->core] = Kernel;
+                        /* Allocate pages inside the MMU. */
+                        gcmkONERROR(
+                                gckMMU_AllocatePages(Kernel->mmu,
+                                    Node->Virtual.pageCount,
+                                    &Node->Virtual.pageTables[Kernel->core],
+                                    &Node->Virtual.addresses[Kernel->core]));
+
+                        Node->Virtual.lockKernels[Kernel->core] = Kernel;
+
+#if gcdMULTICORE_MAPPING
+                        if (anotherKernel)
+                        {
+                            gcmkONERROR(
+                                    gckMMU_AllocatePages(anotherKernel->mmu,
+                                        Node->Virtual.pageCount,
+                                        &Node->Virtual.pageTables[anotherKernel->core],
+                                        &Node->Virtual.addresses[anotherKernel->core]));
+
+                            Node->Virtual.lockKernels[anotherKernel->core] = Kernel;
+                        }
+#endif
 
-                /* Map the pages. */
+                        /* Map the pages. */
 #ifdef __QNXNTO__
-                gcmkONERROR(
-                    gckOS_MapPagesEx(os,
+                        gcmkONERROR(
+                                gckOS_MapPagesEx(os,
                                      Kernel->core,
                                      Node->Virtual.physical,
                                      Node->Virtual.logical,
                                      Node->Virtual.pageCount,
                                      Node->Virtual.pageTables[Kernel->core]));
 #else
-                gcmkONERROR(
-                    gckOS_MapPagesEx(os,
-                                     Kernel->core,
-                                     Node->Virtual.physical,
-                                     Node->Virtual.pageCount,
-                                     Node->Virtual.pageTables[Kernel->core]));
+
+                        gcmkONERROR(
+                                gckOS_MapPagesEx(os,
+                                    Kernel->core,
+                                    Node->Virtual.physical,
+                                    Node->Virtual.pageCount,
+                                    Node->Virtual.pageTables[Kernel->core]));
+
+#if gcdMULTICORE_MAPPING
+                        if (anotherKernel)
+                        {
+                            gcmkONERROR(
+                                    gckOS_MapPagesEx(os,
+                                        anotherKernel->core,
+                                        Node->Virtual.physical,
+                                        Node->Virtual.pageCount,
+                                        Node->Virtual.pageTables[anotherKernel->core]));
+                        }
+#endif
 #endif
+                    }
+                }
             }
 
             gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
@@ -1728,6 +1869,21 @@ gckVIDMEM_Unlock(
                       Node,
                       Node->VidMem.locked);
 
+#ifdef __QNXNTO__
+        /* Unmap the video memory */
+        if ((Node->VidMem.locked == 0) && (Node->VidMem.logical != gcvNULL))
+        {
+            if (Kernel->core == gcvCORE_VG)
+            {
+                gckKERNEL_UnmapVideoMemory(Kernel,
+                                           Node->VidMem.logical,
+                                           Node->VidMem.processID,
+                                           Node->VidMem.bytes);
+                Node->VidMem.logical = gcvNULL;
+            }
+        }
+#endif /* __QNXNTO__ */
+
         if (Node->VidMem.freePending && (Node->VidMem.locked == 0))
         {
             /* Client has unlocked node previously attempted to be freed by compositor. Free now. */
@@ -1785,18 +1941,12 @@ gckVIDMEM_Unlock(
                             gckVGMMU_FreePages(Kernel->vg->mmu,
                                              Node->Virtual.pageTables[Kernel->core],
                                              Node->Virtual.pageCount));
+
+                        /* Mark page table as freed. */
+                        Node->Virtual.pageTables[Kernel->core] = gcvNULL;
+                        Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
                     }
-                    else
 #endif
-                    {
-                        gcmkONERROR(
-                            gckMMU_FreePages(Kernel->mmu,
-                                             Node->Virtual.pageTables[Kernel->core],
-                                             Node->Virtual.pageCount));
-                    }
-                    /* Mark page table as freed. */
-                    Node->Virtual.pageTables[Kernel->core] = gcvNULL;
-                    Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
                 }
 
 #ifdef __QNXNTO__
@@ -1812,6 +1962,39 @@ gckVIDMEM_Unlock(
 
             if (totalLocked == 0)
             {
+                if (Node->Virtual.pageTables[Kernel->core] != gcvNULL)
+                {
+#if gcdMULTICORE_MAPPING
+                    gckKERNEL anotherKernel = Kernel->anotherKernel;
+#endif
+                    gcmkONERROR(
+                        gckMMU_FreePages(Kernel->mmu,
+                                         Node->Virtual.pageTables[Kernel->core],
+                                         Node->Virtual.pageCount));
+
+#if gcdMULTICORE_MAPPING
+                    if (anotherKernel)
+                    {
+                        gcmkONERROR(
+                                gckMMU_FreePages(anotherKernel->mmu,
+                                    Node->Virtual.pageTables[anotherKernel->core],
+                                    Node->Virtual.pageCount));
+                    }
+#endif
+
+                    /* Mark page table as freed. */
+                    Node->Virtual.pageTables[Kernel->core] = gcvNULL;
+                    Node->Virtual.lockKernels[Kernel->core] = gcvNULL;
+
+#if gcdMULTICORE_MAPPING
+                    if (anotherKernel)
+                    {
+                        Node->Virtual.pageTables[anotherKernel->core] = gcvNULL;
+                        Node->Virtual.lockKernels[anotherKernel->core] = gcvNULL;
+                    }
+#endif
+                }
+
                 /* Owner have already freed this node
                 ** and we are the last one to unlock, do
                 ** real free */
index e2a6b66fa1bb865ab74f2d9e6a0ba54235b67546..0b1417665440fc12151041799760c363c2f420f2 100644 (file)
@@ -1895,7 +1895,8 @@ gckHARDWARE_SetMMUv2(
     IN gctBOOL Enable,
     IN gctPOINTER MtlbAddress,
     IN gceMMU_MODE Mode,
-    IN gctPOINTER SafeAddress
+    IN gctPOINTER SafeAddress,
+    IN gctBOOL FromPower
     );
 
 /* Get idle register. */
index 03631fe1528ff6253dce3f917ba337bd0d778bde..6137f5f857c618b58e24d887f6bec6449f12e84a 100644 (file)
@@ -123,6 +123,11 @@ typedef struct _gcsTLS
     gctPOINTER                  context;
     gctTLS_DESTRUCTOR           destructor;
     gctBOOL                     ProcessExiting;
+
+#ifndef VIVANTE_NO_3D
+       gco3D                                           engine3D;
+#endif
+       gco2D                                           engine2D;
 }
 gcsTLS;
 
@@ -337,6 +342,32 @@ gcoHAL_Get3DEngine(
     IN gcoHAL Hal,
     OUT gco3D * Engine
     );
+
+gceSTATUS
+gcoHAL_Query3DEngine(
+    IN gcoHAL Hal,
+    OUT gco3D * Engine
+    );
+
+gceSTATUS
+gcoHAL_Set3DEngine(
+    IN gcoHAL Hal,
+    IN gco3D Engine
+    );
+
+gceSTATUS
+gcoHAL_Get3DHardware(
+    IN gcoHAL Hal,
+    OUT gcoHARDWARE * Hardware
+    );
+
+gceSTATUS
+gcoHAL_Set3DHardware(
+    IN gcoHAL Hal,
+    IN gcoHARDWARE Hardware
+    );
+
+
 #endif /* VIVANTE_NO_3D */
 
 /* Verify whether the specified feature is available in hardware. */
@@ -1855,6 +1886,13 @@ gcoSURF_NODE_Cache(
     IN gceCACHEOPERATION Operation
     );
 
+/* Perform CPU cache operation on surface */
+gceSTATUS
+gcoSURF_CPUCacheOperation(
+    IN gcoSURF Surface,
+    IN gceCACHEOPERATION Operation
+    );
+
 /******************************************************************************\
 ********************************* gcoDUMP Object ********************************
 \******************************************************************************/
index 37715ffdd504e8967fec737f3eea47ec249c0a25..7c2c3469b8d64011e66891039be0a64d30e48cf7 100644 (file)
 extern "C" {
 #endif
 
+#ifndef GC_ENABLE_LOADTIME_OPT
+#define GC_ENABLE_LOADTIME_OPT      0
+#endif
+
 /******************************* IR VERSION ******************/
 #define gcdSL_IR_VERSION gcmCC('\0','\0','\0','\1')
 
@@ -104,33 +108,33 @@ typedef enum _gcSL_OPCODE
        gcSL_LOAD,                                                      /* 0x36 */
        gcSL_STORE,                                                     /* 0x37 */
        gcSL_BARRIER,                                           /* 0x38 */
-       gcSL_SIN_CL,                                            /* 0x39 */
-       gcSL_COS_CL,                                            /* 0x3A */
-       gcSL_TAN_CL,                                            /* 0x3B */
-       gcSL_ACOS_CL,                                           /* 0x3C */
-       gcSL_ASIN_CL,                                           /* 0x3D */
-       gcSL_ATAN_CL,                                           /* 0x3E */
-       gcSL_SINH_CL,                                           /* 0x3F */
-       gcSL_COSH_CL,                                           /* 0x40 */
-       gcSL_TANH_CL,                                           /* 0x41 */
-       gcSL_ASINH_CL,                                          /* 0x42 */
-       gcSL_ACOSH_CL,                                          /* 0x43 */
-       gcSL_ATANH_CL,                                          /* 0x44 */
-       gcSL_SINPI_CL,                                          /* 0x45 */
-       gcSL_COSPI_CL,                                          /* 0x46 */
-       gcSL_TANPI_CL,                                          /* 0x47 */
-       gcSL_ASINPI_CL,                                         /* 0x48 */
-       gcSL_ACOSPI_CL,                                         /* 0x49 */
-       gcSL_ATANPI_CL,                                         /* 0x4A */
-       gcSL_ATAN2_CL,                                          /* 0x4B */
-       gcSL_ATAN2PI_CL,                                        /* 0x4C */
-       gcSL_POW_CL,                                            /* 0x4D */
-       gcSL_RSQ_CL,                                            /* 0x4E */
-       gcSL_LOG_CL,                                            /* 0x4F */
-       gcSL_EXP_CL,                                            /* 0x50 */
-       gcSL_SQRT_CL,                                           /* 0x51 */
-       gcSL_CBRT_CL,                                           /* 0x52 */
-       gcSL_ADDLO,                                                     /* 0x53 */  /* Float only. */
+       gcSL_STORE1,                                            /* 0x39 */
+       /*gcSL_COS_CL,                                           0x3A */
+       /*gcSL_TAN_CL,                                           0x3B */
+       /*gcSL_ACOS_CL,                                          0x3C */
+       /*gcSL_ASIN_CL,                                          0x3D */
+       /*gcSL_ATAN_CL,                                          0x3E */
+       /*gcSL_SINH_CL,                                          0x3F */
+       /*gcSL_COSH_CL,                                          0x40 */
+       /*gcSL_TANH_CL,                                          0x41 */
+       /*gcSL_ASINH_CL,                                                 0x42 */
+       /*gcSL_ACOSH_CL,                                                 0x43 */
+       /*gcSL_ATANH_CL,                                                 0x44 */
+       /*gcSL_SINPI_CL,                                                 0x45 */
+       /*gcSL_COSPI_CL,                                                 0x46 */
+       /*gcSL_TANPI_CL,                                                 0x47 */
+       /*gcSL_ASINPI_CL,                                                0x48 */
+       /*gcSL_ACOSPI_CL,                                                0x49 */
+       /*gcSL_ATANPI_CL,                                                0x4A */
+       /*gcSL_ATAN2_CL,                                                 0x4B */
+       /*gcSL_ATAN2PI_CL,                                       0x4C */
+       /*gcSL_POW_CL,                                           0x4D */
+       /*gcSL_RSQ_CL,                                           0x4E */
+       /*gcSL_LOG_CL,                                           0x4F */
+       /*gcSL_EXP_CL,                                           0x50 */
+       /*gcSL_SQRT_CL,                                          0x51 */
+       /*gcSL_CBRT_CL,                                          0x52 */
+       gcSL_ADDLO = 0x53,                                                      /* 0x53 */  /* Float only. */
        gcSL_MULLO,                                                     /* 0x54 */  /* Float only. */
        gcSL_CONV,                                                      /* 0x55 */
        gcSL_GETEXP,                                            /* 0x56 */
@@ -169,6 +173,7 @@ gcSL_FORMAT;
 /* Destination write enable bits. */
 typedef enum _gcSL_ENABLE
 {
+    gcSL_ENABLE_NONE                    = 0x0,     /* none is enabled, error/uninitialized state */
        gcSL_ENABLE_X                                           = 0x1,
        gcSL_ENABLE_Y                                           = 0x2,
        gcSL_ENABLE_Z                                           = 0x4,
@@ -264,22 +269,40 @@ typedef enum _gcSL_SWIZZLE
        gcSL_SWIZZLE_XXYZ = gcmSWIZZLE(X, X, Y, Z),
        gcSL_SWIZZLE_XYZW = gcmSWIZZLE(X, Y, Z, W),
        gcSL_SWIZZLE_XYXY = gcmSWIZZLE(X, Y, X, Y),
+       gcSL_SWIZZLE_YYZZ = gcmSWIZZLE(Y, Y, Z, Z),
+       gcSL_SWIZZLE_YYWW = gcmSWIZZLE(Y, Y, W, W),
+       gcSL_SWIZZLE_ZZZW = gcmSWIZZLE(Z, Z, Z, W),
+       gcSL_SWIZZLE_XZZW = gcmSWIZZLE(X, Z, Z, W),
+       gcSL_SWIZZLE_YYZW = gcmSWIZZLE(Y, Y, Z, W),
 
     gcSL_SWIZZLE_INVALID = 0x7FFFFFFF
 }
 gcSL_SWIZZLE;
 
+typedef enum _gcSL_COMPONENT
+{
+       gcSL_COMPONENT_X,               /* 0x0 */
+       gcSL_COMPONENT_Y,               /* 0x1 */
+       gcSL_COMPONENT_Z,               /* 0x2 */
+       gcSL_COMPONENT_W,               /* 0x3 */
+    gcSL_COMPONENT_COUNT            /* 0x4 */
+} gcSL_COMPONENT;
+
+#define gcmIsComponentEnabled(Enable, Component) (((Enable) & (1 << (Component))) != 0)
 
 /******************************************************************************\
 |*********************************** SHADERS **********************************|
 \******************************************************************************/
 
 /* Shader types. */
-#define gcSHADER_TYPE_UNKNOWN                  0
-#define gcSHADER_TYPE_VERTEX                   1
-#define gcSHADER_TYPE_FRAGMENT                 2
-#define gcSHADER_TYPE_CL                       3
-#define gcSHADER_TYPE_PRECOMPILED              4
+typedef enum _gcSHADER_KIND {
+    gcSHADER_TYPE_UNKNOWN = 0,
+    gcSHADER_TYPE_VERTEX,
+    gcSHADER_TYPE_FRAGMENT,
+    gcSHADER_TYPE_CL,
+    gcSHADER_TYPE_PRECOMPILED,
+    gcSHADER_KIND_COUNT
+} gcSHADER_KIND;
 
 #define gcm
 /* gcSHADER objects. */
@@ -372,10 +395,49 @@ typedef enum _gcSHADER_TYPE
        gcSHADER_USAMPLER_3D,                   /* 0x24 */
        gcSHADER_USAMPLER_CUBIC,                /* 0x25 */
        gcSHADER_SAMPLER_EXTERNAL_OES,          /* 0x26 */
-
+    gcSHADER_TYPE_COUNT
 }
 gcSHADER_TYPE;
 
+#if GC_ENABLE_LOADTIME_OPT
+
+typedef struct _gcSHADER_TYPE_INFO
+{
+    gcSHADER_TYPE    type;        /* eg. gcSHADER_FLOAT_2X3 is the type */
+    gctCONST_STRING  name;        /* the name of the type: "gcSHADER_FLOAT_2X3" */
+    gcSHADER_TYPE    baseType;    /* its base type is gcSHADER_FLOAT_2 */
+    gctINT           components;  /* it has 2 components */
+    gctINT           rows;        /* and 3 rows */
+    gctINT           size;        /* the size in byte */
+} gcSHADER_TYPE_INFO;
+
+enum gceLTCDumpOption {
+    gceLTC_DUMP_UNIFORM      = 0x0001,
+    gceLTC_DUMP_EVALUATION   = 0x0002,
+    gceLTC_DUMP_EXPESSION    = 0x0004,
+};
+
+gctBOOL _dumpOption(gctINT Opt);
+
+extern gcSHADER_TYPE_INFO shader_type_info[];
+
+#endif /* GC_ENABLE_LOADTIME_OPT */
+
+
+#define IS_MATRIX_TYPE(type) \
+    (((type >= gcSHADER_FLOAT_2X2) && (type <= gcSHADER_FLOAT_4X4)) || \
+     ((type >= gcSHADER_FLOAT_2X3) && (type <= gcSHADER_FLOAT_4X3)))
+
+/* gcSHADER_PRECISION enumeration. */
+typedef enum _gcSHADER_PRECISION
+{
+       gcSHADER_PRECISION_DEFAULT,                             /* 0x00 */
+       gcSHADER_PRECISION_HIGH,                                /* 0x01 */
+       gcSHADER_PRECISION_MEDIUM,                              /* 0x02 */
+       gcSHADER_PRECISION_LOW,                             /* 0x03 */
+}
+gcSHADER_PRECISION;
+
 /* Shader flags. */
 typedef enum _gceSHADER_FLAGS
 {
@@ -386,6 +448,7 @@ typedef enum _gceSHADER_FLAGS
        gcvSHADER_USE_GL_POSITION                       = 0x10,
        gcvSHADER_USE_GL_FACE                           = 0x20,
        gcvSHADER_USE_GL_POINT_COORD            = 0x40,
+       gcvSHADER_LOADTIME_OPTIMIZER            = 0x80,
 }
 gceSHADER_FLAGS;
 
@@ -420,8 +483,9 @@ typedef enum _gceUNIFORM_FLAGS
        gcvUNIFORM_GLOBAL_OFFSET                = 0x200,
        gcvUNIFORM_WORK_DIM                     = 0x400,
        gcvUNIFORM_KERNEL_ARG_CONSTANT          = 0x800,
-       gcvUNIFORM_KERNEL_ARG_LOCAL_MEM_SIZE    = 0x1000,
+       gcvUNIFORM_KERNEL_ARG_LOCAL_MEM_SIZE    = 0x1000,
        gcvUNIFORM_KERNEL_ARG_PRIVATE           = 0x2000,
+       gcvUNIFORM_LOADTIME_CONSTANT            = 0x4000,
 }
 gceUNIFORM_FLAGS;
 
@@ -906,6 +970,45 @@ gcSHADER_AddUniform(
        OUT gcUNIFORM * Uniform
        );
 
+
+/*******************************************************************************
+**                                                        gcSHADER_AddUniformEx
+********************************************************************************
+**
+**     Add an uniform to a gcSHADER object.
+**
+**     INPUT:
+**
+**             gcSHADER Shader
+**                     Pointer to a gcSHADER object.
+**
+**             gctCONST_STRING Name
+**                     Name of the uniform to add.
+**
+**             gcSHADER_TYPE Type
+**                     Type of the uniform to add.
+**
+**      gcSHADER_PRECISION precision
+**          Precision of the uniform to add.
+**
+**             gctSIZE_T Length
+**                     Array length of the uniform to add.  'Length' must be at least 1.
+**
+**     OUTPUT:
+**
+**             gcUNIFORM * Uniform
+**                     Pointer to a variable receiving the gcUNIFORM object pointer.
+*/
+gceSTATUS
+gcSHADER_AddUniformEx(
+       IN gcSHADER Shader,
+       IN gctCONST_STRING Name,
+       IN gcSHADER_TYPE Type,
+    IN gcSHADER_PRECISION precision,
+       IN gctSIZE_T Length,
+       OUT gcUNIFORM * Uniform
+       );
+
 /*******************************************************************************
 **                          gcSHADER_GetUniformCount
 ********************************************************************************
@@ -1117,6 +1220,37 @@ gcSHADER_GetOutput(
        OUT gcOUTPUT * Output
        );
 
+
+/*******************************************************************************
+**                                                        gcSHADER_GetOutputByName
+********************************************************************************
+**
+**     Get the gcOUTPUT object pointer for this shader by output name.
+**
+**     INPUT:
+**
+**             gcSHADER Shader
+**                     Pointer to a gcSHADER object.
+**
+**             gctSTRING name
+**                     Name of output to retrieve.
+**
+**      gctSIZE_T nameLength
+**          Length of name to retrieve
+**
+**     OUTPUT:
+**
+**             gcOUTPUT * Output
+**                     Pointer to a variable receiving the gcOUTPUT object pointer.
+*/
+gceSTATUS
+gcSHADER_GetOutputByName(
+       IN gcSHADER Shader,
+       IN gctSTRING name,
+    IN gctSIZE_T nameLength,
+       OUT gcOUTPUT * Output
+       );
+
 /*******************************************************************************
 **  gcSHADER_ReallocateVariables
 **
@@ -2159,6 +2293,41 @@ gcUNIFORM_GetType(
        OUT gctSIZE_T * ArrayLength
        );
 
+/*******************************************************************************
+**                              gcUNIFORM_GetTypeEx
+********************************************************************************
+**
+**     Get the type and array length of a gcUNIFORM object.
+**
+**     INPUT:
+**
+**             gcUNIFORM Uniform
+**                     Pointer to a gcUNIFORM object.
+**
+**     OUTPUT:
+**
+**             gcSHADER_TYPE * Type
+**                     Pointer to a variable receiving the type of the uniform.  'Type' can
+**                     be gcvNULL, in which case no type will be returned.
+**
+**             gcSHADER_PRECISION * Precision
+**                     Pointer to a variable receiving the precision of the uniform.  'Precision' can
+**                     be gcvNULL, in which case no type will be returned.
+**
+**             gctSIZE_T * ArrayLength
+**                     Pointer to a variable receiving the length of the array if the
+**                     uniform was declared as an array.  If the uniform was not declared
+**                     as an array, the array length will be 1.  'ArrayLength' can be gcvNULL,
+**                     in which case no array length will be returned.
+*/
+gceSTATUS
+gcUNIFORM_GetTypeEx(
+       IN gcUNIFORM Uniform,
+       OUT gcSHADER_TYPE * Type,
+    OUT gcSHADER_PRECISION * Precision,
+       OUT gctSIZE_T * ArrayLength
+       );
+
 /*******************************************************************************
 **                              gcUNIFORM_GetFlags
 ********************************************************************************
@@ -3034,6 +3203,7 @@ gcInvokeThreadWalker(
     IN gcsTHREAD_WALKER_INFO_PTR Info
     );
 
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
new file mode 100644 (file)
index 0000000..6b3a6e5
--- /dev/null
@@ -0,0 +1,257 @@
+/****************************************************************************
+*
+*    Copyright (C) 2005 - 2011 by Vivante Corp.
+*
+*    This program is free software; you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation; either version 2 of the license, or
+*    (at your option) any later version.
+*
+*    This program is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with this program; if not write to the Free Software
+*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+
+#ifndef __gc_hal_eglplatform_h_
+#define __gc_hal_eglplatform_h_
+
+/* Include VDK types. */
+#include <EGL/egl.h>
+#include "gc_hal_types.h"
+#include "gc_hal_base.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*******************************************************************************
+** Display. ********************************************************************
+*/
+
+EGLNativeDisplayType
+gcoOS_GetDisplay(
+       void
+    );
+
+EGLNativeDisplayType
+gcoOS_GetDisplayByIndex(
+    int DisplayIndex
+    );
+
+int
+gcoOS_GetDisplayInfo(
+    EGLNativeDisplayType Display,
+    int * Width,
+    int * Height,
+    unsigned long * Physical,
+    int * Stride,
+    int * BitsPerPixel
+    );
+
+/* VFK_DISPLAY_INFO structure defining information returned by
+   vdkGetDisplayInfoEx. */
+typedef struct _halDISPLAY_INFO
+{
+    /* The size of the display in pixels. */
+    int                         width;
+    int                         height;
+
+    /* The stride of the dispay. -1 is returned if the stride is not known
+    ** for the specified display.*/
+    int                         stride;
+
+    /* The color depth of the display in bits per pixel. */
+    int                         bitsPerPixel;
+
+    /* The logical pointer to the display memory buffer. NULL is returned
+    ** if the pointer is not known for the specified display. */
+    void *                      logical;
+
+    /* The physical address of the display memory buffer. ~0 is returned
+    ** if the address is not known for the specified display. */
+    unsigned long               physical;
+
+    /* The color info of the display. */
+    unsigned int                alphaLength;
+    unsigned int                alphaOffset;
+    unsigned int                redLength;
+    unsigned int                redOffset;
+    unsigned int                greenLength;
+    unsigned int                greenOffset;
+    unsigned int                blueLength;
+    unsigned int                blueOffset;
+
+    /* Display flip support. */
+    int                         flip;
+}
+halDISPLAY_INFO;
+
+int
+gcoOS_GetDisplayInfoEx(
+    EGLNativeDisplayType Display,
+#ifdef __QNXNTO__
+    EGLNativeWindowType Window,
+#endif
+    unsigned int DisplayInfoSize,
+    halDISPLAY_INFO * DisplayInfo
+    );
+
+int
+gcoOS_GetDisplayVirtual(
+    EGLNativeDisplayType Display,
+    int * Width,
+    int * Height
+    );
+
+int
+gcoOS_GetDisplayBackbuffer(
+    EGLNativeDisplayType Display,
+    NativeWindowType Window,
+    gctPOINTER    context,
+    gcoSURF       surface,
+    unsigned int * Offset,
+    int * X,
+    int * Y
+    );
+
+int
+gcoOS_SetDisplayVirtual(
+    EGLNativeDisplayType Display,
+#ifdef __QNXNTO__
+    EGLNativeWindowType Window,
+#endif
+    unsigned int Offset,
+    int X,
+    int Y
+    );
+
+void
+gcoOS_DestroyDisplay(
+    EGLNativeDisplayType Display
+    );
+
+/*******************************************************************************
+** Windows. ********************************************************************
+*/
+
+EGLNativeWindowType
+gcoOS_CreateWindow(
+    EGLNativeDisplayType Display,
+    int X,
+    int Y,
+    int Width,
+    int Height
+    );
+
+int
+gcoOS_GetWindowInfo(
+#if (defined(LINUX) || defined(__APPLE__)) && !defined(EGL_API_FB)
+    EGLNativeDisplayType Display,
+#endif
+    EGLNativeWindowType Window,
+    int * X,
+    int * Y,
+    int * Width,
+    int * Height,
+    int * BitsPerPixel,
+    unsigned int * Offset
+    );
+
+void
+gcoOS_DestroyWindow(
+#if (defined(LINUX) || defined(__APPLE__)) && !defined(EGL_API_FB)
+    EGLNativeDisplayType Display,
+#endif
+    EGLNativeWindowType Window
+    );
+
+int
+gcoOS_DrawImage(
+#if (defined(LINUX) || defined(__APPLE__)) && !defined(EGL_API_FB)
+    EGLNativeDisplayType Display,
+#endif
+    EGLNativeWindowType Window,
+    int Left,
+    int Top,
+    int Right,
+    int Bottom,
+    int Width,
+    int Height,
+    int BitsPerPixel,
+    void * Bits
+    );
+
+int
+gcoOS_GetImage(
+    EGLNativeWindowType Window,
+    int Left,
+    int Top,
+    int Right,
+    int Bottom,
+    int * BitsPerPixel,
+    void ** Bits
+    );
+
+/*******************************************************************************
+** Pixmaps. ********************************************************************
+*/
+
+EGLNativePixmapType
+gcoOS_CreatePixmap(
+    EGLNativeDisplayType Display,
+    int Width,
+    int Height,
+    int BitsPerPixel
+    );
+
+int
+gcoOS_GetPixmapInfo(
+#if (defined(LINUX) || defined(__APPLE__)) && !defined(EGL_API_FB)
+    EGLNativeDisplayType Display,
+#endif
+    EGLNativePixmapType Pixmap,
+    int * Width,
+    int * Height,
+    int * BitsPerPixel,
+    int * Stride,
+    void ** Bits
+    );
+
+int
+gcoOS_DrawPixmap(
+#if (defined(LINUX) || defined(__APPLE__)) && !defined(EGL_API_FB)
+    EGLNativeDisplayType Display,
+#endif
+    EGLNativePixmapType Pixmap,
+    int Left,
+    int Top,
+    int Right,
+    int Bottom,
+    int Width,
+    int Height,
+    int BitsPerPixel,
+    void * Bits
+    );
+
+void
+gcoOS_DestroyPixmap(
+#if (defined(LINUX) || defined(__APPLE__)) && !defined(EGL_API_FB)
+    EGLNativeDisplayType Display,
+#endif
+    EGLNativePixmapType Pixmap
+    );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_eglplatform_h_ */
index 165234a579fa03023517a2b267994562e9a91139..86852a2ffaf611f8a7291cbfb808860e9d47dcf0 100644 (file)
@@ -385,13 +385,6 @@ gcoSURF_SetResolvability(
     IN gctBOOL Resolvable
     );
 
-/* Perform CPU cache operation on surface */
-gceSTATUS
-gcoSURF_CPUCacheOperation(
-    IN gcoSURF Surface,
-    IN gceCACHEOPERATION Operation
-    );
-
 /******************************************************************************\
 ******************************** gcoINDEX Object *******************************
 \******************************************************************************/
index fc97c78d5d809908b8829c013fab9f2c720a2e71..adc020af954c534fba3b6760f1dc076b391ea9c4 100644 (file)
 #   define gcdENABLE_VG                         0
 #endif
 
+/*
+    gcdDYNAMIC_MAP_RESERVED_MEMORY
+
+        When gcvPOOL_SYSTEM is constructed from RESERVED memory,
+        driver can map the whole reserved memory to kernel space
+        at the beginning, or just map a piece of memory when need
+        to access.
+
+        Notice:
+        -  It's only for the 2D openVG. For other cores, there is
+           _NO_ need to map reserved memory to kernel.
+        -  It's meaningless when memory is allocated by
+           gckOS_AllocateContiguous, in that case, memory is always
+           mapped by system when allocated.
+*/
+#ifndef gcdDYNAMIC_MAP_RESERVED_MEMORY
+#   define gcdDYNAMIC_MAP_RESERVED_MEMORY      0
+#endif
+
 /*
    gcdPAGED_MEMORY_CACHEABLE
 
 #   define gcdENABLE_OUTER_CACHE_PATCH          0
 #endif
 
+/*
+    gcdMULTICORE_MAPPING
+
+        Make different cores own same VA
+*/
+#ifndef gcdMULTICORE_MAPPING
+#   define gcdMULTICORE_MAPPING                 1
+#endif
+
 #endif /* __gc_hal_options_h_ */
index 6213ffaaef8f71ff5ee88ef91f91e37e6fe00fb8..97719934bf357c05baac0cc099abbdd57af0705a 100644 (file)
@@ -28,9 +28,9 @@
 
 #define gcvVERSION_MINOR        6
 
-#define gcvVERSION_PATCH        3
+#define gcvVERSION_PATCH        4
 
-#define gcvVERSION_BUILD        1280
+#define gcvVERSION_BUILD        1311
 
 #define gcvVERSION_DATE      __DATE__
 
index b61964d963029a2859d04ec7e1d389717fc5749d..60c497d2ad8a6327e9cb48f19193d0b2a0333b89 100644 (file)
@@ -249,10 +249,22 @@ typedef gctTHREADFUNCRESULT (gctTHREADFUNCTYPE * gctTHREADFUNC) (
 )
 
 /* some platforms need to fix the physical address for HW to access*/
+#if (defined(__QNXNTO__) && defined(IMX6X))
+
+#define gcmFIXADDRESS(address) \
+(\
+    ((address) + 0x10000000)\
+)
+
+#else
+
 #define gcmFIXADDRESS(address) \
 (\
     (address)\
 )
+
+#endif
+
 /******************************************************************************\
 ****************************** Kernel Debug Macro ******************************
 \******************************************************************************/
@@ -377,6 +389,21 @@ gckKERNEL_QueryCommandBuffer(
     OUT gcsCOMMAND_BUFFER_INFO_PTR Information
     );
 
+#if gcdDYNAMIC_MAP_RESERVED_MEMORY
+gceSTATUS
+gckOS_MapReservedMemoryToKernel(
+    IN gckOS Os,
+    IN gctUINT32 Physical,
+    IN gctINT Bytes,
+    IN OUT gctPOINTER *Virtual
+    );
+
+gceSTATUS
+gckOS_UnmapReservedMemoryFromKernel(
+    IN gctPOINTER Virtual
+    );
+#endif
+
 /******************************************************************************\
 ******************************* gckVGHARDWARE Object ******************************
 \******************************************************************************/
@@ -643,6 +670,9 @@ typedef struct _gcsVGCONTEXT
     /* State map/mod buffer. */
     gctSIZE_T                   mapFirst;
     gctSIZE_T                   mapLast;
+#ifdef __QNXNTO__
+    gctSIZE_T                   mapContainerSize;
+#endif
     gcsVGCONTEXT_MAP_PTR            mapContainer;
     gcsVGCONTEXT_MAP_PTR            mapPrev;
     gcsVGCONTEXT_MAP_PTR            mapCurr;
@@ -700,6 +730,11 @@ typedef struct _gcsTASK_MASTER_TABLE
 
     /* The total size of event data in bytes. */
     gctUINT                     size;
+
+#if defined(__QNXNTO__)
+    gctINT32                    coid;
+    gctINT32                    rcvid;
+#endif
 }
 gcsTASK_MASTER_TABLE;
 
@@ -737,11 +772,24 @@ gckVGINTERRUPT_Disable(
     IN gctINT32 Id
     );
 
+#ifndef __QNXNTO__
+
 gceSTATUS
 gckVGINTERRUPT_Enque(
     IN gckVGINTERRUPT Interrupt
     );
 
+#else
+
+gceSTATUS
+gckVGINTERRUPT_Enque(
+    IN gckVGINTERRUPT Interrupt,
+    OUT gckOS *Os,
+    OUT gctSEMAPHORE *Semaphore
+    );
+
+#endif
+
 gceSTATUS
 gckVGINTERRUPT_DumpState(
     IN gckVGINTERRUPT Interrupt
index 02f2ff761b64b717efbd35009a8844b24e447bab..d619b79f1b821ccb6dcbcfcc66ddf8164bb51199 100644 (file)
@@ -367,7 +367,7 @@ gckGALDEVICE_Construct(
                    PhysBaseAddr, PhysSize, Signal);
 
     /* Allocate device structure. */
-    device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL);
+    device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN);
 
     if (!device)
     {
@@ -564,12 +564,20 @@ gckGALDEVICE_Construct(
         /* Start the command queue. */
         gcmkONERROR(gckCOMMAND_Start(device->kernels[gcvCORE_2D]->command));
 #endif
+
+#if gcdMULTICORE_MAPPING
+        device->kernels[gcvCORE_2D]->anotherKernel = device->kernels[gcvCORE_MAJOR];
+#endif
     }
     else
     {
         device->kernels[gcvCORE_2D] = gcvNULL;
     }
 
+#if gcdMULTICORE_MAPPING
+    device->kernels[gcvCORE_MAJOR]->anotherKernel = device->kernels[gcvCORE_2D];
+#endif
+
     if (IrqLineVG != -1)
     {
 #if gcdENABLE_VG
@@ -807,6 +815,7 @@ gckGALDEVICE_Construct(
                 device->requestedContiguousBase  = ContiguousBase;
                 device->requestedContiguousSize  = ContiguousSize;
 
+#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
                 if (gcmIS_CORE_PRESENT(device, gcvCORE_VG))
                 {
                     device->contiguousBase
@@ -823,6 +832,7 @@ gckGALDEVICE_Construct(
                         gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
                     }
                 }
+#endif
 
                 device->contiguousPhysical = (gctPHYS_ADDR) ContiguousBase;
                 device->contiguousSize     = ContiguousSize;
@@ -921,8 +931,13 @@ gckGALDEVICE_Destroy(
             {
                 if (Device->contiguousMapped)
                 {
-                    /* Unmap the contiguous memory. */
-                    iounmap(Device->contiguousBase);
+#if !gcdDYNAMIC_MAP_RESERVED_MEMORY && gcdENABLE_VG
+                    if (Device->contiguousBase)
+                    {
+                        /* Unmap the contiguous memory. */
+                        iounmap(Device->contiguousBase);
+                    }
+#endif
                 }
                 else
                 {
@@ -1524,7 +1539,7 @@ gckGALDEVICE_Start(
 
         /* Switch to SUSPEND power state. */
         gcmkONERROR(gckHARDWARE_SetPowerManagementState(
-            Device->kernels[gcvCORE_MAJOR]->hardware, gcvPOWER_SUSPEND_ATPOWERON
+            Device->kernels[gcvCORE_MAJOR]->hardware, gcvPOWER_OFF_BROADCAST
             ));
     }
 
@@ -1535,7 +1550,7 @@ gckGALDEVICE_Start(
 
         /* Switch to SUSPEND power state. */
         gcmkONERROR(gckHARDWARE_SetPowerManagementState(
-            Device->kernels[gcvCORE_2D]->hardware, gcvPOWER_SUSPEND_ATPOWERON
+            Device->kernels[gcvCORE_2D]->hardware, gcvPOWER_OFF_BROADCAST
             ));
     }
 
index 86ef0c67d8a7e7a9f91720ed73f06a7d9efb4b3e..b1c82e0ef311addf320d76e001009ad591e454af 100644 (file)
@@ -163,7 +163,7 @@ int drv_open(
         gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
     }
 
-    data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL);
+    data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL | __GFP_NOWARN);
 
     if (data == gcvNULL)
     {
index 619cd768530098269da44bcacf4561c65a328f5f..9a6376e43cedffdee61cc503bbbcd204abb2ba77 100644 (file)
@@ -67,17 +67,43 @@ const char * _PLATFORM = "\n\0$PLATFORM$Linux$\n";
     gcmkVERIFY_OK(gckOS_ReleaseMutex((os), (os)->memoryMapLock))
 
 /* Protection bit when mapping memroy to user sapce */
-#define gcmkPAGED_MEMROY_PROT(x) pgprot_noncached(x)
+#define gcmkPAGED_MEMROY_PROT(x)    pgprot_noncached(x)
+
+#if gcdNONPAGED_MEMORY_BUFFERABLE
+#define gcmkIOREMAP                 ioremap_wc
 #define gcmkNONPAGED_MEMROY_PROT(x) pgprot_writecombine(x)
+#elif !gcdNONPAGED_MEMORY_CACHEABLE
+#define gcmkIOREMAP                 ioremap_nocache
+#define gcmkNONPAGED_MEMROY_PROT(x) pgprot_noncached(x)
+#endif
 
 #define gcdINFINITE_TIMEOUT     (60 * 1000)
 #define gcdDETECT_TIMEOUT       0
 #define gcdDETECT_DMA_ADDRESS   1
 #define gcdDETECT_DMA_STATE     1
 
+#define gcdUSE_NON_PAGED_MEMORY_CACHE 10
+
 /******************************************************************************\
 ********************************** Structures **********************************
 \******************************************************************************/
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+typedef struct _gcsNonPagedMemoryCache
+{
+#ifndef NO_DMA_COHERENT
+    gctINT                           size;
+    gctSTRING                        addr;
+    dma_addr_t                       dmaHandle;
+#else
+    long                             order;
+    struct page *                    page;
+#endif
+
+    struct _gcsNonPagedMemoryCache * prev;
+    struct _gcsNonPagedMemoryCache * next;
+}
+gcsNonPagedMemoryCache;
+#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
 
 typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
 typedef struct _gcsUSER_MAPPING
@@ -145,6 +171,12 @@ struct _gckOS
 
     gcsUSER_MAPPING_PTR         userMap;
     gctPOINTER                  debugLock;
+
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+    gctUINT                      cacheSize;
+    gcsNonPagedMemoryCache *     cacheHead;
+    gcsNonPagedMemoryCache *     cacheTail;
+#endif
 };
 
 typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
@@ -507,7 +539,7 @@ _CreateMdl(
 
     gcmkHEADER_ARG("ProcessID=%d", ProcessID);
 
-    mdl = (PLINUX_MDL)kmalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL);
+    mdl = (PLINUX_MDL)kmalloc(sizeof(struct _LINUX_MDL), GFP_KERNEL | __GFP_NOWARN);
     if (mdl == gcvNULL)
     {
         gcmkFOOTER_NO();
@@ -568,7 +600,7 @@ _CreateMdlMap(
 
     gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
 
-    mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL);
+    mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL | __GFP_NOWARN);
     if (mdlMap == gcvNULL)
     {
         gcmkFOOTER_NO();
@@ -662,6 +694,328 @@ OnProcessExit(
 {
 }
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
+static inline int
+is_vmalloc_addr(
+    void *Addr
+    )
+{
+    unsigned long addr = (unsigned long)Addr;
+
+    return addr >= VMALLOC_START && addr < VMALLOC_END;
+}
+#endif
+
+static void
+_NonContiguousFree(
+    IN struct page ** Pages,
+    IN gctUINT32 NumPages
+    )
+{
+    gctINT i;
+
+    gcmkHEADER_ARG("Pages=0x%X, NumPages=%d", Pages, NumPages);
+
+    gcmkASSERT(Pages != gcvNULL);
+
+    for (i = 0; i < NumPages; i++)
+    {
+        __free_page(Pages[i]);
+    }
+
+    if (is_vmalloc_addr(Pages))
+    {
+        vfree(Pages);
+    }
+    else
+    {
+        kfree(Pages);
+    }
+
+    gcmkFOOTER_NO();
+}
+
+static struct page **
+_NonContiguousAlloc(
+    IN gctUINT32 NumPages
+    )
+{
+    struct page ** pages;
+    struct page *p;
+    gctINT i, size;
+
+    gcmkHEADER_ARG("NumPages=%lu", NumPages);
+
+    size = NumPages * sizeof(struct page *);
+
+    pages = kmalloc(size, GFP_KERNEL | __GFP_NOWARN);
+
+    if (!pages)
+    {
+        pages = vmalloc(size);
+
+        if (!pages)
+        {
+            gcmkFOOTER_NO();
+            return 0;
+        }
+    }
+
+    for (i = 0; i < NumPages; i++)
+    {
+        p = alloc_page(GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN);
+
+        if (!p)
+        {
+            _NonContiguousFree(pages, i);
+            gcmkFOOTER_NO();
+            return 0;
+        }
+
+        pages[i] = p;
+    }
+
+    gcmkFOOTER_ARG("pages=0x%X", pages);
+    return pages;
+}
+
+static inline struct page *
+_NonContiguousToPage(
+    IN struct page ** Pages,
+    IN gctUINT32 Index
+    )
+{
+    gcmkASSERT(Pages != gcvNULL);
+    return Pages[Index];
+}
+
+static inline unsigned long
+_NonContiguousToPfn(
+    IN struct page ** Pages,
+    IN gctUINT32 Index
+    )
+{
+    gcmkASSERT(Pages != gcvNULL);
+    return page_to_pfn(_NonContiguousToPage(Pages, Index));
+}
+
+static inline unsigned long
+_NonContiguousToPhys(
+    IN struct page ** Pages,
+    IN gctUINT32 Index
+    )
+{
+    gcmkASSERT(Pages != gcvNULL);
+    return page_to_phys(_NonContiguousToPage(Pages, Index));
+}
+
+
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+
+static gctBOOL
+_AddNonPagedMemoryCache(
+    gckOS Os,
+#ifndef NO_DMA_COHERENT
+    gctINT Size,
+    gctSTRING Addr,
+    dma_addr_t DmaHandle
+#else
+    long Order,
+    struct page * Page
+#endif
+    )
+{
+    gcsNonPagedMemoryCache *cache;
+
+    if (Os->cacheSize >= gcdUSE_NON_PAGED_MEMORY_CACHE)
+    {
+        return gcvFALSE;
+    }
+
+    /* Allocate the cache record */
+    cache = (gcsNonPagedMemoryCache *)kmalloc(sizeof(gcsNonPagedMemoryCache), GFP_ATOMIC);
+
+    if (cache == gcvNULL) return gcvFALSE;
+
+#ifndef NO_DMA_COHERENT
+    cache->size  = Size;
+    cache->addr  = Addr;
+    cache->dmaHandle = DmaHandle;
+#else
+    cache->order = Order;
+    cache->page  = Page;
+#endif
+
+    /* Add to list */
+    if (Os->cacheHead == gcvNULL)
+    {
+        cache->prev   = gcvNULL;
+        cache->next   = gcvNULL;
+        Os->cacheHead =
+        Os->cacheTail = cache;
+    }
+    else
+    {
+        /* Add to the tail. */
+        cache->prev         = Os->cacheTail;
+        cache->next         = gcvNULL;
+        Os->cacheTail->next = cache;
+        Os->cacheTail       = cache;
+    }
+
+    Os->cacheSize++;
+
+    return gcvTRUE;
+}
+
+#ifndef NO_DMA_COHERENT
+static gctSTRING
+_GetNonPagedMemoryCache(
+    gckOS Os,
+    gctINT Size,
+    dma_addr_t * DmaHandle
+    )
+#else
+static struct page *
+_GetNonPagedMemoryCache(
+    gckOS Os,
+    long Order
+    )
+#endif
+{
+    gcsNonPagedMemoryCache *cache;
+#ifndef NO_DMA_COHERENT
+    gctSTRING addr;
+#else
+    struct page * page;
+#endif
+
+    if (Os->cacheHead == gcvNULL) return gcvNULL;
+
+    /* Find the right cache */
+    cache = Os->cacheHead;
+
+    while (cache != gcvNULL)
+    {
+#ifndef NO_DMA_COHERENT
+        if (cache->size == Size) break;
+#else
+        if (cache->order == Order) break;
+#endif
+
+        cache = cache->next;
+    }
+
+    if (cache == gcvNULL) return gcvNULL;
+
+    /* Remove the cache from list */
+    if (cache == Os->cacheHead)
+    {
+        Os->cacheHead = cache->next;
+
+        if (Os->cacheHead == gcvNULL)
+        {
+            Os->cacheTail = gcvNULL;
+        }
+    }
+    else
+    {
+        cache->prev->next = cache->next;
+
+        if (cache == Os->cacheTail)
+        {
+            Os->cacheTail = cache->prev;
+        }
+        else
+        {
+            cache->next->prev = cache->prev;
+        }
+    }
+
+    /* Destroy cache */
+#ifndef NO_DMA_COHERENT
+    addr       = cache->addr;
+    *DmaHandle = cache->dmaHandle;
+#else
+    page       = cache->page;
+#endif
+
+    kfree(cache);
+
+    Os->cacheSize--;
+
+#ifndef NO_DMA_COHERENT
+    return addr;
+#else
+    return page;
+#endif
+}
+
+static void
+_FreeAllNonPagedMemoryCache(
+    gckOS Os
+    )
+{
+    gcsNonPagedMemoryCache *cache, *nextCache;
+
+    MEMORY_LOCK(Os);
+
+    cache = Os->cacheHead;
+
+    while (cache != gcvNULL)
+    {
+        if (cache != Os->cacheTail)
+        {
+            nextCache = cache->next;
+        }
+        else
+        {
+            nextCache = gcvNULL;
+        }
+
+        /* Remove the cache from list */
+        if (cache == Os->cacheHead)
+        {
+            Os->cacheHead = cache->next;
+
+            if (Os->cacheHead == gcvNULL)
+            {
+                Os->cacheTail = gcvNULL;
+            }
+        }
+        else
+        {
+            cache->prev->next = cache->next;
+
+            if (cache == Os->cacheTail)
+            {
+                Os->cacheTail = cache->prev;
+            }
+            else
+            {
+                cache->next->prev = cache->prev;
+            }
+        }
+
+#ifndef NO_DMA_COHERENT
+    dma_free_coherent(gcvNULL,
+                    cache->size,
+                    cache->addr,
+                    cache->dmaHandle);
+#else
+    free_pages((unsigned long)page_address(cache->page), cache->order);
+#endif
+
+        kfree(cache);
+
+        cache = nextCache;
+    }
+
+    MEMORY_UNLOCK(Os);
+}
+
+#endif /* gcdUSE_NON_PAGED_MEMORY_CACHE */
+
 /*******************************************************************************
 **
 **  gckOS_Construct
@@ -693,7 +1047,7 @@ gckOS_Construct(
     gcmkVERIFY_ARGUMENT(Os != gcvNULL);
 
     /* Allocate the gckOS object. */
-    os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL);
+    os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | __GFP_NOWARN);
 
     if (os == gcvNULL)
     {
@@ -741,7 +1095,7 @@ gckOS_Construct(
 
     /* Initialize the signal table. */
     os->signal.table =
-        kmalloc(gcmSIZEOF(gctPOINTER) * USER_SIGNAL_TABLE_LEN_INIT, GFP_KERNEL);
+        kmalloc(gcmSIZEOF(gctPOINTER) * USER_SIGNAL_TABLE_LEN_INIT, GFP_KERNEL | __GFP_NOWARN);
 
     if (os->signal.table == gcvNULL)
     {
@@ -761,6 +1115,12 @@ gckOS_Construct(
     /* Initial signal ID. */
     os->signal.currentID = 0;
 
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+    os->cacheSize = 0;
+    os->cacheHead = gcvNULL;
+    os->cacheTail = gcvNULL;
+#endif
+
     /* Return pointer to the gckOS object. */
     *Os = os;
 
@@ -839,6 +1199,10 @@ gckOS_Destroy(
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
 
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+    _FreeAllNonPagedMemoryCache(Os);
+#endif
+
     /*
      * Destroy the signal manager.
      */
@@ -880,6 +1244,59 @@ gckOS_Destroy(
     return gcvSTATUS_OK;
 }
 
+#ifdef NO_DMA_COHERENT
+static gctSTRING
+_CreateKernelVirtualMapping(
+    IN struct page * Page,
+    IN gctINT NumPages
+    )
+{
+    gctSTRING addr = 0;
+
+#if gcdNONPAGED_MEMORY_CACHEABLE
+    addr = page_address(Page);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+    struct page ** pages;
+    gctINT i;
+
+    pages = kmalloc(sizeof(struct page *) * NumPages, GFP_KERNEL | __GFP_NOWARN);
+
+    if (!pages)
+    {
+        return gcvNULL;
+    }
+
+    for (i = 0; i < NumPages; i++)
+    {
+        pages[i] = nth_page(Page, i);
+    }
+
+    /* ioremap() can't work on system memory since 2.6.38. */
+    addr = vmap(pages, NumPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
+
+    kfree(pages);
+#else
+    addr = gcmkIOREMAP(page_to_phys(Page), NumPages * PAGE_SIZE);
+#endif
+
+    return addr;
+}
+
+static void
+_DestoryKernelVirtualMapping(
+    IN gctSTRING Addr
+    )
+{
+#if !gcdNONPAGED_MEMORY_CACHEABLE
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)
+    vunmap(Addr);
+#   else
+    iounmap(Addr);
+#   endif
+#endif
+}
+#endif
+
 /*******************************************************************************
 **
 **  gckOS_Allocate
@@ -1021,7 +1438,14 @@ gckOS_AllocateMemory(
     gcmkVERIFY_ARGUMENT(Bytes > 0);
     gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
 
-    memory = (gctPOINTER) kmalloc(Bytes, GFP_KERNEL);
+    if (Bytes > PAGE_SIZE)
+    {
+        memory = (gctPOINTER) vmalloc(Bytes);
+    }
+    else
+    {
+        memory = (gctPOINTER) kmalloc(Bytes, GFP_KERNEL);
+    }
 
     if (memory == gcvNULL)
     {
@@ -1069,7 +1493,14 @@ gckOS_FreeMemory(
     gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
 
     /* Free the memory from the OS pool. */
-    kfree(Memory);
+    if (is_vmalloc_addr(Memory))
+    {
+        vfree(Memory);
+    }
+    else
+    {
+        kfree(Memory);
+    }
 
     /* Success. */
     gcmkFOOTER_NO();
@@ -1479,14 +1910,30 @@ gckOS_AllocateNonPagedMemory(
     locked = gcvTRUE;
 
 #ifndef NO_DMA_COHERENT
-    addr = dma_alloc_coherent(gcvNULL,
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+    addr = _GetNonPagedMemoryCache(Os,
+                mdl->numPages * PAGE_SIZE,
+                &mdl->dmaHandle);
+
+    if (addr == gcvNULL)
+#endif
+    {
+        addr = dma_alloc_coherent(gcvNULL,
                 mdl->numPages * PAGE_SIZE,
                 &mdl->dmaHandle,
-                GFP_KERNEL);
+                GFP_KERNEL | __GFP_NOWARN);
+    }
 #else
     size    = mdl->numPages * PAGE_SIZE;
     order   = get_order(size);
-    page    = alloc_pages(GFP_KERNEL, order);
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+    page = _GetNonPagedMemoryCache(Os, order);
+
+    if (page == gcvNULL)
+#endif
+    {
+        page = alloc_pages(GFP_KERNEL | __GFP_NOWARN, order);
+    }
 
     if (page == gcvNULL)
     {
@@ -1494,17 +1941,10 @@ gckOS_AllocateNonPagedMemory(
     }
 
     vaddr           = (gctPOINTER)page_address(page);
-
-#if gcdNONPAGED_MEMORY_CACHEABLE
-    addr            = vaddr;
-#   elif gcdNONPAGED_MEMORY_BUFFERABLE
-    addr            = ioremap_wc(virt_to_phys(vaddr), size);
-#   else
-    addr            = ioremap_nocache(virt_to_phys(vaddr), size);
-#   endif
-
+    addr            = _CreateKernelVirtualMapping(page, mdl->numPages);
     mdl->dmaHandle  = virt_to_phys(vaddr);
     mdl->kaddr      = vaddr;
+    mdl->u.contiguousPages = page;
 
     /* Cache invalidate. */
     dma_sync_single_for_device(
@@ -1749,10 +2189,18 @@ gceSTATUS gckOS_FreeNonPagedMemory(
     MEMORY_LOCK(Os);
 
 #ifndef NO_DMA_COHERENT
-    dma_free_coherent(gcvNULL,
-                    mdl->numPages * PAGE_SIZE,
-                    mdl->addr,
-                    mdl->dmaHandle);
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+    if (!_AddNonPagedMemoryCache(Os,
+                                 mdl->numPages * PAGE_SIZE,
+                                 mdl->addr,
+                                 mdl->dmaHandle))
+#endif
+    {
+        dma_free_coherent(gcvNULL,
+                mdl->numPages * PAGE_SIZE,
+                mdl->addr,
+                mdl->dmaHandle);
+    }
 #else
     size    = mdl->numPages * PAGE_SIZE;
     vaddr   = mdl->kaddr;
@@ -1765,12 +2213,16 @@ gceSTATUS gckOS_FreeNonPagedMemory(
         size    -= PAGE_SIZE;
     }
 
-    free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE));
-
-#if !gcdNONPAGED_MEMORY_CACHEABLE
-    iounmap(mdl->addr);
+#if gcdUSE_NON_PAGED_MEMORY_CACHE
+    if (!_AddNonPagedMemoryCache(Os,
+                                 get_order(mdl->numPages * PAGE_SIZE),
+                                 virt_to_page(mdl->kaddr)))
 #endif
+    {
+        free_pages((unsigned long)mdl->kaddr, get_order(mdl->numPages * PAGE_SIZE));
+    }
 
+    _DestoryKernelVirtualMapping(mdl->addr);
 #endif /* NO_DMA_COHERENT */
 
     mdlMap = mdl->maps;
@@ -2137,7 +2589,8 @@ _ConvertLogical2Physical(
         }
         else if (Mdl->pagedMem && !Mdl->contiguous)
         {
-            *Physical = page_to_phys(vmalloc_to_page(base + offset));
+            /* paged memory is not mapped to kernel space. */
+            return gcvSTATUS_INVALID_ADDRESS;
         }
         else
         {
@@ -2181,12 +2634,11 @@ _ConvertLogical2Physical(
             }
             else if (Mdl->pagedMem && !Mdl->contiguous)
             {
-                *Physical = page_to_phys(vmalloc_to_page(base + offset));
+                *Physical = _NonContiguousToPhys(Mdl->u.nonContiguousPages, offset/PAGE_SIZE);
             }
             else
             {
-                /* Return the kernel virtual pointer based on this. */
-                *Physical = gcmPTR2INT(virt_to_phys(base)) + offset;
+                *Physical = page_to_phys(Mdl->u.contiguousPages) + offset;
             }
 
             return gcvSTATUS_OK;
@@ -2500,7 +2952,7 @@ gckOS_CreateMutex(
     gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);
 
     /* Allocate a FAST_MUTEX structure. */
-    *Mutex = (gctPOINTER)kmalloc(sizeof(struct semaphore), GFP_KERNEL);
+    *Mutex = (gctPOINTER)kmalloc(sizeof(struct semaphore), GFP_KERNEL | __GFP_NOWARN);
 
     if (*Mutex == gcvNULL)
     {
@@ -3418,7 +3870,6 @@ gckOS_AllocatePagedMemoryEx(
     gctINT numPages;
     gctINT i;
     PLINUX_MDL mdl = gcvNULL;
-    gctSTRING addr;
     gctSIZE_T bytes;
     gctBOOL locked = gcvFALSE;
     gceSTATUS status;
@@ -3445,22 +3896,29 @@ gckOS_AllocatePagedMemoryEx(
 
     if (Contiguous)
     {
-        /* Get free pages, and suppress warning (stack dump) from kernel when
+        /* Get contiguous pages, and suppress warning (stack dump) from kernel when
            we run out of memory. */
-        addr = (char *)__get_free_pages(GFP_KERNEL | __GFP_NOWARN, GetOrder(numPages));
+        mdl->u.contiguousPages =
+            alloc_pages(GFP_KERNEL | __GFP_NOWARN, GetOrder(numPages));
+
+        if (mdl->u.contiguousPages == gcvNULL)
+        {
+            mdl->u.contiguousPages =
+                alloc_pages(GFP_KERNEL | __GFP_HIGHMEM | __GFP_NOWARN, GetOrder(numPages));
+        }
     }
     else
     {
-        addr = vmalloc(bytes);
+        mdl->u.nonContiguousPages = _NonContiguousAlloc(numPages);
     }
 
-    if (addr == gcvNULL)
+    if (mdl->u.contiguousPages == gcvNULL && mdl->u.nonContiguousPages == gcvNULL)
     {
         gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
     }
 
     mdl->dmaHandle  = 0;
-    mdl->addr       = addr;
+    mdl->addr       = 0;
     mdl->numPages   = numPages;
     mdl->pagedMem   = 1;
     mdl->contiguous = Contiguous;
@@ -3471,21 +3929,21 @@ gckOS_AllocatePagedMemoryEx(
 
         if (mdl->contiguous)
         {
-            page = virt_to_page(addr + i * PAGE_SIZE);
+            page = nth_page(mdl->u.contiguousPages, i);
         }
         else
         {
-            page = vmalloc_to_page(addr + i * PAGE_SIZE);
+            page = _NonContiguousToPage(mdl->u.nonContiguousPages, i);
         }
 
         SetPageReserved(page);
 
-        if (page_to_phys(page))
+        if (!PageHighMem(page) && page_to_phys(page))
         {
             gcmkVERIFY_OK(
                 gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
-                                (gctPOINTER)page_to_phys(page),
-                                 addr + i * PAGE_SIZE,
+                                 (gctPOINTER)page_to_phys(page),
+                                 page_address(page),
                                  PAGE_SIZE));
         }
     }
@@ -3582,21 +4040,21 @@ gckOS_FreePagedMemory(
     {
         if (mdl->contiguous)
         {
-            ClearPageReserved(virt_to_page((gctPOINTER)(((unsigned long)addr) + i * PAGE_SIZE)));
+            ClearPageReserved(nth_page(mdl->u.contiguousPages, i));
         }
         else
         {
-            ClearPageReserved(vmalloc_to_page((gctPOINTER)(((unsigned long)addr) + i * PAGE_SIZE)));
+            ClearPageReserved(_NonContiguousToPage(mdl->u.nonContiguousPages, i));
         }
     }
 
     if (mdl->contiguous)
     {
-        free_pages((unsigned long)mdl->addr, GetOrder(mdl->numPages));
+        __free_pages(mdl->u.contiguousPages, GetOrder(mdl->numPages));
     }
     else
     {
-        vfree(mdl->addr);
+        _NonContiguousFree(mdl->u.nonContiguousPages, mdl->numPages);
     }
 
     /* Remove the node from global list. */
@@ -3778,7 +4236,7 @@ gckOS_LockPages(
             /* map kernel memory to user space.. */
             if (remap_pfn_range(mdlMap->vma,
                                 mdlMap->vma->vm_start,
-                                virt_to_phys((gctPOINTER)mdl->addr) >> PAGE_SHIFT,
+                                page_to_pfn(mdl->u.contiguousPages),
                                 mdlMap->vma->vm_end - mdlMap->vma->vm_start,
                                 mdlMap->vma->vm_page_prot) < 0)
             {
@@ -3804,7 +4262,7 @@ gckOS_LockPages(
 
             for (i = 0; i < mdl->numPages; i++)
             {
-                pfn = vmalloc_to_pfn(addr);
+                pfn = _NonContiguousToPfn(mdl->u.nonContiguousPages, i);
 
                 if (remap_pfn_range(mdlMap->vma,
                                     start,
@@ -3915,8 +4373,8 @@ gckOS_MapPagesEx(
     gceSTATUS status = gcvSTATUS_OK;
     PLINUX_MDL  mdl;
     gctUINT32*  table;
-    gctSTRING   addr;
     gctUINT32   bytes;
+    gctUINT32   offset;
     gckMMU      mmu;
     PLINUX_MDL  mmuMdl;
     gctPHYS_ADDR pageTablePhysical;
@@ -3951,7 +4409,7 @@ gckOS_MapPagesEx(
 
      /* Get all the physical addresses and store them in the page table. */
 
-    addr = mdl->addr;
+    offset = 0;
 
     if (mdl->pagedMem)
     {
@@ -3965,15 +4423,15 @@ gckOS_MapPagesEx(
                 {
                     gcmkONERROR(
                         gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
-                                             virt_to_phys(addr),
-                                             table));
+                             page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
+                             table));
                 }
                 else
                 {
                     gcmkONERROR(
                         gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
-                                             page_to_phys(vmalloc_to_page(addr)),
-                                             table));
+                             _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
+                             table));
                 }
             }
             else
@@ -3983,20 +4441,20 @@ gckOS_MapPagesEx(
                 {
                     gcmkONERROR(
                         gckMMU_SetPage(Os->device->kernels[Core]->mmu,
-                                             virt_to_phys(addr),
-                                             table));
+                             page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
+                             table));
                 }
                 else
                 {
                     gcmkONERROR(
                         gckMMU_SetPage(Os->device->kernels[Core]->mmu,
-                                             page_to_phys(vmalloc_to_page(addr)),
-                                             table));
+                             _NonContiguousToPhys(mdl->u.nonContiguousPages, offset),
+                             table));
                 }
             }
 
             table++;
-            addr += 4096;
+            offset += 1;
         }
     }
     else
@@ -4014,7 +4472,7 @@ gckOS_MapPagesEx(
             {
                 gcmkONERROR(
                         gckVGMMU_SetPage(Os->device->kernels[Core]->vg->mmu,
-                                         (gctUINT32)virt_to_phys(addr),
+                                         page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
                                          table));
             }
             else
@@ -4022,11 +4480,11 @@ gckOS_MapPagesEx(
             {
                 gcmkONERROR(
                         gckMMU_SetPage(Os->device->kernels[Core]->mmu,
-                                         (gctUINT32)virt_to_phys(addr),
+                                         page_to_phys(nth_page(mdl->u.contiguousPages, offset)),
                                          table));
             }
             table++;
-            addr += 4096;
+            offset += 1;
         }
     }
 
@@ -4100,7 +4558,8 @@ gckOS_UnlockPages(
     gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
 
     /* Make sure there is already a mapping...*/
-    gcmkVERIFY_ARGUMENT(mdl->addr != gcvNULL);
+    gcmkVERIFY_ARGUMENT(mdl->u.nonContiguousPages != gcvNULL
+                       || mdl->u.contiguousPages != gcvNULL);
 
     MEMORY_LOCK(Os);
 
@@ -4413,7 +4872,7 @@ gckOS_MapUserPointer(
     gcmkVERIFY_ARGUMENT(Size > 0);
     gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
 
-    buf = kmalloc(Size, GFP_KERNEL);
+    buf = kmalloc(Size, GFP_KERNEL | __GFP_NOWARN);
     if (buf == gcvNULL)
     {
         gcmkTRACE(
@@ -4840,7 +5299,7 @@ OnError:
         MEMORY_MAP_LOCK(Os);
 
         /* Allocate the Info struct. */
-        info = (gcsPageInfo_PTR)kmalloc(sizeof(gcsPageInfo), GFP_KERNEL);
+        info = (gcsPageInfo_PTR)kmalloc(sizeof(gcsPageInfo), GFP_KERNEL | __GFP_NOWARN);
 
         if (info == gcvNULL)
         {
@@ -4849,7 +5308,7 @@ OnError:
         }
 
         /* Allocate the array of page addresses. */
-        pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL);
+        pages = (struct page **)kmalloc(pageCount * sizeof(struct page *), GFP_KERNEL | __GFP_NOWARN);
 
         if (pages == gcvNULL)
         {
@@ -4957,8 +5416,11 @@ OnError:
 
         for (i = 0; i < pageCount; i++)
         {
-            unsigned long paddr = page_to_phys(pages[i]);
-            outer_clean_range(paddr, paddr + PAGE_SIZE);
+            /* Flush(clean) the data cache. */
+            gcmkONERROR(gckOS_CacheFlush(Os, _GetProcessID(), gcvNULL,
+                             (gctPOINTER)page_to_phys(pages[i]),
+                             (gctPOINTER)(memory & PAGE_MASK) + i*PAGE_SIZE,
+                             PAGE_SIZE));
         }
 
 #if gcdENABLE_VG
@@ -5259,8 +5721,6 @@ OnError:
         /* Release the page cache. */
         for (i = 0; i < pageCount; i++)
         {
-            unsigned long paddr = page_to_phys(pages[i]);
-
             gcmkTRACE_ZONE(
                 gcvLEVEL_INFO, gcvZONE_OS,
                 "%s(%d): pages[%d]: 0x%X.",
@@ -5273,10 +5733,6 @@ OnError:
                 SetPageDirty(pages[i]);
             }
 
-            flush_dcache_page(pages[i]);
-
-            outer_inv_range(paddr, paddr + PAGE_SIZE);
-
             page_cache_release(pages[i]);
         }
 
@@ -5896,7 +6352,7 @@ gckOS_Broadcast(
     case gcvBROADCAST_AXI_BUS_ERROR:
         gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_AXI_BUS_ERROR\n");
         gcmkONERROR(_DumpGPUState(Os));
-        /*gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));*/
+        gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
         break;
     }
 
@@ -6024,7 +6480,7 @@ gckOS_CreateSemaphore(
     gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
 
     /* Allocate the semaphore structure. */
-    sem = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL);
+    sem = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | __GFP_NOWARN);
     if (sem == gcvNULL)
     {
         gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
@@ -6558,7 +7014,7 @@ gckOS_CreateSignal(
     gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
 
     /* Create an event structure. */
-    signal = (gcsSIGNAL_PTR) kmalloc(sizeof(gcsSIGNAL), GFP_KERNEL);
+    signal = (gcsSIGNAL_PTR) kmalloc(sizeof(gcsSIGNAL), GFP_KERNEL | __GFP_NOWARN);
 
     if (signal == gcvNULL)
     {
@@ -7184,7 +7640,7 @@ gckOS_CreateUserSignal(
         /* Enlarge the table. */
         table = (gctPOINTER *) kmalloc(
                     sizeof(gctPOINTER) * (Os->signal.tableLen + USER_SIGNAL_TABLE_LEN_INIT),
-                    GFP_KERNEL);
+                    GFP_KERNEL | __GFP_NOWARN);
 
         if (table == gcvNULL)
         {
@@ -7616,7 +8072,7 @@ gckOS_CreateSemaphoreVG(
     do
     {
         /* Allocate the semaphore structure. */
-       newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL);
+       newSemaphore = (struct semaphore *)kmalloc(gcmSIZEOF(struct semaphore), GFP_KERNEL | __GFP_NOWARN);
        if (newSemaphore == gcvNULL)
        {
                gcmkERR_BREAK(gcvSTATUS_OUT_OF_MEMORY);
@@ -7860,5 +8316,58 @@ gckOS_VerifyThread(
     /* Success. */
     return gcvSTATUS_OK;
 }
+
+#if gcdDYNAMIC_MAP_RESERVED_MEMORY
+gceSTATUS
+gckOS_MapReservedMemoryToKernel(
+    IN gckOS Os,
+    IN gctUINT32 Physical,
+    IN gctINT Bytes,
+    IN OUT gctPOINTER *Virtual
+    )
+{
+    gceSTATUS status;
+    gckGALDEVICE device;
+
+    gcmkHEADER_ARG("Os=0x%X Physical=0x%x Bytes=0x%d", Os, Physical, Bytes);
+
+    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+    gcmkVERIFY_ARGUMENT(Physical != 0);
+    gcmkVERIFY_ARGUMENT(Bytes != 0);
+    gcmkVERIFY_ARGUMENT(Virtual != gcvNULL);
+
+    device = (gckGALDEVICE) Os->device;
+
+    /* Reserved memory should not be mapped yet. */
+    gcmkASSERT(device->contiguousBase == gcvNULL);
+
+    *Virtual = ioremap_nocache(Physical, Bytes);
+
+    if(*Virtual == gcvNULL)
+    {
+        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+    }
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckOS_UnmapReservedMemoryFromKernel(
+    IN gctPOINTER Virtual
+    )
+{
+    gcmkHEADER_ARG("Virtual=0x%X", Virtual);
+
+    iounmap((void *)Virtual);
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+}
+#endif
 #endif
 
index f155f10cb7d573ae1b717ff39e0929cb162c4cff..ae94fcf4cef2ea70096773fb4b8f324065440193 100644 (file)
@@ -40,6 +40,15 @@ typedef struct _LINUX_MDL
     gctINT                  pid;
     char *                  addr;
 
+    union _pages
+    {
+        /* Pointer to a array of pages. */
+        struct page *       contiguousPages;
+        /* Pointer to a array of pointers to page. */
+        struct page **      nonContiguousPages;
+    }
+    u;
+
 #ifdef NO_DMA_COHERENT
     gctPOINTER              kaddr;
 #endif /* NO_DMA_COHERENT */