summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-wandboard-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-wandboard-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch')
-rw-r--r--recipes-kernel/linux/linux-wandboard-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch1040
1 files changed, 1040 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-wandboard-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch b/recipes-kernel/linux/linux-wandboard-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
new file mode 100644
index 0000000..9c7cd44
--- /dev/null
+++ b/recipes-kernel/linux/linux-wandboard-3.0.35/0001-ENGR00255688-4.6.9p11.1-gpu-GPU-Kernel-driver-integr.patch
@@ -0,0 +1,1040 @@
1From 46e3a6de5adb9379f9d6eef2c038c2f18637d407 Mon Sep 17 00:00:00 2001
2From: Loren Huang <b02279@freescale.com>
3Date: Mon, 25 Mar 2013 15:43:57 +0800
4Subject: [PATCH 1/6] ENGR00255688 4.6.9p11.1 [gpu]GPU Kernel driver
5 integration
6
74.6.9p11.1 GPU kernel driver integration
8Cherry pick from imx_3.0.35
9
10Upstream-Status: Backport [3.5.7-1.0.0]
11
12Signed-off-by: Loren Huang <b02279@freescale.com>
13Acked-by: Lily Zhang
14---
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(-)
31
32diff --git a/drivers/mxc/gpu-viv/Kbuild b/drivers/mxc/gpu-viv/Kbuild
33index 0b18a7b..93b1259 100644
34--- a/drivers/mxc/gpu-viv/Kbuild
35+++ b/drivers/mxc/gpu-viv/Kbuild
36@@ -1,6 +1,6 @@
37 ##############################################################################
38 #
39-# Copyright (C) 2005 - 2012 by Vivante Corp.
40+# Copyright (C) 2005 - 2013 by Vivante Corp.
41 #
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
44diff --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
45index 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);
50
51 /* Current context pointer. */
52-#if gcdDEBUG
53+#if gcdDEBUG
54 index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
55 #endif
56
57diff --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
58index 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(
62 }
63
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)))
69 {
70 Identity->superTileMode = 1;
71@@ -751,7 +752,7 @@ gckHARDWARE_Construct(
72 /* Initialize the fast clear. */
73 gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
74
75-#if !gcdENABLE_128B_MERGE
76+#if !gcdENABLE_128B_MERGE
77
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))))))))
79 {
80@@ -1027,7 +1028,7 @@ gckHARDWARE_InitializeHardware(
81 0x00424,
82 baseAddress));
83
84-#if !VIVANTE_PROFILER
85+#if !VIVANTE_PROFILER
86 {
87 gctUINT32 data;
88
89diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
90index 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
94 gctUINT64 idle;
95
96 /* Pointer to database. */
97- gcsDATABASE_RECORD_PTR list;
98+ gcsDATABASE_RECORD_PTR list[48];
99
100 #if gcdSECURE_USER
101 /* Secure cache. */
102diff --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
103index 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
106@@ -26,6 +26,9 @@
107 /*******************************************************************************
108 ***** Private fuctions ********************************************************/
109
110+#define _GetSlot(database, x) \
111+ (gctUINT32)(((gcmPTR_TO_UINT64(x) >> 7) % gcmCOUNTOF(database->list)))
112+
113 /*******************************************************************************
114 ** gckKERNEL_NewDatabase
115 **
116@@ -56,6 +59,7 @@ gckKERNEL_NewDatabase(
117 gcsDATABASE_PTR database;
118 gctBOOL acquired = gcvFALSE;
119 gctSIZE_T slot;
120+ gcsDATABASE_PTR existingDatabase;
121
122 gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
123
124@@ -63,6 +67,21 @@ gckKERNEL_NewDatabase(
125 gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
126 acquired = gcvTRUE;
127
128+ /* Compute the hash for the database. */
129+ slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
130+
131+ /* Walk the hash list. */
132+ for (existingDatabase = Kernel->db->db[slot];
133+ existingDatabase != gcvNULL;
134+ existingDatabase = existingDatabase->next)
135+ {
136+ if (existingDatabase->processID == ProcessID)
137+ {
138+ /* One process can't be added twice. */
139+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
140+ }
141+ }
142+
143 if (Kernel->db->freeDatabase != gcvNULL)
144 {
145 /* Allocate a database from the free list. */
146@@ -81,9 +100,6 @@ gckKERNEL_NewDatabase(
147 database = pointer;
148 }
149
150- /* Compute the hash for the database. */
151- slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
152-
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
157 gckKERNEL_NewRecord(
158 IN gckKERNEL Kernel,
159 IN gcsDATABASE_PTR Database,
160+ IN gctUINT32 Slot,
161 OUT gcsDATABASE_RECORD_PTR * Record
162 )
163 {
164@@ -383,8 +400,8 @@ gckKERNEL_NewRecord(
165 }
166
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;
172
173 /* Release the database mutex. */
174 gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
175@@ -449,6 +466,7 @@ gckKERNEL_DeleteRecord(
176 gceSTATUS status;
177 gctBOOL acquired = gcvFALSE;
178 gcsDATABASE_RECORD_PTR record, previous;
179+ gctUINT32 slot = _GetSlot(Database, Data);
180
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));
185 acquired = gcvTRUE;
186
187+
188 /* Scan the database for this record. */
189- for (record = Database->list, previous = gcvNULL;
190+ for (record = Database->list[slot], previous = gcvNULL;
191 record != gcvNULL;
192 record = record->next
193 )
194@@ -490,7 +509,7 @@ gckKERNEL_DeleteRecord(
195 /* Remove record from database. */
196 if (previous == gcvNULL)
197 {
198- Database->list = record->next;
199+ Database->list[slot] = record->next;
200 }
201 else
202 {
203@@ -557,6 +576,7 @@ gckKERNEL_FindRecord(
204 gceSTATUS status;
205 gctBOOL acquired = gcvFALSE;
206 gcsDATABASE_RECORD_PTR record;
207+ gctUINT32 slot = _GetSlot(Database, Data);
208
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(
212 acquired = gcvTRUE;
213
214 /* Scan the database for this record. */
215- for (record = Database->list;
216+ for (record = Database->list[slot];
217 record != gcvNULL;
218 record = record->next
219 )
220@@ -642,6 +662,7 @@ gckKERNEL_CreateProcessDB(
221 {
222 gceSTATUS status;
223 gcsDATABASE_PTR database = gcvNULL;
224+ gctUINT32 i;
225
226 gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
227
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;
233+
234+ for (i = 0; i < gcmCOUNTOF(database->list); i++)
235+ {
236+ database->list[i] = gcvNULL;
237+ }
238
239 #if gcdSECURE_USER
240 {
241@@ -848,7 +873,7 @@ gckKERNEL_AddProcessDB(
242 gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
243
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));
247
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;
254+ gctUINT32 i;
255
256 gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
257
258@@ -1126,8 +1152,11 @@ gckKERNEL_DestroyProcessDB(
259 ProcessID);
260 }
261
262+ for(i = 0; i < gcmCOUNTOF(database->list); i++)
263+ {
264+
265 /* Walk all records. */
266- for (record = database->list; record != gcvNULL; record = next)
267+ for (record = database->list[i]; record != gcvNULL; record = next)
268 {
269 /* Next next record. */
270 next = record->next;
271@@ -1293,6 +1322,8 @@ gckKERNEL_DestroyProcessDB(
272 gcvNULL));
273 }
274
275+ }
276+
277 /* Delete the database. */
278 gcmkONERROR(gckKERNEL_DeleteDatabase(Kernel, database));
279
280diff --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
281index 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;
286 #endif
287
288+ gcmkONERROR(__RemoveRecordFromProcessDB(Event, record));
289+
290 /* Acquire the mutex. */
291 gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
292 acquired = gcvTRUE;
293@@ -1539,9 +1541,6 @@ gckEVENT_Submit(
294 gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
295 acquired = gcvFALSE;
296
297- gcmkONERROR(__RemoveRecordFromProcessDB(Event,
298- Event->queues[id].head));
299-
300 #if gcdNULL_DRIVER
301 /* Notify immediately on infinite hardware. */
302 gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
303diff --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
304index 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;
309 #endif
310
311+static void
312+_WritePageEntry(
313+ IN gctUINT32_PTR PageEntry,
314+ IN gctUINT32 EntryValue
315+ )
316+{
317+ static gctUINT16 data = 0xff00;
318+
319+ if (*(gctUINT8 *)&data == 0xff)
320+ {
321+ *PageEntry = gcmSWAB32(EntryValue);
322+ }
323+ else
324+ {
325+ *PageEntry = EntryValue;
326+ }
327+}
328+
329+static gctUINT32
330+_ReadPageEntry(
331+ IN gctUINT32_PTR PageEntry
332+ )
333+{
334+ static gctUINT16 data = 0xff00;
335+ gctUINT32 entryValue;
336+
337+ if (*(gctUINT8 *)&data == 0xff)
338+ {
339+ entryValue = *PageEntry;
340+ return gcmSWAB32(entryValue);
341+ }
342+ else
343+ {
344+ return *PageEntry;
345+ }
346+}
347+
348 static gceSTATUS
349 _FillPageTable(
350 IN gctUINT32_PTR PageTable,
351@@ -108,7 +145,7 @@ _FillPageTable(
352
353 for (i = 0; i < PageCount; i++)
354 {
355- PageTable[i] = EntryValue;
356+ _WritePageEntry(PageTable + i, EntryValue);
357 }
358
359 return gcvSTATUS_OK;
360@@ -132,16 +169,16 @@ _Link(
361 gctUINT32_PTR pageTable = Mmu->pageTableLogical;
362
363 /* Dispatch on node type. */
364- switch (gcmENTRY_TYPE(pageTable[Index]))
365+ switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[Index])))
366 {
367 case gcvMMU_SINGLE:
368 /* Set single index. */
369- pageTable[Index] = (Next << 8) | gcvMMU_SINGLE;
370+ _WritePageEntry(&pageTable[Index], (Next << 8) | gcvMMU_SINGLE);
371 break;
372
373 case gcvMMU_FREE:
374 /* Set index. */
375- pageTable[Index + 1] = Next;
376+ _WritePageEntry(&pageTable[Index + 1], Next);
377 break;
378
379 default:
380@@ -167,13 +204,13 @@ _AddFree(
381 if (Count == 1)
382 {
383 /* Initialize a single page node. */
384- pageTable[Node] = (~((1U<<8)-1)) | gcvMMU_SINGLE;
385+ _WritePageEntry(pageTable + Node, (~((1U<<8)-1)) | gcvMMU_SINGLE);
386 }
387 else
388 {
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);
394 }
395
396 /* Append the node. */
397@@ -196,7 +233,7 @@ _Collect(
398 for (i = 0; i < Mmu->pageTableEntries; ++i)
399 {
400 /* Dispatch based on type of page. */
401- switch (gcmENTRY_TYPE(pageTable[i]))
402+ switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[i])))
403 {
404 case gcvMMU_USED:
405 /* Used page, so close any open node. */
406@@ -229,10 +266,10 @@ _Collect(
407 }
408
409 /* Advance the count. */
410- count += pageTable[i] >> 8;
411+ count += _ReadPageEntry(&pageTable[i]) >> 8;
412
413 /* Advance the index into the page table. */
414- i += (pageTable[i] >> 8) - 1;
415+ i += (_ReadPageEntry(&pageTable[i]) >> 8) - 1;
416 break;
417
418 default:
419@@ -341,19 +378,20 @@ _FillFlatMapping(
420 gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
421 }
422
423- *(Mmu->mtlbLogical + mStart)
424- = stlb->physBase
425- /* 64KB page size */
426- | (1 << 2)
427- /* Ignore exception */
428- | (0 << 1)
429- /* Present */
430- | (1 << 0);
431+ _WritePageEntry(Mmu->mtlbLogical + mStart,
432+ stlb->physBase
433+ /* 64KB page size */
434+ | (1 << 2)
435+ /* Ignore exception */
436+ | (0 << 1)
437+ /* Present */
438+ | (1 << 0)
439+ );
440 #if gcdMMU_TABLE_DUMP
441 gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
442 __FUNCTION__, __LINE__,
443 mStart,
444- *(Mmu->mtlbLogical + mStart));
445+ _ReadPageEntry(Mmu->mtlbLogical + mStart));
446 #endif
447
448 stlb->mtlbIndex = mStart;
449@@ -368,12 +406,12 @@ _FillFlatMapping(
450 while (sStart <= last)
451 {
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__,
458 sStart,
459- *(stlb->logical + sStart));
460+ _ReadPageEntry(stlb->logical + sStart));
461 #endif
462 /* next page. */
463 start += gcdMMU_PAGE_64K_SIZE;
464@@ -428,7 +466,7 @@ OnError:
465 if (pre->mtlbEntryNum != 0)
466 {
467 gcmkASSERT(pre->mtlbEntryNum == 1);
468- *(Mmu->mtlbLogical + pre->mtlbIndex) = 0;
469+ _WritePageEntry(Mmu->mtlbLogical + pre->mtlbIndex, 0);
470 }
471
472 gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
473@@ -493,8 +531,8 @@ _SetupDynamicSpace(
474
475 /* Initilization. */
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);
481 Mmu->heapList = 0;
482 Mmu->freeNodes = gcvFALSE;
483
484@@ -509,18 +547,20 @@ _SetupDynamicSpace(
485 /* Map to Master TLB. */
486 for (; i < gcdMMU_MTLB_ENTRY_NUM; i++)
487 {
488- Mmu->mtlbLogical[i] = physical
489- /* 4KB page size */
490- | (0 << 2)
491- /* Ignore exception */
492- | (0 << 1)
493- /* Present */
494- | (1 << 0);
495+ _WritePageEntry(Mmu->mtlbLogical + i,
496+ physical
497+ /* 4KB page size */
498+ | (0 << 2)
499+ /* Ignore exception */
500+ | (0 << 1)
501+ /* Present */
502+ | (1 << 0)
503+ );
504 #if gcdMMU_TABLE_DUMP
505 gckOS_Print("%s(%d): insert MTLB[%d]: %08x\n",
506 __FUNCTION__, __LINE__,
507 i,
508- *(Mmu->mtlbLogical + i));
509+ _ReadPageEntry(Mmu->mtlbLogical + i));
510 #endif
511 physical += gcdMMU_STLB_4K_SIZE;
512 }
513@@ -645,18 +685,11 @@ _Construct(
514 pageTable = mmu->pageTableLogical;
515
516 #if gcdMMU_CLEAR_VALUE
517- {
518- gctUINT32 i;
519-
520- for (i = 0; i < mmu->pageTableEntries; ++i)
521- {
522- pageTable[i] = gcdMMU_CLEAR_VALUE;
523- }
524- }
525+ _FillPageTable(pageTable, mmu->pageTableEntries, gcdMMU_CLEAR_VALUE);
526 #endif
527
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);
532 mmu->heapList = 0;
533 mmu->freeNodes = gcvFALSE;
534
535@@ -797,7 +830,7 @@ _Destroy(
536 if (pre->mtlbEntryNum != 0)
537 {
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);)
546 {
547 /* Check the node type. */
548- switch (gcmENTRY_TYPE(pageTable[index]))
549+ switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
550 {
551 case gcvMMU_SINGLE:
552 /* Single odes are valid if we only need 1 page. */
553@@ -1056,13 +1089,13 @@ _AllocatePages(
554 {
555 /* Move to next node. */
556 previous = index;
557- index = pageTable[index] >> 8;
558+ index = _ReadPageEntry(&pageTable[index]) >> 8;
559 }
560 break;
561
562 case gcvMMU_FREE:
563 /* Test if the node has enough space. */
564- if (PageCount <= (pageTable[index] >> 8))
565+ if (PageCount <= (_ReadPageEntry(&pageTable[index]) >> 8))
566 {
567 gotIt = gcvTRUE;
568 }
569@@ -1070,7 +1103,7 @@ _AllocatePages(
570 {
571 /* Move to next node. */
572 previous = index;
573- index = pageTable[index + 1];
574+ index = _ReadPageEntry(&pageTable[index + 1]);
575 }
576 break;
577
578@@ -1099,36 +1132,36 @@ _AllocatePages(
579 }
580 }
581
582- switch (gcmENTRY_TYPE(pageTable[index]))
583+ switch (gcmENTRY_TYPE(_ReadPageEntry(&pageTable[index])))
584 {
585 case gcvMMU_SINGLE:
586 /* Unlink single node from free list. */
587 gcmkONERROR(
588- _Link(Mmu, previous, pageTable[index] >> 8));
589+ _Link(Mmu, previous, _ReadPageEntry(&pageTable[index]) >> 8));
590 break;
591
592 case gcvMMU_FREE:
593 /* Check how many pages will be left. */
594- left = (pageTable[index] >> 8) - PageCount;
595+ left = (_ReadPageEntry(&pageTable[index]) >> 8) - PageCount;
596 switch (left)
597 {
598 case 0:
599 /* The entire node is consumed, just unlink it. */
600 gcmkONERROR(
601- _Link(Mmu, previous, pageTable[index + 1]));
602+ _Link(Mmu, previous, _ReadPageEntry(&pageTable[index + 1])));
603 break;
604
605 case 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);
610 index ++;
611 break;
612
613 default:
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);
618 index += left;
619 break;
620 }
621@@ -1232,35 +1265,32 @@ _FreePages(
622 #if gcdMMU_CLEAR_VALUE
623 if (Mmu->hardware->mmuVersion == 0)
624 {
625- gctUINT32 i;
626-
627- for (i = 0; i < PageCount; ++i)
628- {
629- pageTable[i] = gcdMMU_CLEAR_VALUE;
630- }
631+ _FillPageTable(pageTable, PageCount, gcdMMU_CLEAR_VALUE);
632 }
633 #endif
634
635 if (PageCount == 1)
636 {
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 */
643- | (1 << 1)
644+ /* Enable exception */
645+ | 1 << 1
646 #endif
647- ;
648+ );
649 }
650 else
651 {
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 */
658- | (1 << 1)
659+ /* Enable exception */
660+ | 1 << 1
661 #endif
662- ;
663- pageTable[1] = ~0U;
664+ );
665+ _WritePageEntry(pageTable + 1, ~0U);
666
667 #if gcdUSE_MMU_EXCEPTION
668 /* Enable exception */
669@@ -1509,12 +1539,8 @@ gckMMU_SetPage(
670 data = _SetPage(PageAddress);
671 }
672
673- if (Mmu->hardware->bigEndian)
674- {
675- data = gcmSWAB32(data);
676- }
677+ _WritePageEntry(PageEntry, data);
678
679- *PageEntry = data;
680 #if gcdMIRROR_PAGETABLE
681 for (i = 0; i < mirrorPageTable->reference; i++)
682 {
683@@ -1526,11 +1552,11 @@ gckMMU_SetPage(
684
685 if (mmu->hardware->mmuVersion == 0)
686 {
687- *pageEntry = PageAddress;
688+ _WritePageEntry(pageEntry, PageAddress);
689 }
690 else
691 {
692- *pageEntry = _SetPage(PageAddress);
693+ _WritePageEntry(pageEntry, _SetPage(PageAddress));
694 }
695 }
696
697@@ -1734,7 +1760,7 @@ gckMMU_DumpPageTableEntry(
698 * gcdMMU_STLB_4K_ENTRY_NUM
699 + stlb;
700
701- gcmkPRINT(" Page table entry = 0x%08X", pageTable[index]);
702+ gcmkPRINT(" Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
703 }
704
705 gcmkFOOTER_NO();
706diff --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
707index 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(
711 )
712 {
713 /* The left memory is for small memory.*/
714- gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
715+ status = gcvSTATUS_OUT_OF_MEMORY;
716+ goto OnError;
717 }
718 #endif
719
720diff --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
721index 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(
725 );
726
727 gceSTATUS
728-gcoOS_GetNextDisplayInfoEx(
729+gcoOS_GetNextDisplayInfoExByIndex(
730+ IN gctINT Index,
731 IN HALNativeDisplayType Display,
732 IN HALNativeWindowType Window,
733 IN gctUINT DisplayInfoSize,
734@@ -274,15 +275,15 @@ gcoOS_SetDisplayVirtualEx(
735
736 gceSTATUS
737 gcoOS_SetSwapInterval(
738- IN HALNativeDisplayType Display,
739- IN gctINT Interval
740+ IN HALNativeDisplayType Display,
741+ IN gctINT Interval
742 );
743
744 gceSTATUS
745 gcoOS_GetSwapInterval(
746- IN HALNativeDisplayType Display,
747- IN gctINT_PTR Min,
748- IN gctINT_PTR Max
749+ IN HALNativeDisplayType Display,
750+ IN gctINT_PTR Min,
751+ IN gctINT_PTR Max
752 );
753
754 gceSTATUS
755diff --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
756index 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
760 }
761 gceTEXTURE_FACE;
762
763+#if gcdFORCE_MIPMAP
764+typedef enum
765+{
766+ gcvForceMipDisabled = 0,
767+ gcvForceMipEnable = 1,
768+ gcvForceMipGenerated = 2,
769+ gcvForceMipNever = 3,
770+}gceFORCE_MIPMAP;
771+#endif
772+
773 typedef struct _gcsTEXTURE
774 {
775 /* Addressing modes. */
776@@ -1446,6 +1456,10 @@ typedef struct _gcsTEXTURE
777 gceTEXTURE_FILTER mipFilter;
778 gctUINT anisoFilter;
779 gctBOOL forceTopLevel;
780+ gctBOOL autoMipmap;
781+#if gcdFORCE_MIPMAP
782+ gceFORCE_MIPMAP forceMipmap;
783+#endif
784 /* Level of detail. */
785 gctFIXED_POINT lodBias;
786 gctFIXED_POINT lodMin;
787@@ -1479,7 +1493,18 @@ gceSTATUS
788 gcoTEXTURE_Destroy(
789 IN gcoTEXTURE Texture
790 );
791+#if gcdFORCE_MIPMAP
792+gceSTATUS
793+gcoTEXTURE_DestroyForceMipmap(
794+ IN gcoTEXTURE Texture
795+ );
796
797+gceSTATUS
798+gcoTEXTURE_GetMipLevels(
799+ IN gcoTEXTURE Texture,
800+ OUT gctINT * levels
801+ );
802+#endif
803 /* Replace a mipmap in gcoTEXTURE object. */
804 gceSTATUS
805 gcoTEXTURE_ReplaceMipMap(
806diff --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
807index 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
810@@ -114,6 +114,30 @@
811 #define COMMAND_PROCESSOR_VERSION 1
812
813 /*
814+ gcdDUMP_KEY
815+
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.
818+*/
819+#ifndef gcdDUMP_KEY
820+# define gcdDUMP_KEY "process"
821+#endif
822+
823+/*
824+ gcdDUMP_PATH
825+
826+ The dump file location. Some processes cannot write to the sdcard.
827+ Try apps' data dir, e.g. /data/data/com.android.launcher
828+*/
829+#ifndef gcdDUMP_PATH
830+#if defined(ANDROID)
831+# define gcdDUMP_PATH "/mnt/sdcard/"
832+#else
833+# define gcdDUMP_PATH "./"
834+#endif
835+#endif
836+
837+/*
838 gcdDUMP
839
840 When set to 1, a dump of all states and memory uploads, as well as other
841@@ -342,6 +366,17 @@
842 #endif
843
844 /*
845+ gcdUSER_HEAP_ALLOCATOR
846+
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.
850+*/
851+#ifndef gcdUSER_HEAP_ALLOCATOR
852+# define gcdUSER_HEAP_ALLOCATOR 1
853+#endif
854+
855+/*
856 gcdHEAP_SIZE
857
858 Set the allocation size for the internal heaps. Each time a heap is
859diff --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
860index 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
863@@ -28,7 +28,7 @@
864
865 #define gcvVERSION_PATCH 9
866
867-#define gcvVERSION_BUILD 1210
868+#define gcvVERSION_BUILD 4651
869
870 #define gcvVERSION_DATE __DATE__
871
872diff --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
873index 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(
877
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;
882 #endif
883 vma->vm_pgoff = 0;
884
885diff --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
886index 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
889@@ -73,6 +73,12 @@
890
891 #define GetPageCount(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
892
893+#if LINUX_VERSION_CODE >= KERNEL_VERSION (3,7,0)
894+#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP)
895+#else
896+#define gcdVM_FLAGS (VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_RESERVED)
897+#endif
898+
899 static inline gctINT
900 GetOrder(
901 IN gctINT numPages
902diff --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
903index 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(
907 #endif
908 }
909
910+gceSTATUS
911+_QueryProcessPageTable(
912+ IN gctPOINTER Logical,
913+ OUT gctUINT32 * Address
914+ )
915+{
916+ spinlock_t *lock;
917+ gctUINTPTR_T logical = (gctUINTPTR_T)Logical;
918+ pgd_t *pgd;
919+ pud_t *pud;
920+ pmd_t *pmd;
921+ pte_t *pte;
922+
923+ if (!current->mm)
924+ {
925+ return gcvSTATUS_NOT_FOUND;
926+ }
927+
928+ pgd = pgd_offset(current->mm, logical);
929+ if (pgd_none(*pgd) || pgd_bad(*pgd))
930+ {
931+ return gcvSTATUS_NOT_FOUND;
932+ }
933+
934+ pud = pud_offset(pgd, logical);
935+ if (pud_none(*pud) || pud_bad(*pud))
936+ {
937+ return gcvSTATUS_NOT_FOUND;
938+ }
939+
940+ pmd = pmd_offset(pud, logical);
941+ if (pmd_none(*pmd) || pmd_bad(*pmd))
942+ {
943+ return gcvSTATUS_NOT_FOUND;
944+ }
945+
946+ pte = pte_offset_map_lock(current->mm, pmd, logical, &lock);
947+ if (!pte)
948+ {
949+ return gcvSTATUS_NOT_FOUND;
950+ }
951+
952+ if (!pte_present(*pte))
953+ {
954+ pte_unmap_unlock(pte, lock);
955+ return gcvSTATUS_NOT_FOUND;
956+ }
957+
958+ *Address = (pte_pfn(*pte) << PAGE_SHIFT) | (logical & ~PAGE_MASK);
959+ pte_unmap_unlock(pte, lock);
960+
961+ return gcvSTATUS_OK;
962+}
963+
964 /*******************************************************************************
965 **
966 ** gckOS_Construct
967@@ -1106,6 +1160,9 @@ _CreateKernelVirtualMapping(
968 numPages,
969 0,
970 PAGE_KERNEL);
971+
972+ /* Trigger a page fault. */
973+ memset(addr, 0, numPages * PAGE_SIZE);
974 }
975 #else
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));
980
981+ /* Trigger a page fault. */
982+ memset(addr, 0, numPages * PAGE_SIZE);
983+
984 if (free)
985 {
986 kfree(pages);
987@@ -1540,7 +1600,7 @@ gckOS_MapMemory(
988 #else
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;
993 # endif
994 mdlMap->vma->vm_pgoff = 0;
995
996@@ -1987,7 +2047,7 @@ gckOS_AllocateNonPagedMemory(
997 }
998 #else
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;
1003
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);
1008
1009- /* Get current process ID. */
1010- processID = _GetProcessID();
1011+ /* Query page table of current process first. */
1012+ status = _QueryProcessPageTable(Logical, Address);
1013
1014- /* Route through other function. */
1015- gcmkONERROR(
1016- gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
1017+ if (gcmIS_ERROR(status))
1018+ {
1019+ /* Get current process ID. */
1020+ processID = _GetProcessID();
1021+
1022+ /* Route through other function. */
1023+ gcmkONERROR(
1024+ gckOS_GetPhysicalAddressProcess(Os, Logical, processID, Address));
1025+ }
1026
1027 /* Success. */
1028 gcmkFOOTER_ARG("*Address=0x%08x", *Address);
1029@@ -4139,7 +4205,7 @@ gckOS_LockPages(
1030 return gcvSTATUS_OUT_OF_RESOURCES;
1031 }
1032
1033- mdlMap->vma->vm_flags |= VM_RESERVED;
1034+ mdlMap->vma->vm_flags |= gcdVM_FLAGS;
1035 #if !gcdPAGED_MEMORY_CACHEABLE
1036 if (Cacheable == gcvFALSE)
1037 {
1038--
10391.8.3.2
1040