RK3368 GPU version: Rogue M 1.31
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / rogue_m / services / server / devices / rgx / rgxmmuinit.c
1 /*************************************************************************/ /*!
2 @File
3 @Title          Device specific initialisation routines
4 @Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
5 @Description    Device specific MMU initialisation
6 @License        Dual MIT/GPLv2
7
8 The contents of this file are subject to the MIT license as set out below.
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 Alternatively, the contents of this file may be used under the terms of
21 the GNU General Public License Version 2 ("GPL") in which case the provisions
22 of GPL are applicable instead of those above.
23
24 If you wish to allow use of your version of this file only under the terms of
25 GPL, and not to allow others to use your version of this file under the terms
26 of the MIT license, indicate your decision by deleting the provisions above
27 and replace them with the notice and other provisions required by GPL as set
28 out in the file called "GPL-COPYING" included in this distribution. If you do
29 not delete the provisions above, a recipient may use your version of this file
30 under the terms of either the MIT license or GPL.
31
32 This License is also included in this distribution in the file called
33 "MIT-COPYING".
34
35 EXCEPT AS OTHERWISE STATED IN A NEGOTIATED AGREEMENT: (A) THE SOFTWARE IS
36 PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
37 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
38 PURPOSE AND NONINFRINGEMENT; AND (B) IN NO EVENT SHALL THE AUTHORS OR
39 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
40 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
41 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 */ /**************************************************************************/
43 #include "rgxmmuinit.h"
44 #include "rgxmmudefs_km.h"
45
46 #include "device.h"
47 #include "img_types.h"
48 #include "mmu_common.h"
49 #include "pdump_mmu.h"
50
51 #include "pvr_debug.h"
52 #include "pvrsrv_error.h"
53 #include "rgx_memallocflags.h"
54 #include "pdump_km.h"
55
56 /*
57  * Bits of PT, PD and PC not involving addresses 
58  */
59
60 #define RGX_MMUCTRL_PTE_PROTMASK        (RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN | \
61                                                                          RGX_MMUCTRL_PT_DATA_ENTRY_PENDING_EN | \
62                                                                          RGX_MMUCTRL_PT_DATA_PM_SRC_EN | \
63                                                                          RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN | \
64                                                                          RGX_MMUCTRL_PT_DATA_CC_EN | \
65                                                                          RGX_MMUCTRL_PT_DATA_READ_ONLY_EN | \
66                                                                          RGX_MMUCTRL_PT_DATA_VALID_EN)
67
68 #define RGX_MMUCTRL_PDE_PROTMASK        (RGX_MMUCTRL_PD_DATA_ENTRY_PENDING_EN | \
69                                                                          ~RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK | \
70                                                                          RGX_MMUCTRL_PD_DATA_VALID_EN)
71
72 #define RGX_MMUCTRL_PCE_PROTMASK        (RGX_MMUCTRL_PC_DATA_ENTRY_PENDING_EN | \
73                                                                          RGX_MMUCTRL_PC_DATA_VALID_EN)
74
75
76
77
78
79 static MMU_PxE_CONFIG sRGXMMUPCEConfig;
80 static MMU_DEVVADDR_CONFIG sRGXMMUTopLevelDevVAddrConfig;
81
82
83 typedef struct _RGX_PAGESIZECONFIG_
84 {
85         const MMU_PxE_CONFIG *psPDEConfig;
86         const MMU_PxE_CONFIG *psPTEConfig;
87         const MMU_DEVVADDR_CONFIG *psDevVAddrConfig;
88         IMG_UINT32 uiRefCount;
89         IMG_UINT32 uiMaxRefCount;
90 } RGX_PAGESIZECONFIG;
91
92 /*
93  *
94  *  Configuration for heaps with 4kB Data-Page size
95  *
96  */
97
98 static MMU_PxE_CONFIG sRGXMMUPDEConfig_4KBDP;
99 static MMU_PxE_CONFIG sRGXMMUPTEConfig_4KBDP;
100 static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_4KBDP;
101 static RGX_PAGESIZECONFIG gsPageSizeConfig4KB;
102
103
104 /*
105  *
106  *  Configuration for heaps with 16kB Data-Page size
107  *
108  */
109
110 static MMU_PxE_CONFIG sRGXMMUPDEConfig_16KBDP;
111 static MMU_PxE_CONFIG sRGXMMUPTEConfig_16KBDP;
112 static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_16KBDP;
113 static RGX_PAGESIZECONFIG gsPageSizeConfig16KB;
114
115
116 /*
117  *
118  *  Configuration for heaps with 64kB Data-Page size
119  *
120  */
121
122 static MMU_PxE_CONFIG sRGXMMUPDEConfig_64KBDP;
123 static MMU_PxE_CONFIG sRGXMMUPTEConfig_64KBDP;
124 static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_64KBDP;
125 static RGX_PAGESIZECONFIG gsPageSizeConfig64KB;
126
127
128 /*
129  *
130  *  Configuration for heaps with 256kB Data-Page size
131  *
132  */
133
134 static MMU_PxE_CONFIG sRGXMMUPDEConfig_256KBDP;
135 static MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP;
136 static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_256KBDP;
137 static RGX_PAGESIZECONFIG gsPageSizeConfig256KB;
138
139
140 /*
141  *
142  *  Configuration for heaps with 1MB Data-Page size
143  *
144  */
145
146 static MMU_PxE_CONFIG sRGXMMUPDEConfig_1MBDP;
147 static MMU_PxE_CONFIG sRGXMMUPTEConfig_1MBDP;
148 static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_1MBDP;
149 static RGX_PAGESIZECONFIG gsPageSizeConfig1MB;
150
151
152 /*
153  *
154  *  Configuration for heaps with 2MB Data-Page size
155  *
156  */
157
158 static MMU_PxE_CONFIG sRGXMMUPDEConfig_2MBDP;
159 static MMU_PxE_CONFIG sRGXMMUPTEConfig_2MBDP;
160 static MMU_DEVVADDR_CONFIG sRGXMMUDevVAddrConfig_2MBDP;
161 static RGX_PAGESIZECONFIG gsPageSizeConfig2MB;
162
163
164 /* Forward declaration of protection bits derivation functions, for
165    the following structure */
166 static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 ui32Log2PageSize);
167 static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags);
168 static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 ui32Log2PageSize);
169 static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags);
170 static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 ui32Log2PageSize);
171 static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags);
172
173 static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize,
174                                            const MMU_PxE_CONFIG **ppsMMUPDEConfig,
175                                            const MMU_PxE_CONFIG **ppsMMUPTEConfig,
176                                            const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig,
177                                            IMG_HANDLE *phPriv);
178
179 static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv);
180
181 static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize);
182 static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize);
183
184 static MMU_DEVICEATTRIBS sRGXMMUDeviceAttributes;
185
186 PVRSRV_ERROR RGXMMUInit_Register(PVRSRV_DEVICE_NODE *psDeviceNode)
187 {
188         /*
189          * Setup sRGXMMUDeviceAttributes
190          */
191         sRGXMMUDeviceAttributes.eMMUType = PDUMP_MMU_TYPE_VARPAGE_40BIT;
192         sRGXMMUDeviceAttributes.eTopLevel = MMU_LEVEL_3;
193         sRGXMMUDeviceAttributes.ui32BaseAlign = RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT;
194         sRGXMMUDeviceAttributes.psBaseConfig = &sRGXMMUPCEConfig;
195         sRGXMMUDeviceAttributes.psTopLevelDevVAddrConfig = &sRGXMMUTopLevelDevVAddrConfig;
196
197         /* Functions for deriving page table/dir/cat protection bits */
198         sRGXMMUDeviceAttributes.pfnDerivePCEProt8 = RGXDerivePCEProt8;
199         sRGXMMUDeviceAttributes.pfnDerivePCEProt4 = RGXDerivePCEProt4;
200         sRGXMMUDeviceAttributes.pfnDerivePDEProt8 = RGXDerivePDEProt8;
201         sRGXMMUDeviceAttributes.pfnDerivePDEProt4 = RGXDerivePDEProt4;
202         sRGXMMUDeviceAttributes.pfnDerivePTEProt8 = RGXDerivePTEProt8;
203         sRGXMMUDeviceAttributes.pfnDerivePTEProt4 = RGXDerivePTEProt4;
204
205         /* Functions for establishing configurations for PDE/PTE/DEVVADDR
206            on per-heap basis */
207         sRGXMMUDeviceAttributes.pfnGetPageSizeConfiguration = RGXGetPageSizeConfigCB;
208         sRGXMMUDeviceAttributes.pfnPutPageSizeConfiguration = RGXPutPageSizeConfigCB;
209
210         sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE4 = RGXGetPageSizeFromPDE4;
211         sRGXMMUDeviceAttributes.pfnGetPageSizeFromPDE8 = RGXGetPageSizeFromPDE8;
212
213         /*
214          * Setup sRGXMMUPCEConfig
215          */
216         sRGXMMUPCEConfig.uiBytesPerEntry = 4; /* 32 bit entries */
217         sRGXMMUPCEConfig.uiAddrMask = 0xfffffff0; /* Mask to get significant address bits of PC entry */
218
219         sRGXMMUPCEConfig.uiAddrShift = 4; /* Shift this many bits to get PD address in PC entry */
220         sRGXMMUPCEConfig.uiLog2Align = 12; /* Alignment of PD AND PC */
221
222         sRGXMMUPCEConfig.uiProtMask = RGX_MMUCTRL_PCE_PROTMASK; //Mask to get the status bits of the PC */
223         sRGXMMUPCEConfig.uiProtShift = 0; /* Shift this many bits to have status bits starting with bit 0 */
224
225         sRGXMMUPCEConfig.uiValidEnMask = RGX_MMUCTRL_PC_DATA_VALID_EN; /* Mask to get entry valid bit of the PC */
226         sRGXMMUPCEConfig.uiValidEnShift = RGX_MMUCTRL_PC_DATA_VALID_SHIFT; /* Shift this many bits to have entry valid bit starting with bit 0 */
227
228         /*
229          *  Setup sRGXMMUTopLevelDevVAddrConfig
230          */
231         sRGXMMUTopLevelDevVAddrConfig.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK; /* Get the PC address bits from a 40 bit virt. address (in a 64bit UINT) */
232         sRGXMMUTopLevelDevVAddrConfig.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
233
234         sRGXMMUTopLevelDevVAddrConfig.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK; /* Get the PD address bits from a 40 bit virt. address (in a 64bit UINT) */
235         sRGXMMUTopLevelDevVAddrConfig.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
236
237 /*
238  *
239  *  Configuration for heaps with 4kB Data-Page size
240  *
241  */
242
243         /*
244          * Setup sRGXMMUPDEConfig_4KBDP
245          */
246         sRGXMMUPDEConfig_4KBDP.uiBytesPerEntry = 8;
247
248         sRGXMMUPDEConfig_4KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
249         sRGXMMUPDEConfig_4KBDP.uiAddrShift = 12;
250         sRGXMMUPDEConfig_4KBDP.uiLog2Align = 12;
251
252         sRGXMMUPDEConfig_4KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
253         sRGXMMUPDEConfig_4KBDP.uiVarCtrlShift = 1;
254
255         sRGXMMUPDEConfig_4KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
256         sRGXMMUPDEConfig_4KBDP.uiProtShift = 0;
257
258         sRGXMMUPDEConfig_4KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
259         sRGXMMUPDEConfig_4KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
260
261         /*
262          * Setup sRGXMMUPTEConfig_4KBDP
263          */
264         sRGXMMUPTEConfig_4KBDP.uiBytesPerEntry = 8;
265
266         sRGXMMUPTEConfig_4KBDP.uiAddrMask = IMG_UINT64_C(0xfffffff000);
267         sRGXMMUPTEConfig_4KBDP.uiAddrShift = 12;
268         sRGXMMUPTEConfig_4KBDP.uiLog2Align = 12;
269
270         sRGXMMUPTEConfig_4KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
271         sRGXMMUPTEConfig_4KBDP.uiProtShift = 0;
272
273         sRGXMMUPTEConfig_4KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
274         sRGXMMUPTEConfig_4KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
275
276         /*
277          * Setup sRGXMMUDevVAddrConfig_4KBDP
278          */
279         sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
280         sRGXMMUDevVAddrConfig_4KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
281
282         sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
283         sRGXMMUDevVAddrConfig_4KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
284
285         sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexMask = ~RGX_MMUCTRL_VADDR_PT_INDEX_CLRMSK;
286         sRGXMMUDevVAddrConfig_4KBDP.uiPTIndexShift = RGX_MMUCTRL_VADDR_PT_INDEX_SHIFT;
287
288         sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000000fff);
289         sRGXMMUDevVAddrConfig_4KBDP.uiPageOffsetShift = 0;
290
291         /*
292          * Setup gsPageSizeConfig4KB
293          */
294         gsPageSizeConfig4KB.psPDEConfig = &sRGXMMUPDEConfig_4KBDP;
295         gsPageSizeConfig4KB.psPTEConfig = &sRGXMMUPTEConfig_4KBDP;
296         gsPageSizeConfig4KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_4KBDP;
297         gsPageSizeConfig4KB.uiRefCount = 0;
298         gsPageSizeConfig4KB.uiMaxRefCount = 0;
299
300
301 /*
302  *
303  *  Configuration for heaps with 16kB Data-Page size
304  *
305  */
306
307         /*
308          * Setup sRGXMMUPDEConfig_16KBDP
309          */
310         sRGXMMUPDEConfig_16KBDP.uiBytesPerEntry = 8;
311
312         sRGXMMUPDEConfig_16KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
313         sRGXMMUPDEConfig_16KBDP.uiAddrShift = 10; /* These are for a page directory ENTRY, meaning the address of a PT cropped to suit the PD */
314         sRGXMMUPDEConfig_16KBDP.uiLog2Align = 10; /* Alignment of the page tables NOT directories */
315
316         sRGXMMUPDEConfig_16KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
317         sRGXMMUPDEConfig_16KBDP.uiVarCtrlShift = 1;
318
319         sRGXMMUPDEConfig_16KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
320         sRGXMMUPDEConfig_16KBDP.uiProtShift = 0;
321
322         sRGXMMUPDEConfig_16KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
323         sRGXMMUPDEConfig_16KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
324
325         /*
326          * Setup sRGXMMUPTEConfig_16KBDP
327          */
328         sRGXMMUPTEConfig_16KBDP.uiBytesPerEntry = 8;
329
330         sRGXMMUPTEConfig_16KBDP.uiAddrMask = IMG_UINT64_C(0xffffffc000);
331         sRGXMMUPTEConfig_16KBDP.uiAddrShift = 14; /* These are for a page table ENTRY, meaning the address of a PAGE cropped to suit the PD */
332         sRGXMMUPTEConfig_16KBDP.uiLog2Align = 14; /* Alignment of the pages NOT tables */
333
334         sRGXMMUPTEConfig_16KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
335         sRGXMMUPTEConfig_16KBDP.uiProtShift = 0;
336
337         sRGXMMUPTEConfig_16KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
338         sRGXMMUPTEConfig_16KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
339
340         /*
341          * Setup sRGXMMUDevVAddrConfig_16KBDP
342          */
343         sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
344         sRGXMMUDevVAddrConfig_16KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
345
346         sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
347         sRGXMMUDevVAddrConfig_16KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
348
349         sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001fc000);
350         sRGXMMUDevVAddrConfig_16KBDP.uiPTIndexShift = 14;
351
352         sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetMask = IMG_UINT64_C(0x0000003fff);
353         sRGXMMUDevVAddrConfig_16KBDP.uiPageOffsetShift = 0;
354
355         /*
356          * Setup gsPageSizeConfig16KB
357          */
358         gsPageSizeConfig16KB.psPDEConfig = &sRGXMMUPDEConfig_16KBDP;
359         gsPageSizeConfig16KB.psPTEConfig = &sRGXMMUPTEConfig_16KBDP;
360         gsPageSizeConfig16KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_16KBDP;
361         gsPageSizeConfig16KB.uiRefCount = 0;
362         gsPageSizeConfig16KB.uiMaxRefCount = 0;
363
364
365 /*
366  *
367  *  Configuration for heaps with 64kB Data-Page size
368  *
369  */
370
371         /*
372          * Setup sRGXMMUPDEConfig_64KBDP
373          */
374         sRGXMMUPDEConfig_64KBDP.uiBytesPerEntry = 8;
375
376         sRGXMMUPDEConfig_64KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
377         sRGXMMUPDEConfig_64KBDP.uiAddrShift = 8;
378         sRGXMMUPDEConfig_64KBDP.uiLog2Align = 8;
379
380         sRGXMMUPDEConfig_64KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
381         sRGXMMUPDEConfig_64KBDP.uiVarCtrlShift = 1;
382
383         sRGXMMUPDEConfig_64KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
384         sRGXMMUPDEConfig_64KBDP.uiProtShift = 0;
385
386         sRGXMMUPDEConfig_64KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
387         sRGXMMUPDEConfig_64KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
388
389         /*
390          * Setup sRGXMMUPTEConfig_64KBDP
391          */
392         sRGXMMUPTEConfig_64KBDP.uiBytesPerEntry = 8;
393
394         sRGXMMUPTEConfig_64KBDP.uiAddrMask = IMG_UINT64_C(0xffffff0000);
395         sRGXMMUPTEConfig_64KBDP.uiAddrShift =16;
396         sRGXMMUPTEConfig_64KBDP.uiLog2Align = 16;
397
398         sRGXMMUPTEConfig_64KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
399         sRGXMMUPTEConfig_64KBDP.uiProtShift = 0;
400
401         sRGXMMUPTEConfig_64KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
402         sRGXMMUPTEConfig_64KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
403
404         /*
405          * Setup sRGXMMUDevVAddrConfig_64KBDP
406          */
407         sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
408         sRGXMMUDevVAddrConfig_64KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
409
410         sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
411         sRGXMMUDevVAddrConfig_64KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
412
413         sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001f0000);
414         sRGXMMUDevVAddrConfig_64KBDP.uiPTIndexShift = 16;
415
416         sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000000ffff);
417         sRGXMMUDevVAddrConfig_64KBDP.uiPageOffsetShift = 0;
418
419         /*
420          * Setup gsPageSizeConfig64KB
421          */
422         gsPageSizeConfig64KB.psPDEConfig = &sRGXMMUPDEConfig_64KBDP;
423         gsPageSizeConfig64KB.psPTEConfig = &sRGXMMUPTEConfig_64KBDP;
424         gsPageSizeConfig64KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_64KBDP;
425         gsPageSizeConfig64KB.uiRefCount = 0;
426         gsPageSizeConfig64KB.uiMaxRefCount = 0;
427
428
429 /*
430  *
431  *  Configuration for heaps with 256kB Data-Page size
432  *
433  */
434
435         /*
436          * Setup sRGXMMUPDEConfig_256KBDP
437          */
438         sRGXMMUPDEConfig_256KBDP.uiBytesPerEntry = 8;
439
440         sRGXMMUPDEConfig_256KBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
441         sRGXMMUPDEConfig_256KBDP.uiAddrShift = 6;
442         sRGXMMUPDEConfig_256KBDP.uiLog2Align = 6;
443
444         sRGXMMUPDEConfig_256KBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
445         sRGXMMUPDEConfig_256KBDP.uiVarCtrlShift = 1;
446
447         sRGXMMUPDEConfig_256KBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
448         sRGXMMUPDEConfig_256KBDP.uiProtShift = 0;
449
450         sRGXMMUPDEConfig_256KBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
451         sRGXMMUPDEConfig_256KBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
452
453         /*
454          * Setup MMU_PxE_CONFIG sRGXMMUPTEConfig_256KBDP
455          */
456         sRGXMMUPTEConfig_256KBDP.uiBytesPerEntry = 8;
457
458         sRGXMMUPTEConfig_256KBDP.uiAddrMask = IMG_UINT64_C(0xfffffc0000);
459         sRGXMMUPTEConfig_256KBDP.uiAddrShift = 18;
460         sRGXMMUPTEConfig_256KBDP.uiLog2Align = 18;
461
462         sRGXMMUPTEConfig_256KBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
463         sRGXMMUPTEConfig_256KBDP.uiProtShift = 0;
464
465         sRGXMMUPTEConfig_256KBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
466         sRGXMMUPTEConfig_256KBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
467
468         /*
469          * Setup sRGXMMUDevVAddrConfig_256KBDP
470          */
471         sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
472         sRGXMMUDevVAddrConfig_256KBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
473
474         sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
475         sRGXMMUDevVAddrConfig_256KBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
476
477         sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexMask = IMG_UINT64_C(0x00001c0000);
478         sRGXMMUDevVAddrConfig_256KBDP.uiPTIndexShift = 18;
479
480         sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetMask = IMG_UINT64_C(0x000003ffff);
481         sRGXMMUDevVAddrConfig_256KBDP.uiPageOffsetShift = 0;
482
483         /*
484          * Setup gsPageSizeConfig256KB
485          */
486         gsPageSizeConfig256KB.psPDEConfig = &sRGXMMUPDEConfig_256KBDP;
487         gsPageSizeConfig256KB.psPTEConfig = &sRGXMMUPTEConfig_256KBDP;
488         gsPageSizeConfig256KB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_256KBDP;
489         gsPageSizeConfig256KB.uiRefCount = 0;
490         gsPageSizeConfig256KB.uiMaxRefCount = 0;
491
492         /*
493          * Setup sRGXMMUPDEConfig_1MBDP
494          */
495         sRGXMMUPDEConfig_1MBDP.uiBytesPerEntry = 8;
496
497         sRGXMMUPDEConfig_1MBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
498         sRGXMMUPDEConfig_1MBDP.uiAddrShift = 4;
499         sRGXMMUPDEConfig_1MBDP.uiLog2Align = 4;
500
501         sRGXMMUPDEConfig_1MBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
502         sRGXMMUPDEConfig_1MBDP.uiVarCtrlShift = 1;
503
504         sRGXMMUPDEConfig_1MBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
505         sRGXMMUPDEConfig_1MBDP.uiProtShift = 0;
506
507         sRGXMMUPDEConfig_1MBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
508         sRGXMMUPDEConfig_1MBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
509
510         /*
511          * Setup sRGXMMUPTEConfig_1MBDP
512          */
513         sRGXMMUPTEConfig_1MBDP.uiBytesPerEntry = 8;
514
515         sRGXMMUPTEConfig_1MBDP.uiAddrMask = IMG_UINT64_C(0xfffff00000);
516         sRGXMMUPTEConfig_1MBDP.uiAddrShift = 20;
517         sRGXMMUPTEConfig_1MBDP.uiLog2Align = 20;
518
519         sRGXMMUPTEConfig_1MBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
520         sRGXMMUPTEConfig_1MBDP.uiProtShift = 0;
521
522         sRGXMMUPTEConfig_1MBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
523         sRGXMMUPTEConfig_1MBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
524
525         /*
526          * Setup sRGXMMUDevVAddrConfig_1MBDP
527          */
528         sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
529         sRGXMMUDevVAddrConfig_1MBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
530
531         sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
532         sRGXMMUDevVAddrConfig_1MBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
533
534         sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexMask = IMG_UINT64_C(0x0000100000);
535         sRGXMMUDevVAddrConfig_1MBDP.uiPTIndexShift = 20;
536
537         sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetMask = IMG_UINT64_C(0x00000fffff);
538         sRGXMMUDevVAddrConfig_1MBDP.uiPageOffsetShift = 0;
539
540         /*
541          * Setup gsPageSizeConfig1MB
542          */
543         gsPageSizeConfig1MB.psPDEConfig = &sRGXMMUPDEConfig_1MBDP;
544         gsPageSizeConfig1MB.psPTEConfig = &sRGXMMUPTEConfig_1MBDP;
545         gsPageSizeConfig1MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_1MBDP;
546         gsPageSizeConfig1MB.uiRefCount = 0;
547         gsPageSizeConfig1MB.uiMaxRefCount = 0;
548
549         /*
550          * Setup sRGXMMUPDEConfig_2MBDP
551          */
552         sRGXMMUPDEConfig_2MBDP.uiBytesPerEntry = 8;
553
554         sRGXMMUPDEConfig_2MBDP.uiAddrMask = IMG_UINT64_C(0xfffffffff0);
555         sRGXMMUPDEConfig_2MBDP.uiAddrShift = 4;
556         sRGXMMUPDEConfig_2MBDP.uiLog2Align = 4;
557
558         sRGXMMUPDEConfig_2MBDP.uiVarCtrlMask = IMG_UINT64_C(0x000000000e);
559         sRGXMMUPDEConfig_2MBDP.uiVarCtrlShift = 1;
560
561         sRGXMMUPDEConfig_2MBDP.uiProtMask = RGX_MMUCTRL_PDE_PROTMASK;
562         sRGXMMUPDEConfig_2MBDP.uiProtShift = 0;
563
564         sRGXMMUPDEConfig_2MBDP.uiValidEnMask = RGX_MMUCTRL_PD_DATA_VALID_EN;
565         sRGXMMUPDEConfig_2MBDP.uiValidEnShift = RGX_MMUCTRL_PD_DATA_VALID_SHIFT;
566
567         /*
568          * Setup sRGXMMUPTEConfig_2MBDP
569          */
570         sRGXMMUPTEConfig_2MBDP.uiBytesPerEntry = 8;
571
572         sRGXMMUPTEConfig_2MBDP.uiAddrMask = IMG_UINT64_C(0xffffe00000);
573         sRGXMMUPTEConfig_2MBDP.uiAddrShift = 21;
574         sRGXMMUPTEConfig_2MBDP.uiLog2Align = 21;
575
576         sRGXMMUPTEConfig_2MBDP.uiProtMask = RGX_MMUCTRL_PTE_PROTMASK;
577         sRGXMMUPTEConfig_2MBDP.uiProtShift = 0;
578
579         sRGXMMUPTEConfig_2MBDP.uiValidEnMask = RGX_MMUCTRL_PT_DATA_VALID_EN;
580         sRGXMMUPTEConfig_2MBDP.uiValidEnShift = RGX_MMUCTRL_PT_DATA_VALID_SHIFT;
581
582         /*
583          * Setup sRGXMMUDevVAddrConfig_2MBDP
584          */
585         sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexMask = ~RGX_MMUCTRL_VADDR_PC_INDEX_CLRMSK;
586         sRGXMMUDevVAddrConfig_2MBDP.uiPCIndexShift = RGX_MMUCTRL_VADDR_PC_INDEX_SHIFT;
587
588         sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexMask = ~RGX_MMUCTRL_VADDR_PD_INDEX_CLRMSK;
589         sRGXMMUDevVAddrConfig_2MBDP.uiPDIndexShift = RGX_MMUCTRL_VADDR_PD_INDEX_SHIFT;
590
591         sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexMask = IMG_UINT64_C(0x0000000000);
592         sRGXMMUDevVAddrConfig_2MBDP.uiPTIndexShift = 21;
593
594         sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetMask = IMG_UINT64_C(0x00001fffff);
595         sRGXMMUDevVAddrConfig_2MBDP.uiPageOffsetShift = 0;
596
597         /*
598          * Setup gsPageSizeConfig2MB
599          */
600         gsPageSizeConfig2MB.psPDEConfig = &sRGXMMUPDEConfig_2MBDP;
601         gsPageSizeConfig2MB.psPTEConfig = &sRGXMMUPTEConfig_2MBDP;
602         gsPageSizeConfig2MB.psDevVAddrConfig = &sRGXMMUDevVAddrConfig_2MBDP;
603         gsPageSizeConfig2MB.uiRefCount = 0;
604         gsPageSizeConfig2MB.uiMaxRefCount = 0;
605
606         /*
607          * Setup sRGXMMUDeviceAttributes
608          */
609         sRGXMMUDeviceAttributes.eTopLevel = MMU_LEVEL_3;
610         sRGXMMUDeviceAttributes.ui32BaseAlign = RGX_MMUCTRL_PC_DATA_PD_BASE_ALIGNSHIFT;
611         sRGXMMUDeviceAttributes.psBaseConfig = &sRGXMMUPCEConfig;
612         sRGXMMUDeviceAttributes.psTopLevelDevVAddrConfig = &sRGXMMUTopLevelDevVAddrConfig;
613
614         /* Functions for deriving page table/dir/cat protection bits */
615         sRGXMMUDeviceAttributes.pfnDerivePCEProt8 = RGXDerivePCEProt8;
616         sRGXMMUDeviceAttributes.pfnDerivePCEProt4 = RGXDerivePCEProt4;
617         sRGXMMUDeviceAttributes.pfnDerivePDEProt8 = RGXDerivePDEProt8;
618         sRGXMMUDeviceAttributes.pfnDerivePDEProt4 = RGXDerivePDEProt4;
619         sRGXMMUDeviceAttributes.pfnDerivePTEProt8 = RGXDerivePTEProt8;
620         sRGXMMUDeviceAttributes.pfnDerivePTEProt4 = RGXDerivePTEProt4;
621
622         /* Functions for establishing configurations for PDE/PTE/DEVVADDR
623            on per-heap basis */
624         sRGXMMUDeviceAttributes.pfnGetPageSizeConfiguration = RGXGetPageSizeConfigCB;
625         sRGXMMUDeviceAttributes.pfnPutPageSizeConfiguration = RGXPutPageSizeConfigCB;
626
627         psDeviceNode->psMMUDevAttrs = &sRGXMMUDeviceAttributes;
628
629         return PVRSRV_OK;
630 }
631
632 PVRSRV_ERROR RGXMMUInit_Unregister(PVRSRV_DEVICE_NODE *psDeviceNode)
633 {
634     PVRSRV_ERROR eError;
635
636     eError = PVRSRV_OK;
637
638 #if defined(PDUMP)
639     psDeviceNode->pfnMMUGetContextID = IMG_NULL;
640 #endif
641
642     psDeviceNode->psMMUDevAttrs = IMG_NULL;
643
644 #if defined(DEBUG)
645     PVR_DPF((PVR_DBG_MESSAGE, "Variable Page Size Heap Stats:"));
646     PVR_DPF((PVR_DBG_MESSAGE, "Max 4K page heaps: %d",
647              gsPageSizeConfig4KB.uiMaxRefCount));
648     PVR_DPF((PVR_DBG_VERBOSE, "Current 4K page heaps (should be 0): %d",
649              gsPageSizeConfig4KB.uiRefCount));
650     PVR_DPF((PVR_DBG_MESSAGE, "Max 16K page heaps: %d",
651              gsPageSizeConfig16KB.uiMaxRefCount));
652     PVR_DPF((PVR_DBG_VERBOSE, "Current 16K page heaps (should be 0): %d",
653              gsPageSizeConfig16KB.uiRefCount));
654     PVR_DPF((PVR_DBG_MESSAGE, "Max 64K page heaps: %d",
655              gsPageSizeConfig64KB.uiMaxRefCount));
656     PVR_DPF((PVR_DBG_VERBOSE, "Current 64K page heaps (should be 0): %d",
657              gsPageSizeConfig64KB.uiRefCount));
658     PVR_DPF((PVR_DBG_MESSAGE, "Max 256K page heaps: %d",
659              gsPageSizeConfig256KB.uiMaxRefCount));
660     PVR_DPF((PVR_DBG_VERBOSE, "Current 256K page heaps (should be 0): %d",
661              gsPageSizeConfig256KB.uiRefCount));
662     PVR_DPF((PVR_DBG_MESSAGE, "Max 1M page heaps: %d",
663              gsPageSizeConfig1MB.uiMaxRefCount));
664     PVR_DPF((PVR_DBG_VERBOSE, "Current 1M page heaps (should be 0): %d",
665              gsPageSizeConfig1MB.uiRefCount));
666     PVR_DPF((PVR_DBG_MESSAGE, "Max 2M page heaps: %d",
667              gsPageSizeConfig2MB.uiMaxRefCount));
668     PVR_DPF((PVR_DBG_VERBOSE, "Current 2M page heaps (should be 0): %d",
669              gsPageSizeConfig2MB.uiRefCount));
670 #endif
671     if (gsPageSizeConfig4KB.uiRefCount > 0 ||
672         gsPageSizeConfig16KB.uiRefCount > 0 ||
673         gsPageSizeConfig64KB.uiRefCount > 0 ||
674         gsPageSizeConfig256KB.uiRefCount > 0 ||
675         gsPageSizeConfig1MB.uiRefCount > 0 ||
676         gsPageSizeConfig2MB.uiRefCount > 0
677         )
678     {
679         PVR_DPF((PVR_DBG_ERROR, "RGXMMUInit_Unregister: Unbalanced MMU API Usage (Internal error)"));
680     }
681
682     return eError;
683 }
684
685 /*************************************************************************/ /*!
686 @Function       RGXDerivePCEProt4
687 @Description    calculate the PCE protection flags based on a 4 byte entry
688 @Return         PVRSRV_ERROR
689 */ /**************************************************************************/
690 static IMG_UINT32 RGXDerivePCEProt4(IMG_UINT32 uiProtFlags)
691 {
692     return (uiProtFlags & MMU_PROTFLAGS_INVALID)?0:RGX_MMUCTRL_PC_DATA_VALID_EN;
693 }
694
695
696 /*************************************************************************/ /*!
697 @Function       RGXDerivePCEProt8
698 @Description    calculate the PCE protection flags based on an 8 byte entry
699 @Return         PVRSRV_ERROR
700 */ /**************************************************************************/
701 static IMG_UINT64 RGXDerivePCEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 ui32Log2PageSize)
702 {
703         PVR_UNREFERENCED_PARAMETER(uiProtFlags);
704         PVR_UNREFERENCED_PARAMETER(ui32Log2PageSize);
705
706         PVR_DPF((PVR_DBG_ERROR, "8-byte PCE not supported on this device"));
707         return 0;       
708 }
709
710
711 /*************************************************************************/ /*!
712 @Function       RGXDerivePDEProt4
713 @Description    derive the PDE protection flags based on a 4 byte entry
714 @Return         PVRSRV_ERROR
715 */ /**************************************************************************/
716 static IMG_UINT32 RGXDerivePDEProt4(IMG_UINT32 uiProtFlags)
717 {
718     PVR_UNREFERENCED_PARAMETER(uiProtFlags);
719         PVR_DPF((PVR_DBG_ERROR, "4-byte PDE not supported on this device"));
720         return 0;
721 }
722
723
724 /*************************************************************************/ /*!
725 @Function       RGXDerivePDEProt8
726 @Description    derive the PDE protection flags based on an 8 byte entry
727
728 @Input          ui8Log2PageSize The log2 of the required page size.
729                 E.g, for 4KiB pages, this parameter must be 12.
730                 For 2MiB pages, it must be set to 21.
731
732 @Return         PVRSRV_ERROR
733 */ /**************************************************************************/
734 static IMG_UINT64 RGXDerivePDEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 ui32Log2PageSize)
735 {
736         IMG_UINT64 ret_value = 0; // 0 means invalid
737
738     if (! (uiProtFlags & MMU_PROTFLAGS_INVALID)) // if not invalid
739         {
740                 switch (ui32Log2PageSize)
741                 {
742                         case 12:
743                                 ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB;
744                                 break;
745                         case 14:
746                                 ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB;
747                                 break;
748                         case 16:
749                                 ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB;
750                                 break;
751                         case 18:
752                                 ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB;
753                                 break;
754                         case 20:
755                                 ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB;
756                                 break;
757                         case 21:
758                                 ret_value = RGX_MMUCTRL_PD_DATA_VALID_EN | RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB;
759                                 break;
760                         default:
761                                 PVR_DPF((PVR_DBG_ERROR,
762                                                  "%s:%d: in function<%s>: Invalid parameter log2_page_size. Expected {12, 14, 16, 18, 20, 21}. Got [%u]",
763                                                  __FILE__, __LINE__, __FUNCTION__, ui32Log2PageSize));
764                 }
765         }
766         return ret_value;
767 }
768
769
770 /*************************************************************************/ /*!
771 @Function       RGXDerivePTEProt4
772 @Description    calculate the PTE protection flags based on a 4 byte entry
773 @Return         PVRSRV_ERROR
774 */ /**************************************************************************/
775 static IMG_UINT32 RGXDerivePTEProt4(IMG_UINT32 uiProtFlags)
776 {
777     PVR_UNREFERENCED_PARAMETER(uiProtFlags);
778         PVR_DPF((PVR_DBG_ERROR, "4-byte PTE not supported on this device"));
779
780         return 0;
781 }
782
783 /*************************************************************************/ /*!
784 @Function       RGXDerivePTEProt8
785 @Description    calculate the PTE protection flags based on an 8 byte entry
786 @Return         PVRSRV_ERROR
787 */ /**************************************************************************/
788 static IMG_UINT64 RGXDerivePTEProt8(IMG_UINT32 uiProtFlags, IMG_UINT32 ui32Log2PageSize)
789 {
790         IMG_UINT64 ui64MMUFlags=0;
791
792         PVR_UNREFERENCED_PARAMETER(ui32Log2PageSize);
793
794         if(((MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE) & uiProtFlags) == (MMU_PROTFLAGS_READABLE|MMU_PROTFLAGS_WRITEABLE))
795         {
796                 /* read/write */
797         }
798         else if(MMU_PROTFLAGS_READABLE & uiProtFlags)
799         {
800                 /* read only */
801                 ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_READ_ONLY_EN;
802         }
803         else if(MMU_PROTFLAGS_WRITEABLE & uiProtFlags)
804         {
805                 /* write only */
806         PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt8: write-only is not possible on this device"));
807         }
808     else if ((MMU_PROTFLAGS_INVALID & uiProtFlags) == 0)
809     {
810         PVR_DPF((PVR_DBG_ERROR, "RGXDerivePTEProt8: neither read nor write specified..."));
811     }
812
813         /* cache coherency */
814         if(MMU_PROTFLAGS_CACHE_COHERENT & uiProtFlags)
815         {
816                 ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_CC_EN;
817         }
818
819         /* cache setup */
820         if ((MMU_PROTFLAGS_CACHED & uiProtFlags) == 0)
821         {
822                 ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_SLC_BYPASS_CTRL_EN;
823         }
824
825     if ((uiProtFlags & MMU_PROTFLAGS_INVALID) == 0)
826     {
827         ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_VALID_EN;
828     }
829
830         if (MMU_PROTFLAGS_DEVICE(PMMETA_PROTECT) & uiProtFlags)
831         {
832                 ui64MMUFlags |= RGX_MMUCTRL_PT_DATA_PM_META_PROTECT_EN;
833         }
834
835         return ui64MMUFlags;
836 }
837
838
839 /*************************************************************************/ /*!
840 @Function       RGXGetPageSizeConfig
841 @Description    Set up configuration for variable sized data pages.
842                 RGXPutPageSizeConfigCB has to be called to ensure correct
843                 refcounting.
844 @Return         PVRSRV_ERROR
845 */ /**************************************************************************/
846 static PVRSRV_ERROR RGXGetPageSizeConfigCB(IMG_UINT32 uiLog2DataPageSize,
847                                            const MMU_PxE_CONFIG **ppsMMUPDEConfig,
848                                            const MMU_PxE_CONFIG **ppsMMUPTEConfig,
849                                            const MMU_DEVVADDR_CONFIG **ppsMMUDevVAddrConfig,
850                                            IMG_HANDLE *phPriv)
851 {
852     RGX_PAGESIZECONFIG *psPageSizeConfig;
853
854     switch (uiLog2DataPageSize)
855     {
856     case 12:
857         psPageSizeConfig = &gsPageSizeConfig4KB;
858         break;
859     case 14:
860         psPageSizeConfig = &gsPageSizeConfig16KB;
861         break;
862     case 16:
863         psPageSizeConfig = &gsPageSizeConfig64KB;
864         break;
865     case 18:
866         psPageSizeConfig = &gsPageSizeConfig256KB;
867         break;
868     case 20:
869         psPageSizeConfig = &gsPageSizeConfig1MB;
870         break;
871     case 21:
872         psPageSizeConfig = &gsPageSizeConfig2MB;
873         break;
874     default:
875         PVR_DPF((PVR_DBG_ERROR,
876                  "RGXGetPageSizeConfigCB: Invalid Data Page Size 1<<0x%x",
877                  uiLog2DataPageSize));
878         return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
879     }
880     
881     /* Refer caller's pointers to the data */
882     *ppsMMUPDEConfig = psPageSizeConfig->psPDEConfig;
883     *ppsMMUPTEConfig = psPageSizeConfig->psPTEConfig;
884     *ppsMMUDevVAddrConfig = psPageSizeConfig->psDevVAddrConfig;
885
886 #if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT)
887     /* Increment ref-count - not that we're allocating anything here
888        (I'm using static structs), but one day we might, so we want
889        the Get/Put code to be balanced properly */
890     psPageSizeConfig->uiRefCount ++;
891
892     /* This is purely for debug statistics */
893     psPageSizeConfig->uiMaxRefCount = MAX(psPageSizeConfig->uiMaxRefCount,
894                                           psPageSizeConfig->uiRefCount);
895 #endif
896
897     *phPriv = (IMG_HANDLE)(IMG_UINTPTR_T)uiLog2DataPageSize;
898         PVR_ASSERT (uiLog2DataPageSize == (IMG_UINT32)(IMG_UINTPTR_T)*phPriv);
899
900     return PVRSRV_OK;
901 }
902
903 /*************************************************************************/ /*!
904 @Function       RGXPutPageSizeConfig
905 @Description    Tells this code that the mmu module is done with the
906                 configurations set in RGXGetPageSizeConfig.  This can
907                 be a no-op.
908                 Called after RGXGetPageSizeConfigCB.
909 @Return         PVRSRV_ERROR
910 */ /**************************************************************************/
911 static PVRSRV_ERROR RGXPutPageSizeConfigCB(IMG_HANDLE hPriv)
912 {
913 #if defined(SUPPORT_MMU_PAGESIZECONFIG_REFCOUNT)
914     RGX_PAGESIZECONFIG *psPageSizeConfig;
915     IMG_UINT32 uiLog2DataPageSize;
916
917     uiLog2DataPageSize = (IMG_UINT32)(IMG_UINTPTR_T) hPriv;
918
919     switch (uiLog2DataPageSize)
920     {
921     case 12:
922         psPageSizeConfig = &gsPageSizeConfig4KB;
923         break;
924     case 14:
925         psPageSizeConfig = &gsPageSizeConfig16KB;
926         break;
927     case 16:
928         psPageSizeConfig = &gsPageSizeConfig64KB;
929         break;
930     case 18:
931         psPageSizeConfig = &gsPageSizeConfig256KB;
932         break;
933     case 20:
934         psPageSizeConfig = &gsPageSizeConfig1MB;
935         break;
936     case 21:
937         psPageSizeConfig = &gsPageSizeConfig2MB;
938         break;
939     default:
940         PVR_DPF((PVR_DBG_ERROR,
941                  "RGXPutPageSizeConfigCB: Invalid Data Page Size 1<<0x%x",
942                  uiLog2DataPageSize));
943         return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
944     }
945
946     /* Ref-count here is not especially useful, but it's an extra
947        check that the API is being used correctly */
948     psPageSizeConfig->uiRefCount --;
949 #else
950     PVR_UNREFERENCED_PARAMETER(hPriv);
951 #endif
952     return PVRSRV_OK;
953 }
954
955 static PVRSRV_ERROR RGXGetPageSizeFromPDE4(IMG_UINT32 ui32PDE, IMG_UINT32 *pui32Log2PageSize)
956 {
957     PVR_UNREFERENCED_PARAMETER(ui32PDE);
958     PVR_UNREFERENCED_PARAMETER(pui32Log2PageSize);
959         PVR_DPF((PVR_DBG_ERROR, "4-byte PDE not supported on this device"));
960         return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
961 }
962
963 static PVRSRV_ERROR RGXGetPageSizeFromPDE8(IMG_UINT64 ui64PDE, IMG_UINT32 *pui32Log2PageSize)
964 {
965         switch (ui64PDE & (~RGX_MMUCTRL_PD_DATA_PAGE_SIZE_CLRMSK))
966         {
967                 case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_4KB:
968                         *pui32Log2PageSize = 12;
969                         break;
970                 case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_16KB:
971                         *pui32Log2PageSize = 14;
972                         break;
973                 case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_64KB:
974                         *pui32Log2PageSize = 16;
975                         break;
976                 case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_256KB:
977                         *pui32Log2PageSize = 18;
978                         break;
979                 case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_1MB:
980                         *pui32Log2PageSize = 20;
981                         break;
982                 case RGX_MMUCTRL_PD_DATA_PAGE_SIZE_2MB:
983                         *pui32Log2PageSize = 21;
984                         break;
985                 default:
986                         return PVRSRV_ERROR_MMU_INVALID_PAGE_SIZE_FOR_DEVICE;
987                         break;
988         }
989         return PVRSRV_OK;
990 }