1 From 46e3a6de5adb9379f9d6eef2c038c2f18637d407 Mon Sep 17 00:00:00 2001
2 From: Loren Huang <b02279@freescale.com>
3 Date: Mon, 25 Mar 2013 15:43:57 +0800
4 Subject: [PATCH 1/6] ENGR00255688 4.6.9p11.1 [gpu]GPU Kernel driver
7 4.6.9p11.1 GPU kernel driver integration
8 Cherry pick from imx_3.0.35
10 Upstream-Status: Backport [3.5.7-1.0.0]
12 Signed-off-by: Loren Huang <b02279@freescale.com>
15 drivers/mxc/gpu-viv/Kbuild | 2 +-
16 .../arch/XAQ2/hal/kernel/gc_hal_kernel_context.c | 2 +-
17 .../arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c | 7 +-
18 drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h | 2 +-
19 drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c | 53 ++++--
20 .../mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c | 5 +-
21 drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c | 178 ++++++++++++---------
22 .../hal/kernel/gc_hal_kernel_video_memory.c | 3 +-
23 .../gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h | 13 +-
24 drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h | 25 +++
25 .../mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h | 35 ++++
26 .../mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h | 2 +-
27 .../hal/os/linux/kernel/gc_hal_kernel_driver.c | 2 +-
28 .../hal/os/linux/kernel/gc_hal_kernel_linux.h | 6 +
29 .../gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c | 82 +++++++++-
30 15 files changed, 304 insertions(+), 113 deletions(-)
32 diff --git a/drivers/mxc/gpu-viv/Kbuild b/drivers/mxc/gpu-viv/Kbuild
33 index 0b18a7b..93b1259 100644
34 --- a/drivers/mxc/gpu-viv/Kbuild
35 +++ b/drivers/mxc/gpu-viv/Kbuild
37 ##############################################################################
39 -# Copyright (C) 2005 - 2012 by Vivante Corp.
40 +# Copyright (C) 2005 - 2013 by Vivante Corp.
42 # This program is free software; you can redistribute it and/or modify
43 # it under the terms of the GNU General Public License as published by
44 diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
45 index 22e1f27..24003e7 100644
46 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
47 +++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
48 @@ -471,7 +471,7 @@ _InitializeContextBuffer(
49 index += _SwitchPipe(Context, index, gcvPIPE_3D);
51 /* Current context pointer. */
54 index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
57 diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
58 index a87259e..3829999 100644
59 --- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
60 +++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
61 @@ -232,7 +232,8 @@ _IdentifyHardware(
64 /* Exception for GC1000, revision 5035 & GC800, revision 4612 */
65 - if (((Identity->chipModel == gcv1000) && (Identity->chipRevision == 0x5035))
66 + if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035)
67 + || (Identity->chipRevision == 0x5036)))
68 || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612)))
70 Identity->superTileMode = 1;
71 @@ -751,7 +752,7 @@ gckHARDWARE_Construct(
72 /* Initialize the fast clear. */
73 gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
75 -#if !gcdENABLE_128B_MERGE
76 +#if !gcdENABLE_128B_MERGE
78 if (((((gctUINT32) (hardware->identity.chipMinorFeatures2)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))))
80 @@ -1027,7 +1028,7 @@ gckHARDWARE_InitializeHardware(
84 -#if !VIVANTE_PROFILER
85 +#if !VIVANTE_PROFILER
89 diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
90 index 1da80b7..5896e93 100644
91 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
92 +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
93 @@ -186,7 +186,7 @@ typedef struct _gcsDATABASE
96 /* Pointer to database. */
97 - gcsDATABASE_RECORD_PTR list;
98 + gcsDATABASE_RECORD_PTR list[48];
102 diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
103 index 1fb18fb..bc5f083 100644
104 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
105 +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
107 /*******************************************************************************
108 ***** Private fuctions ********************************************************/
110 +#define _GetSlot(database, x) \
111 + (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list)))
113 /*******************************************************************************
114 ** gckKERNEL_NewDatabase
116 @@ -56,6 +59,7 @@ gckKERNEL_NewDatabase(
117 gcsDATABASE_PTR database;
118 gctBOOL acquired = gcvFALSE;
120 + gcsDATABASE_PTR existingDatabase;
122 gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
124 @@ -63,6 +67,21 @@ gckKERNEL_NewDatabase(
125 gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
128 + /* Compute the hash for the database. */
129 + slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
131 + /* Walk the hash list. */
132 + for (existingDatabase = Kernel->db->db[slot];
133 + existingDatabase != gcvNULL;
134 + existingDatabase = existingDatabase->next)
136 + if (existingDatabase->processID == ProcessID)
138 + /* One process can't be added twice. */
139 + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
143 if (Kernel->db->freeDatabase != gcvNULL)
145 /* Allocate a database from the free list. */
146 @@ -81,9 +100,6 @@ gckKERNEL_NewDatabase(
150 - /* Compute the hash for the database. */
151 - slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
153 /* Insert the database into the hash. */
154 database->next = Kernel->db->db[slot];
155 Kernel->db->db[slot] = database;
156 @@ -350,6 +366,7 @@ static gceSTATUS
159 IN gcsDATABASE_PTR Database,
161 OUT gcsDATABASE_RECORD_PTR * Record
164 @@ -383,8 +400,8 @@ gckKERNEL_NewRecord(
167 /* Insert the record in the database. */
168 - record->next = Database->list;
169 - Database->list = record;
170 + record->next = Database->list[Slot];
171 + Database->list[Slot] = record;
173 /* Release the database mutex. */
174 gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
175 @@ -449,6 +466,7 @@ gckKERNEL_DeleteRecord(
177 gctBOOL acquired = gcvFALSE;
178 gcsDATABASE_RECORD_PTR record, previous;
179 + gctUINT32 slot = _GetSlot(Database, Data);
181 gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
182 Kernel, Database, Type, Data);
183 @@ -458,8 +476,9 @@ gckKERNEL_DeleteRecord(
184 gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
188 /* Scan the database for this record. */
189 - for (record = Database->list, previous = gcvNULL;
190 + for (record = Database->list[slot], previous = gcvNULL;
192 record = record->next
194 @@ -490,7 +509,7 @@ gckKERNEL_DeleteRecord(
195 /* Remove record from database. */
196 if (previous == gcvNULL)
198 - Database->list = record->next;
199 + Database->list[slot] = record->next;
203 @@ -557,6 +576,7 @@ gckKERNEL_FindRecord(
205 gctBOOL acquired = gcvFALSE;
206 gcsDATABASE_RECORD_PTR record;
207 + gctUINT32 slot = _GetSlot(Database, Data);
209 gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
210 Kernel, Database, Type, Data);
211 @@ -567,7 +587,7 @@ gckKERNEL_FindRecord(
214 /* Scan the database for this record. */
215 - for (record = Database->list;
216 + for (record = Database->list[slot];
218 record = record->next
220 @@ -642,6 +662,7 @@ gckKERNEL_CreateProcessDB(
223 gcsDATABASE_PTR database = gcvNULL;
226 gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
228 @@ -668,7 +689,11 @@ gckKERNEL_CreateProcessDB(
229 database->mapUserMemory.bytes = 0;
230 database->mapUserMemory.maxBytes = 0;
231 database->mapUserMemory.totalBytes = 0;
232 - database->list = gcvNULL;
234 + for (i = 0; i < gcmCOUNTOF(database->list); i++)
236 + database->list[i] = gcvNULL;
241 @@ -848,7 +873,7 @@ gckKERNEL_AddProcessDB(
242 gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
244 /* Create a new record in the database. */
245 - gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, &record));
246 + gcmkONERROR(gckKERNEL_NewRecord(Kernel, database, _GetSlot(database, Pointer), &record));
248 /* Initialize the record. */
249 record->kernel = Kernel;
250 @@ -1086,6 +1111,7 @@ gckKERNEL_DestroyProcessDB(
251 gctPHYS_ADDR physical;
252 gcuVIDMEM_NODE_PTR node;
253 gckKERNEL kernel = Kernel;
256 gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
258 @@ -1126,8 +1152,11 @@ gckKERNEL_DestroyProcessDB(
262 + for(i = 0; i < gcmCOUNTOF(database->list); i++)
265 /* Walk all records. */
266 - for (record = database->list; record != gcvNULL; record = next)
267 + for (record = database->list[i]; record != gcvNULL; record = next)
269 /* Next next record. */
271 @@ -1293,6 +1322,8 @@ gckKERNEL_DestroyProcessDB(
277 /* Delete the database. */
278 gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));
280 diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
281 index f78d096..217f7f1 100644
282 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
283 +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
284 @@ -959,6 +959,8 @@ gckEVENT_AddList(
285 record->kernel = Event->kernel;
288 + gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
290 /* Acquire the mutex. */
291 gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
293 @@ -1539,9 +1541,6 @@ gckEVENT_Submit(
294 gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
297 - gcmkONERROR(__RemoveRecordFromProcessDB(Event,
298 - Event->queues[id].head));
301 /* Notify immediately on infinite hardware. */
302 gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
303 diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
304 index 0c71e28..43c9297 100644
305 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
306 +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
307 @@ -97,6 +97,43 @@ static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL;
308 static gctPOINTER mirrorPageTableMutex = gcvNULL;
313 + IN gctUINT32_PTR PageEntry,
314 + IN gctUINT32 EntryValue
317 + static gctUINT16 data = 0xff00;
319 + if (*(gctUINT8 *)&data == 0xff)
321 + *PageEntry = gcmSWAB32(EntryValue);
325 + *PageEntry = EntryValue;
331 + IN gctUINT32_PTR PageEntry
334 + static gctUINT16 data = 0xff00;
335 + gctUINT32 entryValue;
337 + if (*(gctUINT8 *)&data == 0xff)
339 + entryValue = *PageEntry;
340 + return gcmSWAB32(entryValue);
350 IN gctUINT32_PTR PageTable,
351 @@ -108,7 +145,7 @@ _FillPageTable(
353 for (i = 0; i < PageCount; i++)
355 - PageTable[i] = EntryValue;
356 + _WritePageEntry(PageTable + i, EntryValue);
360 @@ -132,16 +169,16 @@ _Link(
361 gctUINT32_PTR pageTable = Mmu->pageTableLogical;
363 /* Dispatch on node type. */
364 - switch (gcmENTRY_TYPE(pageTable[Index]))
365 + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[Index])))
368 /* Set single index. */
369 - pageTable[Index] = (Next << 8) | gcvMMU_SINGLE;
370 + _WritePageEntry(&pageTable[Index], (Next << 8) | gcvMMU_SINGLE);
375 - pageTable[Index + 1] = Next;
376 + _WritePageEntry(&pageTable[Index + 1], Next);
380 @@ -167,13 +204,13 @@ _AddFree(
383 /* Initialize a single page node. */
384 - pageTable[Node] = (~((1U<<8)-1)) | gcvMMU_SINGLE;
385 + _WritePageEntry(pageTable + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
389 /* Initialize the node. */
390 - pageTable[Node + 0] = (Count << 8) | gcvMMU_FREE;
391 - pageTable[Node + 1] = ~0U;
392 + _WritePageEntry(pageTable + Node + 0, (Count << 8) | gcvMMU_FREE);
393 + _WritePageEntry(pageTable + Node + 1, ~0U);
396 /* Append the node. */
397 @@ -196,7 +233,7 @@ _Collect(
398 for (i = 0; i < Mmu->pageTableEntries; ++i)
400 /* Dispatch based on type of page. */
401 - switch (gcmENTRY_TYPE(pageTable[i]))
402 + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[i])))
405 /* Used page, so close any open node. */
406 @@ -229,10 +266,10 @@ _Collect(
409 /* Advance the count. */
410 - count += pageTable[i] >> 8;
411 + count += _ReadPageEntry(&pageTable[i]) >> 8;
413 /* Advance the index into the page table. */
414 - i += (pageTable[i] >> 8) - 1;
415 + i += (_ReadPageEntry(&pageTable[i]) >> 8) - 1;
419 @@ -341,19 +378,20 @@ _FillFlatMapping(
420 gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
423 - *(Mmu->mtlbLogical + mStart)
425 - /* 64KB page size */
427 - /* Ignore exception */
431 + _WritePageEntry(Mmu->mtlbLogical + mStart,
433 + /* 64KB page size */
435 + /* Ignore exception */
440 #if gcdMMU_TABLE_DUMP
441 gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
442 __FUNCTION__, __LINE__,
444 - *(Mmu->mtlbLogical + mStart));
445 + _ReadPageEntry(Mmu->mtlbLogical + mStart));
448 stlb->mtlbIndex = mStart;
449 @@ -368,12 +406,12 @@ _FillFlatMapping(
450 while (sStart <= last)
452 gcmkASSERT(!(start & gcdMMU_PAGE_64K_MASK));
453 - *(stlb->logical + sStart) = _SetPage(start);
454 + _WritePageEntry(stlb->logical + sStart, _SetPage(start));
455 #if gcdMMU_TABLE_DUMP
456 gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
457 __FUNCTION__, __LINE__,
459 - *(stlb->logical + sStart));
460 + _ReadPageEntry(stlb->logical + sStart));
463 start += gcdMMU_PAGE_64K_SIZE;
464 @@ -428,7 +466,7 @@ OnError:
465 if (pre->mtlbEntryNum != 0)
467 gcmkASSERT(pre->mtlbEntryNum == 1);
468 - *(Mmu->mtlbLogical + pre->mtlbIndex) = 0;
469 + _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
472 gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
473 @@ -493,8 +531,8 @@ _SetupDynamicSpace(
476 pageTable = Mmu->pageTableLogical;
477 - pageTable[0] = (Mmu->pageTableEntries << 8) | gcvMMU_FREE;
478 - pageTable[1] = ~0U;
479 + _WritePageEntry(pageTable, (Mmu->pageTableEntries << 8) | gcvMMU_FREE);
480 + _WritePageEntry(pageTable + 1, ~0U);
482 Mmu->freeNodes = gcvFALSE;
484 @@ -509,18 +547,20 @@ _SetupDynamicSpace(
485 /* Map to Master TLB. */
486 for (; i < gcdMMU_MTLB_ENTRY_NUM; i++)
488 - Mmu->mtlbLogical[i] = physical
489 - /* 4KB page size */
491 - /* Ignore exception */
495 + _WritePageEntry(Mmu->mtlbLogical + i,
497 + /* 4KB page size */
499 + /* Ignore exception */
504 #if gcdMMU_TABLE_DUMP
505 gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
506 __FUNCTION__, __LINE__,
508 - *(Mmu->mtlbLogical + i));
509 + _ReadPageEntry(Mmu->mtlbLogical + i));
511 physical += gcdMMU_STLB_4K_SIZE;
513 @@ -645,18 +685,11 @@ _Construct(
514 pageTable = mmu->pageTableLogical;
516 #if gcdMMU_CLEAR_VALUE
520 - for (i = 0; i < mmu->pageTableEntries; ++i)
522 - pageTable[i] = gcdMMU_CLEAR_VALUE;
525 + _FillPageTable(pageTable, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE);
528 - pageTable[0] = (mmu->pageTableEntries << 8) | gcvMMU_FREE;
529 - pageTable[1] = ~0U;
530 + _WritePageEntry(pageTable, (mmu->pageTableEntries << 8) | gcvMMU_FREE);
531 + _WritePageEntry(pageTable + 1, ~0U);
533 mmu->freeNodes = gcvFALSE;
535 @@ -797,7 +830,7 @@ _Destroy(
536 if (pre->mtlbEntryNum != 0)
538 gcmkASSERT(pre->mtlbEntryNum == 1);
539 - *(Mmu->mtlbLogical + pre->mtlbIndex) = 0;
540 + _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
541 #if gcdMMU_TABLE_DUMP
542 gckOS_Print("%s(%d): clean MTLB[%d]\n",
543 __FUNCTION__, __LINE__,
544 @@ -1044,7 +1077,7 @@ _AllocatePages(
545 for (index = Mmu->heapList; !gotIt && (index < Mmu->pageTableEntries);)
547 /* Check the node type. */
548 - switch (gcmENTRY_TYPE(pageTable[index]))
549 + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
552 /* Single odes are valid if we only need 1 page. */
553 @@ -1056,13 +1089,13 @@ _AllocatePages(
555 /* Move to next node. */
557 - index = pageTable[index] >> 8;
558 + index = _ReadPageEntry(&pageTable[index]) >> 8;
563 /* Test if the node has enough space. */
564 - if (PageCount <= (pageTable[index] >> 8))
565 + if (PageCount <= (_ReadPageEntry(&pageTable[index]) >> 8))
569 @@ -1070,7 +1103,7 @@ _AllocatePages(
571 /* Move to next node. */
573 - index = pageTable[index + 1];
574 + index = _ReadPageEntry(&pageTable[index + 1]);
578 @@ -1099,36 +1132,36 @@ _AllocatePages(
582 - switch (gcmENTRY_TYPE(pageTable[index]))
583 + switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
586 /* Unlink single node from free list. */
588 - _Link(Mmu, previous, pageTable[index] >> 8));
589 + _Link(Mmu, previous, _ReadPageEntry(&pageTable[index]) >> 8));
593 /* Check how many pages will be left. */
594 - left = (pageTable[index] >> 8) - PageCount;
595 + left = (_ReadPageEntry(&pageTable[index]) >> 8) - PageCount;
599 /* The entire node is consumed, just unlink it. */
601 - _Link(Mmu, previous, pageTable[index + 1]));
602 + _Link(Mmu, previous, _ReadPageEntry(&pageTable[index + 1])));
606 /* One page will remain. Convert the node to a single node and
607 ** advance the index. */
608 - pageTable[index] = (pageTable[index + 1] << 8) | gcvMMU_SINGLE;
609 + _WritePageEntry(&pageTable[index], (_ReadPageEntry(&pageTable[index + 1]) << 8) | gcvMMU_SINGLE);
614 /* Enough pages remain for a new node. However, we will just adjust
615 ** the size of the current node and advance the index. */
616 - pageTable[index] = (left << 8) | gcvMMU_FREE;
617 + _WritePageEntry(&pageTable[index], (left << 8) | gcvMMU_FREE);
621 @@ -1232,35 +1265,32 @@ _FreePages(
622 #if gcdMMU_CLEAR_VALUE
623 if (Mmu->hardware->mmuVersion == 0)
627 - for (i = 0; i < PageCount; ++i)
629 - pageTable[i] = gcdMMU_CLEAR_VALUE;
631 + _FillPageTable(pageTable, PageCount, gcdMMU_CLEAR_VALUE);
637 /* Single page node. */
638 - pageTable[0] = (~((1U<<8)-1)) | gcvMMU_SINGLE
639 + _WritePageEntry(pageTable,
640 + (~((1U<<8)-1)) | gcvMMU_SINGLE
641 #if gcdUSE_MMU_EXCEPTION
642 - /* Enable exception */
644 + /* Enable exception */
652 /* Mark the node as free. */
653 - pageTable[0] = (PageCount << 8) | gcvMMU_FREE
654 + _WritePageEntry(pageTable,
655 + (PageCount << 8) | gcvMMU_FREE
656 #if gcdUSE_MMU_EXCEPTION
657 - /* Enable exception */
659 + /* Enable exception */
663 - pageTable[1] = ~0U;
665 + _WritePageEntry(pageTable + 1, ~0U);
667 #if gcdUSE_MMU_EXCEPTION
668 /* Enable exception */
669 @@ -1509,12 +1539,8 @@ gckMMU_SetPage(
670 data = _SetPage(PageAddress);
673 - if (Mmu->hardware->bigEndian)
675 - data = gcmSWAB32(data);
677 + _WritePageEntry(PageEntry, data);
680 #if gcdMIRROR_PAGETABLE
681 for (i = 0; i < mirrorPageTable->reference; i++)
683 @@ -1526,11 +1552,11 @@ gckMMU_SetPage(
685 if (mmu->hardware->mmuVersion == 0)
687 - *pageEntry = PageAddress;
688 + _WritePageEntry(pageEntry, PageAddress);
692 - *pageEntry = _SetPage(PageAddress);
693 + _WritePageEntry(pageEntry, _SetPage(PageAddress));
697 @@ -1734,7 +1760,7 @@ gckMMU_DumpPageTableEntry(
698 * gcdMMU_STLB_4K_ENTRY_NUM
701 - gcmkPRINT(" Page table entry = 0x%08X", pageTable[index]);
702 + gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
706 diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
707 index d49aa64..8a442a2 100644
708 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
709 +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
710 @@ -1027,7 +1027,8 @@ gckVIDMEM_AllocateLinear(
713 /* The left memory is for small memory.*/
714 - gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
715 + status = gcvSTATUS_OUT_OF_MEMORY;
720 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
721 index 496276e..06eea79 100644
722 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
723 +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
724 @@ -227,7 +227,8 @@ gcoOS_GetDisplayInfoEx(
728 -gcoOS_GetNextDisplayInfoEx(
729 +gcoOS_GetNextDisplayInfoExByIndex(
731 IN HALNativeDisplayType Display,
732 IN HALNativeWindowType Window,
733 IN gctUINT DisplayInfoSize,
734 @@ -274,15 +275,15 @@ gcoOS_SetDisplayVirtualEx(
737 gcoOS_SetSwapInterval(
738 - IN HALNativeDisplayType Display,
740 + IN HALNativeDisplayType Display,
745 gcoOS_GetSwapInterval(
746 - IN HALNativeDisplayType Display,
749 + IN HALNativeDisplayType Display,
755 diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
756 index d441d1d..249b61b 100644
757 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
758 +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
759 @@ -1430,6 +1430,16 @@ typedef enum _gceTEXTURE_FACE
766 + gcvForceMipDisabled = 0,
767 + gcvForceMipEnable = 1,
768 + gcvForceMipGenerated = 2,
769 + gcvForceMipNever = 3,
773 typedef struct _gcsTEXTURE
775 /* Addressing modes. */
776 @@ -1446,6 +1456,10 @@ typedef struct _gcsTEXTURE
777 gceTEXTURE_FILTER mipFilter;
779 gctBOOL forceTopLevel;
780 + gctBOOL autoMipmap;
782 + gceFORCE_MIPMAP forceMipmap;
784 /* Level of detail. */
785 gctFIXED_POINT lodBias;
786 gctFIXED_POINT lodMin;
787 @@ -1479,7 +1493,18 @@ gceSTATUS
789 IN gcoTEXTURE Texture
793 +gcoTEXTURE_DestroyForceMipmap(
794 + IN gcoTEXTURE Texture
798 +gcoTEXTURE_GetMipLevels(
799 + IN gcoTEXTURE Texture,
800 + OUT gctINT * levels
803 /* Replace a mipmap in gcoTEXTURE object. */
805 gcoTEXTURE_ReplaceMipMap(
806 diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
807 index 86e9133..afe83d0 100644
808 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
809 +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
811 #define COMMAND_PROCESSOR_VERSION 1
816 + Set this to a string that appears in 'cat /proc/<pid>/cmdline'. E.g. 'camera'.
817 + HAL will create dumps for the processes matching this key.
820 +# define gcdDUMP_KEY "process"
826 + The dump file location. Some processes cannot write to the sdcard.
827 + Try apps' data dir, e.g. /data/data/com.android.launcher
829 +#ifndef gcdDUMP_PATH
830 +#if defined(ANDROID)
831 +# define gcdDUMP_PATH "/mnt/sdcard/"
833 +# define gcdDUMP_PATH "./"
840 When set to 1, a dump of all states and memory uploads, as well as other
845 + gcdUSER_HEAP_ALLOCATOR
847 + Set to 1 to enable user mode heap allocator for fast memory allocation
848 + and destroying. Otherwise, memory allocation/destroying in user mode
849 + will be directly managed by system. Only for linux for now.
851 +#ifndef gcdUSER_HEAP_ALLOCATOR
852 +# define gcdUSER_HEAP_ALLOCATOR 1
858 Set the allocation size for the internal heaps. Each time a heap is
859 diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
860 index 2881604..808fde0 100644
861 --- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
862 +++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
865 #define gcvVERSION_PATCH 9
867 -#define gcvVERSION_BUILD 1210
868 +#define gcvVERSION_BUILD 4651
870 #define gcvVERSION_DATE __DATE__
872 diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
873 index 4e3819c..2ed3d0e 100644
874 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
875 +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
876 @@ -663,7 +663,7 @@ static int drv_mmap(
878 #if !gcdPAGED_MEMORY_CACHEABLE
879 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
880 - vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND;
881 + vma->vm_flags |= gcdVM_FLAGS;
885 diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
886 index 9c0bcd5..3c148f6 100644
887 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
888 +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
891 #define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
893 +#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0)
894 +#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP)
896 +#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
902 diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
903 index c07ded8..9c2bae6 100644
904 --- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
905 +++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
906 @@ -869,6 +869,60 @@ _UnmapUserLogical(
911 +_QueryProcessPageTable(
912 + IN gctPOINTER Logical,
913 + OUT gctUINT32 * Address
917 + gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
925 + return gcvSTATUS_NOT_FOUND;
928 + pgd = pgd_offset(current->mm, logical);
929 + if (pgd_none(*pgd) || pgd_bad(*pgd))
931 + return gcvSTATUS_NOT_FOUND;
934 + pud = pud_offset(pgd, logical);
935 + if (pud_none(*pud) || pud_bad(*pud))
937 + return gcvSTATUS_NOT_FOUND;
940 + pmd = pmd_offset(pud, logical);
941 + if (pmd_none(*pmd) || pmd_bad(*pmd))
943 + return gcvSTATUS_NOT_FOUND;
946 + pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
949 + return gcvSTATUS_NOT_FOUND;
952 + if (!pte_present(*pte))
954 + pte_unmap_unlock(pte, lock);
955 + return gcvSTATUS_NOT_FOUND;
958 + *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
959 + pte_unmap_unlock(pte, lock);
961 + return gcvSTATUS_OK;
964 /*******************************************************************************
967 @@ -1106,6 +1160,9 @@ _CreateKernelVirtualMapping(
972 + /* Trigger a page fault. */
973 + memset(addr, 0, numPages * PAGE_SIZE);
976 struct page ** pages;
977 @@ -1136,6 +1193,9 @@ _CreateKernelVirtualMapping(
978 /* ioremap() can't work on system memory since 2.6.38. */
979 addr = vmap(pages, numPages, 0, gcmkNONPAGED_MEMROY_PROT(PAGE_KERNEL));
981 + /* Trigger a page fault. */
982 + memset(addr, 0, numPages * PAGE_SIZE);
987 @@ -1540,7 +1600,7 @@ gckOS_MapMemory(
989 #if !gcdPAGED_MEMORY_CACHEABLE
990 mdlMap->vma->vm_page_prot = gcmkPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
991 - mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED;
992 + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
994 mdlMap->vma->vm_pgoff = 0;
996 @@ -1987,7 +2047,7 @@ gckOS_AllocateNonPagedMemory(
999 mdlMap->vma->vm_page_prot = gcmkNONPAGED_MEMROY_PROT(mdlMap->vma->vm_page_prot);
1000 - mdlMap->vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED;
1001 + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
1002 mdlMap->vma->vm_pgoff = 0;
1004 if (remap_pfn_range(mdlMap->vma,
1005 @@ -2367,12 +2427,18 @@ gckOS_GetPhysicalAddress(
1006 gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
1007 gcmkVERIFY_ARGUMENT(Address != gcvNULL);
1009 - /* Get current process ID. */
1010 - processID = _GetProcessID();
1011 + /* Query page table of current process first. */
1012 + status = _QueryProcessPageTable(Logical, Address);
1014 - /* Route through other function. */
1016 - gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
1017 + if (gcmIS_ERROR(status))
1019 + /* Get current process ID. */
1020 + processID = _GetProcessID();
1022 + /* Route through other function. */
1024 + gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
1028 gcmkFOOTER_ARG("*Address=0x%08x", *Address);
1029 @@ -4139,7 +4205,7 @@ gckOS_LockPages(
1030 return gcvSTATUS_OUT_OF_RESOURCES;
1033 - mdlMap->vma->vm_flags |= VM_RESERVED;
1034 + mdlMap->vma->vm_flags |= gcdVM_FLAGS;
1035 #if !gcdPAGED_MEMORY_CACHEABLE
1036 if (Cacheable == gcvFALSE)