]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
ENGR00306992 Revert "ENGR00302036-3 gpu:gpu2d may cause bus hang in some corner case"
[karo-tx-linux.git] / drivers / mxc / gpu-viv / arch / XAQ2 / hal / kernel / gc_hal_kernel_hardware.c
1 /****************************************************************************
2 *
3 *    Copyright (C) 2005 - 2013 by Vivante Corp.
4 *
5 *    This program is free software; you can redistribute it and/or modify
6 *    it under the terms of the GNU General Public License as published by
7 *    the Free Software Foundation; either version 2 of the license, or
8 *    (at your option) any later version.
9 *
10 *    This program is distributed in the hope that it will be useful,
11 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 *    GNU General Public License for more details.
14 *
15 *    You should have received a copy of the GNU General Public License
16 *    along with this program; if not write to the Free Software
17 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *****************************************************************************/
20
21
22 #include "gc_hal.h"
23 #include "gc_hal_kernel.h"
24 #if VIVANTE_PROFILER_CONTEXT
25 #include "gc_hal_kernel_context.h"
26 #endif
27
28 #define _GC_OBJ_ZONE    gcvZONE_HARDWARE
29
30 typedef struct _gcsiDEBUG_REGISTERS * gcsiDEBUG_REGISTERS_PTR;
31 typedef struct _gcsiDEBUG_REGISTERS
32 {
33     gctSTRING       module;
34     gctUINT         index;
35     gctUINT         shift;
36     gctUINT         data;
37     gctUINT         count;
38     gctUINT32       signature;
39 }
40 gcsiDEBUG_REGISTERS;
41
42 extern int gpu3DMinClock;
43 /******************************************************************************\
44 ********************************* Support Code *********************************
45 \******************************************************************************/
46 static gceSTATUS
47 _ResetGPU(
48     IN gckHARDWARE Hardware,
49     IN gckOS Os,
50     IN gceCORE Core
51     );
52
53 static gceSTATUS
54 _IdentifyHardware(
55     IN gckOS Os,
56     IN gceCORE Core,
57     OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
58     )
59 {
60     gceSTATUS status;
61
62     gctUINT32 chipIdentity;
63
64     gctUINT32 streamCount = 0;
65     gctUINT32 registerMax = 0;
66     gctUINT32 threadCount = 0;
67     gctUINT32 shaderCoreCount = 0;
68     gctUINT32 vertexCacheSize = 0;
69     gctUINT32 vertexOutputBufferSize = 0;
70     gctUINT32 pixelPipes = 0;
71     gctUINT32 instructionCount = 0;
72     gctUINT32 numConstants = 0;
73     gctUINT32 bufferSize = 0;
74     gctUINT32 varyingsCount = 0;
75     gctBOOL useHZ;
76
77     gcmkHEADER_ARG("Os=0x%x", Os);
78
79     /***************************************************************************
80     ** Get chip ID and revision.
81     */
82
83     /* Read chip identity register. */
84     gcmkONERROR(
85         gckOS_ReadRegisterEx(Os, Core,
86                              0x00018,
87                              &chipIdentity));
88
89     /* Special case for older graphic cores. */
90     if (((((gctUINT32) (chipIdentity)) >> (0 ? 31:24) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))))
91     {
92         Identity->chipModel    = gcv500;
93         Identity->chipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
94     }
95
96     else
97     {
98         /* Read chip identity register. */
99         gcmkONERROR(
100             gckOS_ReadRegisterEx(Os, Core,
101                                  0x00020,
102                                  (gctUINT32_PTR) &Identity->chipModel));
103
104         /* !!!! HACK ALERT !!!! */
105         /* Because people change device IDs without letting software know
106         ** about it - here is the hack to make it all look the same.  Only
107         ** for GC400 family.  Next time - TELL ME!!! */
108         if (((Identity->chipModel & 0xFF00) == 0x0400)
109           && (Identity->chipModel != 0x0420))
110         {
111             Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400);
112         }
113
114         /* Read CHIP_REV register. */
115         gcmkONERROR(
116             gckOS_ReadRegisterEx(Os, Core,
117                                  0x00024,
118                                  &Identity->chipRevision));
119
120         if ((Identity->chipModel    == gcv300)
121         &&  (Identity->chipRevision == 0x2201)
122         )
123         {
124             gctUINT32 chipDate;
125             gctUINT32 chipTime;
126
127             /* Read date and time registers. */
128             gcmkONERROR(
129                 gckOS_ReadRegisterEx(Os, Core,
130                                      0x00028,
131                                      &chipDate));
132
133             gcmkONERROR(
134                 gckOS_ReadRegisterEx(Os, Core,
135                                      0x0002C,
136                                      &chipTime));
137
138             if ((chipDate == 0x20080814) && (chipTime == 0x12051100))
139             {
140                 /* This IP has an ECO; put the correct revision in it. */
141                 Identity->chipRevision = 0x1051;
142             }
143         }
144     }
145
146     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
147                    "Identity: chipModel=%X",
148                    Identity->chipModel);
149
150     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
151                    "Identity: chipRevision=%X",
152                    Identity->chipRevision);
153
154
155     /***************************************************************************
156     ** Get chip features.
157     */
158
159     /* Read chip feature register. */
160     gcmkONERROR(
161         gckOS_ReadRegisterEx(Os, Core,
162                              0x0001C,
163                              &Identity->chipFeatures));
164
165 #ifndef VIVANTE_NO_3D
166     /* Disable fast clear on GC700. */
167     if (Identity->chipModel == gcv700)
168     {
169         Identity->chipFeatures
170             = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
171     }
172 #endif
173
174     if (((Identity->chipModel == gcv500) && (Identity->chipRevision < 2))
175     ||  ((Identity->chipModel == gcv300) && (Identity->chipRevision < 0x2000))
176     )
177     {
178         /* GC500 rev 1.x and GC300 rev < 2.0 doesn't have these registers. */
179         Identity->chipMinorFeatures  = 0;
180         Identity->chipMinorFeatures1 = 0;
181         Identity->chipMinorFeatures2 = 0;
182         Identity->chipMinorFeatures3 = 0;
183         Identity->chipMinorFeatures4 = 0;
184     }
185     else
186     {
187         /* Read chip minor feature register #0. */
188         gcmkONERROR(
189             gckOS_ReadRegisterEx(Os, Core,
190                                  0x00034,
191                                  &Identity->chipMinorFeatures));
192
193         if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (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)))))))
194         )
195         {
196             /* Read chip minor featuress register #1. */
197             gcmkONERROR(
198                 gckOS_ReadRegisterEx(Os, Core,
199                                      0x00074,
200                                      &Identity->chipMinorFeatures1));
201
202             /* Read chip minor featuress register #2. */
203             gcmkONERROR(
204                 gckOS_ReadRegisterEx(Os, Core,
205                                      0x00084,
206                                      &Identity->chipMinorFeatures2));
207
208             /*Identity->chipMinorFeatures2 &= ~(0x1 << 3);*/
209
210             /* Read chip minor featuress register #1. */
211             gcmkONERROR(
212                 gckOS_ReadRegisterEx(Os, Core,
213                                      0x00088,
214                                      &Identity->chipMinorFeatures3));
215
216             /*The BG2 chip has no compression supertiled, and the bit of GCMinorFeature3BugFixes15 is n/a*/
217             if(Identity->chipModel == gcv1000 && Identity->chipRevision == 0x5036)
218             {
219                 Identity->chipMinorFeatures3
220                     = ((((gctUINT32) (Identity->chipMinorFeatures3)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
221                 Identity->chipMinorFeatures3
222                     = ((((gctUINT32) (Identity->chipMinorFeatures3)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27)));
223             }
224
225             /* Read chip minor featuress register #4. */
226             gcmkONERROR(
227                 gckOS_ReadRegisterEx(Os, Core,
228                                      0x00094,
229                                      &Identity->chipMinorFeatures4));
230         }
231         else
232         {
233             /* Chip doesn't has minor features register #1 or 2 or 3 or 4. */
234             Identity->chipMinorFeatures1 = 0;
235             Identity->chipMinorFeatures2 = 0;
236             Identity->chipMinorFeatures3 = 0;
237             Identity->chipMinorFeatures4 = 0;
238         }
239     }
240
241     /* Get the Supertile layout in the hardware. */
242     if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))))
243      || ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))))
244     {
245         Identity->superTileMode = 2;
246     }
247     else if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))))
248     {
249         Identity->superTileMode = 1;
250     }
251     else
252     {
253         Identity->superTileMode = 0;
254     }
255
256     /* Exception for GC1000, revision 5035 &  GC800, revision 4612 */
257     if (((Identity->chipModel == gcv1000) && ((Identity->chipRevision == 0x5035)
258                                            || (Identity->chipRevision == 0x5036)
259                                            || (Identity->chipRevision == 0x5037)))
260          || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612))
261      || ((Identity->chipModel == gcv860) && (Identity->chipRevision == 0x4647)))
262     {
263         Identity->superTileMode = 1;
264     }
265
266     if (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5245)
267     {
268         useHZ = ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))))
269              || ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))));
270     }
271     else
272     {
273         useHZ = gcvFALSE;
274     }
275
276     if (useHZ)
277     {
278         /* Disable EZ. */
279         Identity->chipFeatures
280             = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
281     }
282
283     /* Disable HZ when EZ is present for older chips. */
284     else if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))))
285     {
286         /* Disable HIERARCHICAL_Z. */
287         Identity->chipMinorFeatures
288             = ((((gctUINT32) (Identity->chipMinorFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27)));
289     }
290
291     /* Disable rectangle primitive when chip is gc880_5_1_0_rc6*/
292     if ((Identity->chipModel == gcv880) && (Identity->chipRevision == 0x5106))
293     {
294         /* Disable rectangle primitive. */
295         Identity->chipMinorFeatures2
296             = ((((gctUINT32) (Identity->chipMinorFeatures2)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
297     }
298
299     if ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4605))
300     {
301         /* Correct feature bit: RTL does not have such feature. */
302         Identity->chipFeatures
303             = ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)));
304     }
305
306     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
307                    "Identity: chipFeatures=0x%08X",
308                    Identity->chipFeatures);
309
310     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
311                    "Identity: chipMinorFeatures=0x%08X",
312                    Identity->chipMinorFeatures);
313
314     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
315                    "Identity: chipMinorFeatures1=0x%08X",
316                    Identity->chipMinorFeatures1);
317
318     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
319                    "Identity: chipMinorFeatures2=0x%08X",
320                    Identity->chipMinorFeatures2);
321
322     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
323                    "Identity: chipMinorFeatures3=0x%08X",
324                    Identity->chipMinorFeatures3);
325
326     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
327                    "Identity: chipMinorFeatures4=0x%08X",
328                    Identity->chipMinorFeatures4);
329
330     /***************************************************************************
331     ** Get chip specs.
332     */
333
334     if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (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))))))))
335     {
336         gctUINT32 specs, specs2, specs3;
337
338         /* Read gcChipSpecs register. */
339         gcmkONERROR(
340             gckOS_ReadRegisterEx(Os, Core,
341                                  0x00048,
342                                  &specs));
343
344         /* Extract the fields. */
345         streamCount            = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) );
346         registerMax            = (((((gctUINT32) (specs)) >> (0 ? 7:4)) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1)))))) );
347         threadCount            = (((((gctUINT32) (specs)) >> (0 ? 11:8)) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1)))))) );
348         shaderCoreCount        = (((((gctUINT32) (specs)) >> (0 ? 24:20)) & ((gctUINT32) ((((1 ? 24:20) - (0 ? 24:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:20) - (0 ? 24:20) + 1)))))) );
349         vertexCacheSize        = (((((gctUINT32) (specs)) >> (0 ? 16:12)) & ((gctUINT32) ((((1 ? 16:12) - (0 ? 16:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:12) - (0 ? 16:12) + 1)))))) );
350         vertexOutputBufferSize = (((((gctUINT32) (specs)) >> (0 ? 31:28)) & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1)))))) );
351         pixelPipes             = (((((gctUINT32) (specs)) >> (0 ? 27:25)) & ((gctUINT32) ((((1 ? 27:25) - (0 ? 27:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:25) - (0 ? 27:25) + 1)))))) );
352
353         /* Read gcChipSpecs2 register. */
354         gcmkONERROR(
355             gckOS_ReadRegisterEx(Os, Core,
356                                  0x00080,
357                                  &specs2));
358
359         instructionCount       = (((((gctUINT32) (specs2)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) );
360         numConstants           = (((((gctUINT32) (specs2)) >> (0 ? 31:16)) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1)))))) );
361         bufferSize             = (((((gctUINT32) (specs2)) >> (0 ? 7:0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1)))))) );
362
363         /* Read gcChipSpecs3 register. */
364         gcmkONERROR(
365             gckOS_ReadRegisterEx(Os, Core,
366                                  0x0008C,
367                                  &specs3));
368
369         varyingsCount          = (((((gctUINT32) (specs3)) >> (0 ? 8:4)) & ((gctUINT32) ((((1 ? 8:4) - (0 ? 8:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:4) - (0 ? 8:4) + 1)))))) );
370     }
371
372     /* Get the number of pixel pipes. */
373     Identity->pixelPipes = gcmMAX(pixelPipes, 1);
374
375     /* Get the stream count. */
376     Identity->streamCount = (streamCount != 0)
377                           ? streamCount
378                           : (Identity->chipModel >= gcv1000) ? 4 : 1;
379
380     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
381                    "Specs: streamCount=%u%s",
382                    Identity->streamCount,
383                    (streamCount == 0) ? " (default)" : "");
384
385     /* Get the vertex output buffer size. */
386     Identity->vertexOutputBufferSize = (vertexOutputBufferSize != 0)
387                                      ? 1 << vertexOutputBufferSize
388                                      : (Identity->chipModel == gcv400)
389                                        ? (Identity->chipRevision < 0x4000) ? 512
390                                        : (Identity->chipRevision < 0x4200) ? 256
391                                        : 128
392                                      : (Identity->chipModel == gcv530)
393                                        ? (Identity->chipRevision < 0x4200) ? 512
394                                        : 128
395                                      : 512;
396
397     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
398                    "Specs: vertexOutputBufferSize=%u%s",
399                    Identity->vertexOutputBufferSize,
400                    (vertexOutputBufferSize == 0) ? " (default)" : "");
401
402     /* Get the maximum number of threads. */
403     Identity->threadCount = (threadCount != 0)
404                           ? 1 << threadCount
405                           : (Identity->chipModel == gcv400) ? 64
406                           : (Identity->chipModel == gcv500) ? 128
407                           : (Identity->chipModel == gcv530) ? 128
408                           : 256;
409
410     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
411                    "Specs: threadCount=%u%s",
412                    Identity->threadCount,
413                    (threadCount == 0) ? " (default)" : "");
414
415     /* Get the number of shader cores. */
416     Identity->shaderCoreCount = (shaderCoreCount != 0)
417                               ? shaderCoreCount
418                               : (Identity->chipModel >= gcv1000) ? 2
419                               : 1;
420     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
421                    "Specs: shaderCoreCount=%u%s",
422                    Identity->shaderCoreCount,
423                    (shaderCoreCount == 0) ? " (default)" : "");
424
425     /* Get the vertex cache size. */
426     Identity->vertexCacheSize = (vertexCacheSize != 0)
427                               ? vertexCacheSize
428                               : 8;
429     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
430                    "Specs: vertexCacheSize=%u%s",
431                    Identity->vertexCacheSize,
432                    (vertexCacheSize == 0) ? " (default)" : "");
433
434     /* Get the maximum number of temporary registers. */
435     Identity->registerMax = (registerMax != 0)
436         /* Maximum of registerMax/4 registers are accessible to 1 shader */
437                           ? 1 << registerMax
438                           : (Identity->chipModel == gcv400) ? 32
439                           : 64;
440     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
441                    "Specs: registerMax=%u%s",
442                    Identity->registerMax,
443                    (registerMax == 0) ? " (default)" : "");
444
445     /* Get the instruction count. */
446     Identity->instructionCount = (instructionCount == 0) ? 256
447                                : (instructionCount == 1) ? 1024
448                                : (instructionCount == 2) ? 2048
449                                : (instructionCount == 0xFF) ? 512
450                                : 256;
451
452     if (Identity->instructionCount == 256)
453     {
454         if ((Identity->chipModel == gcv2000 && Identity->chipRevision == 0x5108)
455         ||  Identity->chipModel == gcv880)
456         {
457             Identity->instructionCount = 512;
458         }
459     }
460
461     if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))))
462     {
463         Identity->instructionCount = 512;
464     }
465
466     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
467                    "Specs: instructionCount=%u%s",
468                    Identity->instructionCount,
469                    (instructionCount == 0) ? " (default)" : "");
470
471     /* Get the number of constants. */
472     Identity->numConstants = (numConstants == 0) ? 168 : numConstants;
473
474     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
475                    "Specs: numConstants=%u%s",
476                    Identity->numConstants,
477                    (numConstants == 0) ? " (default)" : "");
478
479     /* Get the buffer size. */
480     Identity->bufferSize = bufferSize;
481
482     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
483                    "Specs: bufferSize=%u%s",
484                    Identity->bufferSize,
485                    (bufferSize == 0) ? " (default)" : "");
486
487
488      if (varyingsCount != 0)
489      {
490          /* Bug 4480. */
491          /*Identity->varyingsCount = varyingsCount;*/
492          Identity->varyingsCount = 12;
493      }
494      else if (((((gctUINT32) (Identity->chipMinorFeatures1)) >> (0 ? 23:23) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))))
495      {
496          Identity->varyingsCount = 12;
497      }
498      else
499      {
500          Identity->varyingsCount = 8;
501      }
502
503      /* For some cores, it consumes two varying for position, so the max varying vectors should minus one. */
504      if ((Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5222) ||
505          (Identity->chipModel == gcv4000 && Identity->chipRevision == 0x5208) ||
506          ((Identity->chipModel == gcv2100 || Identity->chipModel == gcv2000) && Identity->chipRevision == 0x5108) ||
507          (Identity->chipModel == gcv880 && (Identity->chipRevision == 0x5107 || Identity->chipRevision == 0x5106)))
508      {
509          Identity->varyingsCount -= 1;
510      }
511
512     /* Success. */
513     gcmkFOOTER();
514     return gcvSTATUS_OK;
515
516 OnError:
517     /* Return the status. */
518     gcmkFOOTER();
519     return status;
520 }
521
522 #if gcdPOWEROFF_TIMEOUT
523 void
524 _PowerTimerFunction(
525     gctPOINTER Data
526     )
527 {
528     gckHARDWARE hardware = (gckHARDWARE)Data;
529     gcmkVERIFY_OK(
530         gckHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
531 }
532 #endif
533
534 static gceSTATUS
535 _VerifyDMA(
536     IN gckOS Os,
537     IN gceCORE Core,
538     gctUINT32_PTR Address1,
539     gctUINT32_PTR Address2,
540     gctUINT32_PTR State1,
541     gctUINT32_PTR State2
542     )
543 {
544     gceSTATUS status;
545     gctUINT32 i;
546
547     gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State1));
548     gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address1));
549
550     for (i = 0; i < 500; i += 1)
551     {
552         gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State2));
553         gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address2));
554
555         if (*Address1 != *Address2)
556         {
557             break;
558         }
559
560         if (*State1 != *State2)
561         {
562             break;
563         }
564     }
565
566 OnError:
567     return status;
568 }
569
570 static gceSTATUS
571 _DumpDebugRegisters(
572     IN gckOS Os,
573     IN gceCORE Core,
574     IN gcsiDEBUG_REGISTERS_PTR Descriptor
575     )
576 {
577     gceSTATUS status = gcvSTATUS_OK;
578     gctUINT32 select;
579     gctUINT32 data = 0;
580     gctUINT i;
581
582     gcmkHEADER_ARG("Os=0x%X Descriptor=0x%X", Os, Descriptor);
583
584     gcmkPRINT_N(4, "    %s debug registers:\n", Descriptor->module);
585
586     for (i = 0; i < Descriptor->count; i += 1)
587     {
588         select = i << Descriptor->shift;
589
590         gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
591 #if gcdFPGA_BUILD
592         gcmkONERROR(gckOS_Delay(Os, 1000));
593 #endif
594         gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
595
596         gcmkPRINT_N(12, "      [0x%02X] 0x%08X\n", i, data);
597     }
598
599     select = 0xF << Descriptor->shift;
600
601     for (i = 0; i < 500; i += 1)
602     {
603         gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
604 #if gcdFPGA_BUILD
605         gcmkONERROR(gckOS_Delay(Os, 1000));
606 #endif
607         gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
608
609         if (data == Descriptor->signature)
610         {
611             break;
612         }
613     }
614
615     if (i == 500)
616     {
617         gcmkPRINT_N(4, "      failed to obtain the signature (read 0x%08X).\n", data);
618     }
619     else
620     {
621         gcmkPRINT_N(8, "      signature = 0x%08X (%d read attempt(s))\n", data, i + 1);
622     }
623
624 OnError:
625     /* Return the error. */
626     gcmkFOOTER();
627     return status;
628 }
629
630 static gceSTATUS
631 _IsGPUPresent(
632     IN gckHARDWARE Hardware
633     )
634 {
635     gceSTATUS status;
636     gcsHAL_QUERY_CHIP_IDENTITY identity;
637     gctUINT32 control;
638
639     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
640
641     /* Verify the arguments. */
642     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
643
644     gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
645                                      Hardware->core,
646                                      0x00000,
647                                      &control));
648
649     control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
650     control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
651
652     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
653                                       Hardware->core,
654                                       0x00000,
655                                       control));
656
657     /* Identify the hardware. */
658     gcmkONERROR(_IdentifyHardware(Hardware->os,
659                                   Hardware->core,
660                                   &identity));
661
662     /* Check if these are the same values as saved before. */
663     if ((Hardware->identity.chipModel          != identity.chipModel)
664     ||  (Hardware->identity.chipRevision       != identity.chipRevision)
665     ||  (Hardware->identity.chipFeatures       != identity.chipFeatures)
666     ||  (Hardware->identity.chipMinorFeatures  != identity.chipMinorFeatures)
667     ||  (Hardware->identity.chipMinorFeatures1 != identity.chipMinorFeatures1)
668     ||  (Hardware->identity.chipMinorFeatures2 != identity.chipMinorFeatures2)
669     )
670     {
671         gcmkPRINT("[galcore]: GPU is not present.");
672         gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
673     }
674
675     /* Success. */
676     gcmkFOOTER_NO();
677     return gcvSTATUS_OK;
678
679 OnError:
680     /* Return the error. */
681     gcmkFOOTER();
682     return status;
683 }
684
685 gceSTATUS
686 _FlushCache(
687     gckHARDWARE Hardware,
688     gckCOMMAND Command
689     )
690 {
691     gceSTATUS status;
692     gctSIZE_T bytes, requested;
693     gctPOINTER buffer;
694
695     /* Get the size of the flush command. */
696     gcmkONERROR(gckHARDWARE_Flush(Hardware,
697                                   gcvFLUSH_ALL,
698                                   gcvNULL,
699                                   &requested));
700
701     /* Reserve space in the command queue. */
702     gcmkONERROR(gckCOMMAND_Reserve(Command,
703                                    requested,
704                                    &buffer,
705                                    &bytes));
706
707     /* Append a flush. */
708     gcmkONERROR(gckHARDWARE_Flush(
709         Hardware, gcvFLUSH_ALL, buffer, &bytes
710         ));
711
712     /* Execute the command queue. */
713     gcmkONERROR(gckCOMMAND_Execute(Command, requested));
714
715     return gcvSTATUS_OK;
716
717 OnError:
718     return status;
719 }
720
721 /******************************************************************************\
722 ****************************** gckHARDWARE API code *****************************
723 \******************************************************************************/
724
725 /*******************************************************************************
726 **
727 **  gckHARDWARE_Construct
728 **
729 **  Construct a new gckHARDWARE object.
730 **
731 **  INPUT:
732 **
733 **      gckOS Os
734 **          Pointer to an initialized gckOS object.
735 **
736 **      gceCORE Core
737 **          Specified core.
738 **
739 **  OUTPUT:
740 **
741 **      gckHARDWARE * Hardware
742 **          Pointer to a variable that will hold the pointer to the gckHARDWARE
743 **          object.
744 */
745 gceSTATUS
746 gckHARDWARE_Construct(
747     IN gckOS Os,
748     IN gceCORE Core,
749     OUT gckHARDWARE * Hardware
750     )
751 {
752     gceSTATUS status;
753     gckHARDWARE hardware = gcvNULL;
754     gctUINT16 data = 0xff00;
755     gctUINT32 axi_ot;
756     gctPOINTER pointer = gcvNULL;
757
758     gcmkHEADER_ARG("Os=0x%x", Os);
759
760     /* Verify the arguments. */
761     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
762     gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
763
764     /* Enable the GPU. */
765     gcmkONERROR(gckOS_SetGPUPower(Os, Core, gcvTRUE, gcvTRUE));
766     gcmkONERROR(gckOS_WriteRegisterEx(Os,
767                                       Core,
768                                       0x00000,
769                                       0x00000900));
770
771     /* Allocate the gckHARDWARE object. */
772     gcmkONERROR(gckOS_Allocate(Os,
773                                gcmSIZEOF(struct _gckHARDWARE),
774                                &pointer));
775
776     hardware = (gckHARDWARE) pointer;
777
778     /* Initialize the gckHARDWARE object. */
779     hardware->object.type = gcvOBJ_HARDWARE;
780     hardware->os          = Os;
781     hardware->core        = Core;
782
783     /* Identify the hardware. */
784     gcmkONERROR(_IdentifyHardware(Os, Core, &hardware->identity));
785
786     /* Determine the hardware type */
787     switch (hardware->identity.chipModel)
788     {
789     case gcv350:
790     case gcv355:
791         hardware->type = gcvHARDWARE_VG;
792         break;
793
794     case gcv300:
795     case gcv320:
796     case gcv420:
797         hardware->type = gcvHARDWARE_2D;
798         /*set outstanding limit*/
799         gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
800         axi_ot = (axi_ot & (~0xFF)) | 0x10;
801         gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
802         break;
803
804     default:
805         hardware->type = gcvHARDWARE_3D;
806         if(hardware->identity.chipModel == gcv880)
807         {
808             /*set outstanding limit*/
809             gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
810             axi_ot = (axi_ot & (~0xFF)) | 0x10;
811             gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
812         }
813
814         if ((((((gctUINT32) (hardware->identity.chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ))
815         {
816             hardware->type = (gceHARDWARE_TYPE) (hardware->type | gcvHARDWARE_2D);
817         }
818     }
819
820     hardware->powerBaseAddress
821         = ((hardware->identity.chipModel   == gcv300)
822         && (hardware->identity.chipRevision < 0x2000))
823             ? 0x0100
824             : 0x0000;
825
826     /* _ResetGPU need powerBaseAddress. */
827     status = _ResetGPU(hardware, Os, Core);
828
829     if (status != gcvSTATUS_OK)
830     {
831         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
832             "_ResetGPU failed: status=%d\n", status);
833     }
834
835     hardware->powerMutex = gcvNULL;
836
837     hardware->mmuVersion
838         = (((((gctUINT32) (hardware->identity.chipMinorFeatures1)) >> (0 ? 28:28)) & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))) );
839
840     /* Determine whether bug fixes #1 are present. */
841     hardware->extraEventStates = ((((gctUINT32) (hardware->identity.chipMinorFeatures1)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))));
842
843     /* Check if big endian */
844     hardware->bigEndian = (*(gctUINT8 *)&data == 0xff);
845
846     /* Initialize the fast clear. */
847     gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
848
849 #if !gcdENABLE_128B_MERGE
850
851     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))))))))
852     {
853         /* 128B merge is turned on by default. Disable it. */
854         gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, 0));
855     }
856
857 #endif
858
859     /* Set power state to ON. */
860     hardware->chipPowerState  = gcvPOWER_ON;
861     hardware->clockState      = gcvTRUE;
862     hardware->powerState      = gcvTRUE;
863     hardware->lastWaitLink    = ~0U;
864     hardware->globalSemaphore = gcvNULL;
865 #if gcdENABLE_FSCALE_VAL_ADJUST
866     hardware->powerOnFscaleVal = 64;
867 #endif
868
869     gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
870     gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
871     hardware->startIsr = gcvNULL;
872     hardware->stopIsr = gcvNULL;
873
874 #if gcdPOWEROFF_TIMEOUT
875     hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
876
877     gcmkVERIFY_OK(gckOS_CreateTimer(Os,
878                                     _PowerTimerFunction,
879                                     (gctPOINTER)hardware,
880                                     &hardware->powerOffTimer));
881 #endif
882
883     gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
884
885 #if gcdLINK_QUEUE_SIZE
886     hardware->linkQueue.front = 0;
887     hardware->linkQueue.rear = 0;
888     hardware->linkQueue.count = 0;
889 #endif
890
891     /* Enable power management by default. */
892     hardware->powerManagement = gcvTRUE;
893
894     /* Disable profiler by default */
895     hardware->gpuProfiler = gcvFALSE;
896
897     /* Return pointer to the gckHARDWARE object. */
898     *Hardware = hardware;
899
900     /* Success. */
901     gcmkFOOTER_ARG("*Hardware=0x%x", *Hardware);
902     return gcvSTATUS_OK;
903
904 OnError:
905     /* Roll back. */
906     if (hardware != gcvNULL)
907     {
908         /* Turn off the power. */
909         gcmkVERIFY_OK(gckOS_SetGPUPower(Os, Core, gcvFALSE, gcvFALSE));
910
911         if (hardware->globalSemaphore != gcvNULL)
912         {
913             /* Destroy the global semaphore. */
914             gcmkVERIFY_OK(gckOS_DestroySemaphore(Os,
915                                                  hardware->globalSemaphore));
916         }
917
918         if (hardware->powerMutex != gcvNULL)
919         {
920             /* Destroy the power mutex. */
921             gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex));
922         }
923
924 #if gcdPOWEROFF_TIMEOUT
925         if (hardware->powerOffTimer != gcvNULL)
926         {
927             gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
928             gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
929         }
930 #endif
931
932         if (hardware->pageTableDirty != gcvNULL)
933         {
934             gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
935         }
936
937         gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware));
938     }
939
940     /* Return the status. */
941     gcmkFOOTER();
942     return status;
943 }
944
945 /*******************************************************************************
946 **
947 **  gckHARDWARE_Destroy
948 **
949 **  Destroy an gckHARDWARE object.
950 **
951 **  INPUT:
952 **
953 **      gckHARDWARE Hardware
954 **          Pointer to the gckHARDWARE object that needs to be destroyed.
955 **
956 **  OUTPUT:
957 **
958 **      Nothing.
959 */
960 gceSTATUS
961 gckHARDWARE_Destroy(
962     IN gckHARDWARE Hardware
963     )
964 {
965     gceSTATUS status;
966
967     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
968
969     /* Verify the arguments. */
970     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
971
972     /* Destroy the power semaphore. */
973     gcmkVERIFY_OK(gckOS_DestroySemaphore(Hardware->os,
974                                          Hardware->globalSemaphore));
975
976     /* Destroy the power mutex. */
977     gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerMutex));
978
979 #if gcdPOWEROFF_TIMEOUT
980     gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
981     gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
982 #endif
983
984     gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
985
986     /* Mark the object as unknown. */
987     Hardware->object.type = gcvOBJ_UNKNOWN;
988
989     /* Free the object. */
990     gcmkONERROR(gcmkOS_SAFE_FREE(Hardware->os, Hardware));
991
992     /* Success. */
993     gcmkFOOTER_NO();
994     return gcvSTATUS_OK;
995
996 OnError:
997     gcmkFOOTER();
998     return status;
999 }
1000
1001 /*******************************************************************************
1002 **
1003 **  gckHARDWARE_GetType
1004 **
1005 **  Get the hardware type.
1006 **
1007 **  INPUT:
1008 **
1009 **      gckHARDWARE Harwdare
1010 **          Pointer to an gckHARDWARE object.
1011 **
1012 **  OUTPUT:
1013 **
1014 **      gceHARDWARE_TYPE * Type
1015 **          Pointer to a variable that receives the type of hardware object.
1016 */
1017 gceSTATUS
1018 gckHARDWARE_GetType(
1019     IN gckHARDWARE Hardware,
1020     OUT gceHARDWARE_TYPE * Type
1021     )
1022 {
1023     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
1024     gcmkVERIFY_ARGUMENT(Type != gcvNULL);
1025
1026     *Type = Hardware->type;
1027
1028     gcmkFOOTER_ARG("*Type=%d", *Type);
1029     return gcvSTATUS_OK;
1030 }
1031
1032 /*******************************************************************************
1033 **
1034 **  gckHARDWARE_InitializeHardware
1035 **
1036 **  Initialize the hardware.
1037 **
1038 **  INPUT:
1039 **
1040 **      gckHARDWARE Hardware
1041 **          Pointer to the gckHARDWARE object.
1042 **
1043 **  OUTPUT:
1044 **
1045 **      Nothing.
1046 */
1047 gceSTATUS
1048 gckHARDWARE_InitializeHardware(
1049     IN gckHARDWARE Hardware
1050     )
1051 {
1052     gceSTATUS status;
1053     gctUINT32 baseAddress;
1054     gctUINT32 chipRev;
1055     gctUINT32 control;
1056
1057     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
1058
1059     /* Verify the arguments. */
1060     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1061
1062     /* Read the chip revision register. */
1063     gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
1064                                      Hardware->core,
1065                                      0x00024,
1066                                      &chipRev));
1067
1068     if (chipRev != Hardware->identity.chipRevision)
1069     {
1070         /* Chip is not there! */
1071         gcmkONERROR(gcvSTATUS_CONTEXT_LOSSED);
1072     }
1073
1074     /* Disable isolate GPU bit. */
1075     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1076                                       Hardware->core,
1077                                       0x00000,
1078                                       ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)))));
1079
1080     gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
1081                                      Hardware->core,
1082                                      0x00000,
1083                                      &control));
1084
1085     /* Enable debug register. */
1086     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1087                                       Hardware->core,
1088                                       0x00000,
1089                                       ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
1090
1091     /* Reset memory counters. */
1092     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1093                                       Hardware->core,
1094                                       0x0003C,
1095                                       ~0U));
1096
1097     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1098                                       Hardware->core,
1099                                       0x0003C,
1100                                       0));
1101
1102     /* Get the system's physical base address. */
1103     gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
1104
1105     /* Program the base addesses. */
1106     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1107                                       Hardware->core,
1108                                       0x0041C,
1109                                       baseAddress));
1110
1111     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1112                                       Hardware->core,
1113                                       0x00418,
1114                                       baseAddress));
1115
1116     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1117                                       Hardware->core,
1118                                       0x00428,
1119                                       baseAddress));
1120
1121     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1122                                       Hardware->core,
1123                                       0x00420,
1124                                       baseAddress));
1125
1126     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1127                                       Hardware->core,
1128                                       0x00424,
1129                                       baseAddress));
1130
1131 #if !VIVANTE_PROFILER
1132     {
1133         gctUINT32 data;
1134
1135         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
1136                                          Hardware->core,
1137                                          Hardware->powerBaseAddress +
1138                                          0x00100,
1139                                          &data));
1140
1141         /* Enable clock gating. */
1142         data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
1143
1144         if ((Hardware->identity.chipRevision == 0x4301)
1145         ||  (Hardware->identity.chipRevision == 0x4302)
1146         )
1147         {
1148             /* Disable stall module level clock gating for 4.3.0.1 and 4.3.0.2
1149             ** revisions. */
1150             data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
1151         }
1152
1153         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1154                                           Hardware->core,
1155                                           Hardware->powerBaseAddress
1156                                           + 0x00100,
1157                                           data));
1158
1159 #ifndef VIVANTE_NO_3D
1160         /* Disable PE clock gating on revs < 5.0 when HZ is present without a
1161         ** bug fix. */
1162         if ((Hardware->identity.chipRevision < 0x5000)
1163         &&  ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 9:9) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))))
1164         &&  ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))))
1165         )
1166         {
1167             gcmkONERROR(
1168                 gckOS_ReadRegisterEx(Hardware->os,
1169                                      Hardware->core,
1170                                      Hardware->powerBaseAddress
1171                                      + 0x00104,
1172                                      &data));
1173
1174             /* Disable PE clock gating. */
1175             data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
1176
1177             gcmkONERROR(
1178                 gckOS_WriteRegisterEx(Hardware->os,
1179                                       Hardware->core,
1180                                       Hardware->powerBaseAddress
1181                                       + 0x00104,
1182                                       data));
1183         }
1184
1185 #endif
1186     }
1187 #endif
1188
1189     /* Special workaround for this core
1190     ** Make sure pulse eater kicks in only when SH is idle */
1191     if (Hardware->identity.chipModel == gcv4000 &&
1192         Hardware->identity.chipRevision == 0x5208)
1193     {
1194                 gcmkONERROR(
1195             gckOS_WriteRegisterEx(Hardware->os,
1196                                   Hardware->core,
1197                                   0x0010C,
1198                                   ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23)))));
1199     }
1200
1201     if ((gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) == gcvFALSE)
1202      || (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI2) && (Hardware->identity.chipRevision < 0x5422))
1203     )
1204     {
1205         gctUINT32 data;
1206
1207         gcmkONERROR(
1208             gckOS_ReadRegisterEx(Hardware->os,
1209                                  Hardware->core,
1210                                  Hardware->powerBaseAddress
1211                                  + 0x00104,
1212                                  &data));
1213
1214
1215         data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15)));
1216
1217
1218         gcmkONERROR(
1219             gckOS_WriteRegisterEx(Hardware->os,
1220                                   Hardware->core,
1221                                   Hardware->powerBaseAddress
1222                                   + 0x00104,
1223                                   data));
1224     }
1225
1226     /* Special workaround for this core
1227     ** Make sure FE and TX are on different buses */
1228     if ((Hardware->identity.chipModel == gcv2000)
1229     &&  (Hardware->identity.chipRevision  == 0x5108))
1230     {
1231         gctUINT32 data;
1232
1233         gcmkONERROR(
1234             gckOS_ReadRegisterEx(Hardware->os,
1235                                  Hardware->core,
1236                                  0x00480,
1237                                  &data));
1238
1239         /* Set FE bus to one, TX bus to zero */
1240         data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
1241         data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
1242
1243         gcmkONERROR(
1244             gckOS_WriteRegisterEx(Hardware->os,
1245                                   Hardware->core,
1246                                   0x00480,
1247                                   data));
1248     }
1249
1250     /* Test if MMU is initialized. */
1251     if ((Hardware->kernel      != gcvNULL)
1252     &&  (Hardware->kernel->mmu != gcvNULL)
1253     )
1254     {
1255         /* Reset MMU. */
1256         if (Hardware->mmuVersion == 0)
1257         {
1258             gcmkONERROR(
1259                     gckHARDWARE_SetMMU(Hardware,
1260                         Hardware->kernel->mmu->pageTableLogical));
1261         }
1262     }
1263
1264     if (Hardware->identity.chipModel >= gcv400
1265     &&  Hardware->identity.chipModel != gcv420
1266     &&  (((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 15:15) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) != gcvTRUE)
1267     )
1268     {
1269                 gctUINT32 data;
1270
1271         gcmkONERROR(
1272             gckOS_ReadRegisterEx(Hardware->os,
1273                                  Hardware->core,
1274                                  Hardware->powerBaseAddress
1275                                  + 0x00104,
1276                                  &data));
1277
1278         /* Disable PA clock gating. */
1279         data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
1280
1281         gcmkONERROR(
1282             gckOS_WriteRegisterEx(Hardware->os,
1283                                   Hardware->core,
1284                                   Hardware->powerBaseAddress
1285                                   + 0x00104,
1286                                   data));
1287     }
1288
1289 #if gcdHZ_L2_DISALBE
1290     /* Disable HZ-L2. */
1291     if (((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) == gcvTRUE ||
1292             ((((gctUINT32) (Hardware->identity.chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) == gcvTRUE)
1293     {
1294                 gctUINT32 data;
1295
1296         gcmkONERROR(
1297             gckOS_ReadRegisterEx(Hardware->os,
1298                                  Hardware->core,
1299                                  0x00414,
1300                                  &data));
1301
1302         data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)));
1303
1304         gcmkONERROR(
1305             gckOS_WriteRegisterEx(Hardware->os,
1306                                   Hardware->core,
1307                                   0x00414,
1308                                   data));
1309     }
1310 #endif
1311
1312     /* Limit 2D outstanding request. */
1313     if(Hardware->identity.chipModel == gcv880)
1314     {
1315         gctUINT32 axi_ot;
1316         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &axi_ot));
1317         axi_ot = (axi_ot & (~0xFF)) | 0x10;
1318         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00414, axi_ot));
1319     }
1320
1321     if ((Hardware->identity.chipModel == gcv320)
1322         && ((Hardware->identity.chipRevision == 0x5007)
1323         || (Hardware->identity.chipRevision == 0x5220)))
1324     {
1325                 gctUINT32 data;
1326
1327         gcmkONERROR(
1328             gckOS_ReadRegisterEx(Hardware->os,
1329                                  Hardware->core,
1330                                  0x0002C,
1331                                  &data));
1332         if (data != 33956864)
1333         {
1334             gcmkONERROR(
1335                 gckOS_ReadRegisterEx(Hardware->os,
1336                                      Hardware->core,
1337                                      0x00414,
1338                                      &data));
1339
1340             data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.chipRevision == 0x5220 ? 8 : (Hardware->identity.chipRevision == 0x5007 ? 16 : 0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
1341
1342             gcmkONERROR(
1343                 gckOS_WriteRegisterEx(Hardware->os,
1344                                       Hardware->core,
1345                                       0x00414,
1346                                       data));
1347         }
1348     }
1349
1350     /* Update GPU AXI cache atttribute. */
1351     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
1352                                       Hardware->core,
1353                                       0x00008,
1354                                       0x00002200));
1355
1356     /* Success. */
1357     gcmkFOOTER_NO();
1358     return gcvSTATUS_OK;
1359
1360 OnError:
1361     /* Return the error. */
1362     gcmkFOOTER();
1363     return status;
1364 }
1365
1366 /*******************************************************************************
1367 **
1368 **  gckHARDWARE_QueryMemory
1369 **
1370 **  Query the amount of memory available on the hardware.
1371 **
1372 **  INPUT:
1373 **
1374 **      gckHARDWARE Hardware
1375 **          Pointer to the gckHARDWARE object.
1376 **
1377 **  OUTPUT:
1378 **
1379 **      gctSIZE_T * InternalSize
1380 **          Pointer to a variable that will hold the size of the internal video
1381 **          memory in bytes.  If 'InternalSize' is gcvNULL, no information of the
1382 **          internal memory will be returned.
1383 **
1384 **      gctUINT32 * InternalBaseAddress
1385 **          Pointer to a variable that will hold the hardware's base address for
1386 **          the internal video memory.  This pointer cannot be gcvNULL if
1387 **          'InternalSize' is also non-gcvNULL.
1388 **
1389 **      gctUINT32 * InternalAlignment
1390 **          Pointer to a variable that will hold the hardware's base address for
1391 **          the internal video memory.  This pointer cannot be gcvNULL if
1392 **          'InternalSize' is also non-gcvNULL.
1393 **
1394 **      gctSIZE_T * ExternalSize
1395 **          Pointer to a variable that will hold the size of the external video
1396 **          memory in bytes.  If 'ExternalSize' is gcvNULL, no information of the
1397 **          external memory will be returned.
1398 **
1399 **      gctUINT32 * ExternalBaseAddress
1400 **          Pointer to a variable that will hold the hardware's base address for
1401 **          the external video memory.  This pointer cannot be gcvNULL if
1402 **          'ExternalSize' is also non-gcvNULL.
1403 **
1404 **      gctUINT32 * ExternalAlignment
1405 **          Pointer to a variable that will hold the hardware's base address for
1406 **          the external video memory.  This pointer cannot be gcvNULL if
1407 **          'ExternalSize' is also non-gcvNULL.
1408 **
1409 **      gctUINT32 * HorizontalTileSize
1410 **          Number of horizontal pixels per tile.  If 'HorizontalTileSize' is
1411 **          gcvNULL, no horizontal pixel per tile will be returned.
1412 **
1413 **      gctUINT32 * VerticalTileSize
1414 **          Number of vertical pixels per tile.  If 'VerticalTileSize' is
1415 **          gcvNULL, no vertical pixel per tile will be returned.
1416 */
1417 gceSTATUS
1418 gckHARDWARE_QueryMemory(
1419     IN gckHARDWARE Hardware,
1420     OUT gctSIZE_T * InternalSize,
1421     OUT gctUINT32 * InternalBaseAddress,
1422     OUT gctUINT32 * InternalAlignment,
1423     OUT gctSIZE_T * ExternalSize,
1424     OUT gctUINT32 * ExternalBaseAddress,
1425     OUT gctUINT32 * ExternalAlignment,
1426     OUT gctUINT32 * HorizontalTileSize,
1427     OUT gctUINT32 * VerticalTileSize
1428     )
1429 {
1430     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
1431
1432     /* Verify the arguments. */
1433     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1434
1435     if (InternalSize != gcvNULL)
1436     {
1437         /* No internal memory. */
1438         *InternalSize = 0;
1439     }
1440
1441     if (ExternalSize != gcvNULL)
1442     {
1443         /* No external memory. */
1444         *ExternalSize = 0;
1445     }
1446
1447     if (HorizontalTileSize != gcvNULL)
1448     {
1449         /* 4x4 tiles. */
1450         *HorizontalTileSize = 4;
1451     }
1452
1453     if (VerticalTileSize != gcvNULL)
1454     {
1455         /* 4x4 tiles. */
1456         *VerticalTileSize = 4;
1457     }
1458
1459     /* Success. */
1460     gcmkFOOTER_ARG("*InternalSize=%lu *InternalBaseAddress=0x%08x "
1461                    "*InternalAlignment=0x%08x *ExternalSize=%lu "
1462                    "*ExternalBaseAddress=0x%08x *ExtenalAlignment=0x%08x "
1463                    "*HorizontalTileSize=%u *VerticalTileSize=%u",
1464                    gcmOPT_VALUE(InternalSize),
1465                    gcmOPT_VALUE(InternalBaseAddress),
1466                    gcmOPT_VALUE(InternalAlignment),
1467                    gcmOPT_VALUE(ExternalSize),
1468                    gcmOPT_VALUE(ExternalBaseAddress),
1469                    gcmOPT_VALUE(ExternalAlignment),
1470                    gcmOPT_VALUE(HorizontalTileSize),
1471                    gcmOPT_VALUE(VerticalTileSize));
1472     return gcvSTATUS_OK;
1473 }
1474
1475 /*******************************************************************************
1476 **
1477 **  gckHARDWARE_QueryChipIdentity
1478 **
1479 **  Query the identity of the hardware.
1480 **
1481 **  INPUT:
1482 **
1483 **      gckHARDWARE Hardware
1484 **          Pointer to the gckHARDWARE object.
1485 **
1486 **  OUTPUT:
1487 **
1488 **      gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
1489 **          Pointer to the identity structure.
1490 **
1491 */
1492 gceSTATUS
1493 gckHARDWARE_QueryChipIdentity(
1494     IN gckHARDWARE Hardware,
1495     OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
1496     )
1497 {
1498     gctUINT32 features;
1499
1500     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
1501
1502     /* Verify the arguments. */
1503     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1504     gcmkVERIFY_ARGUMENT(Identity != gcvNULL);
1505
1506     /* Return chip model and revision. */
1507     Identity->chipModel = Hardware->identity.chipModel;
1508     Identity->chipRevision = Hardware->identity.chipRevision;
1509
1510     /* Return feature set. */
1511     features = Hardware->identity.chipFeatures;
1512
1513     if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
1514     {
1515         /* Override fast clear by command line. */
1516         features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Hardware->allowFastClear) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
1517     }
1518
1519     if ((((((gctUINT32) (features)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ))
1520     {
1521         /* Override compression by command line. */
1522         features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (Hardware->allowCompression) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
1523     }
1524
1525     /* Mark 2D pipe as available for GC500.0 through GC500.2 and GC300,
1526     ** since they did not have this bit. */
1527     if (((Hardware->identity.chipModel == gcv500) && (Hardware->identity.chipRevision <= 2))
1528     ||   (Hardware->identity.chipModel == gcv300)
1529     )
1530     {
1531         features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
1532     }
1533
1534     Identity->chipFeatures = features;
1535
1536     /* Return minor features. */
1537     Identity->chipMinorFeatures  = Hardware->identity.chipMinorFeatures;
1538     Identity->chipMinorFeatures1 = Hardware->identity.chipMinorFeatures1;
1539     Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2;
1540     Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3;
1541     Identity->chipMinorFeatures4 = Hardware->identity.chipMinorFeatures4;
1542
1543     /* Return chip specs. */
1544     Identity->streamCount            = Hardware->identity.streamCount;
1545     Identity->registerMax            = Hardware->identity.registerMax;
1546     Identity->threadCount            = Hardware->identity.threadCount;
1547     Identity->shaderCoreCount        = Hardware->identity.shaderCoreCount;
1548     Identity->vertexCacheSize        = Hardware->identity.vertexCacheSize;
1549     Identity->vertexOutputBufferSize = Hardware->identity.vertexOutputBufferSize;
1550     Identity->pixelPipes             = Hardware->identity.pixelPipes;
1551     Identity->instructionCount       = Hardware->identity.instructionCount;
1552     Identity->numConstants           = Hardware->identity.numConstants;
1553     Identity->bufferSize             = Hardware->identity.bufferSize;
1554     Identity->varyingsCount          = Hardware->identity.varyingsCount;
1555     Identity->superTileMode          = Hardware->identity.superTileMode;
1556
1557     /* Success. */
1558     gcmkFOOTER_NO();
1559     return gcvSTATUS_OK;
1560 }
1561
1562 /*******************************************************************************
1563 **
1564 **  gckHARDWARE_SplitMemory
1565 **
1566 **  Split a hardware specific memory address into a pool and offset.
1567 **
1568 **  INPUT:
1569 **
1570 **      gckHARDWARE Hardware
1571 **          Pointer to the gckHARDWARE object.
1572 **
1573 **      gctUINT32 Address
1574 **          Address in hardware specific format.
1575 **
1576 **  OUTPUT:
1577 **
1578 **      gcePOOL * Pool
1579 **          Pointer to a variable that will hold the pool type for the address.
1580 **
1581 **      gctUINT32 * Offset
1582 **          Pointer to a variable that will hold the offset for the address.
1583 */
1584 gceSTATUS
1585 gckHARDWARE_SplitMemory(
1586     IN gckHARDWARE Hardware,
1587     IN gctUINT32 Address,
1588     OUT gcePOOL * Pool,
1589     OUT gctUINT32 * Offset
1590     )
1591 {
1592     gcmkHEADER_ARG("Hardware=0x%x Addres=0x%08x", Hardware, Address);
1593
1594     /* Verify the arguments. */
1595     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1596     gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
1597     gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
1598
1599     if (Hardware->mmuVersion == 0)
1600     {
1601         /* Dispatch on memory type. */
1602         switch ((((((gctUINT32) (Address)) >> (0 ? 31:31)) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) ))
1603         {
1604         case 0x0:
1605             /* System memory. */
1606             *Pool = gcvPOOL_SYSTEM;
1607             break;
1608
1609         case 0x1:
1610             /* Virtual memory. */
1611             *Pool = gcvPOOL_VIRTUAL;
1612             break;
1613
1614         default:
1615             /* Invalid memory type. */
1616             gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
1617             return gcvSTATUS_INVALID_ARGUMENT;
1618         }
1619
1620         /* Return offset of address. */
1621         *Offset = (((((gctUINT32) (Address)) >> (0 ? 30:0)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1)))))) );
1622     }
1623     else
1624     {
1625         *Pool = gcvPOOL_SYSTEM;
1626         *Offset = Address;
1627     }
1628
1629     /* Success. */
1630     gcmkFOOTER_ARG("*Pool=%d *Offset=0x%08x", *Pool, *Offset);
1631     return gcvSTATUS_OK;
1632 }
1633
1634 /*******************************************************************************
1635 **
1636 **  gckHARDWARE_Execute
1637 **
1638 **  Kickstart the hardware's command processor with an initialized command
1639 **  buffer.
1640 **
1641 **  INPUT:
1642 **
1643 **      gckHARDWARE Hardware
1644 **          Pointer to the gckHARDWARE object.
1645 **
1646 **      gctPOINTER Logical
1647 **          Logical address of command buffer.
1648 **
1649 **      gctSIZE_T Bytes
1650 **          Number of bytes for the prefetch unit (until after the first LINK).
1651 **
1652 **  OUTPUT:
1653 **
1654 **      Nothing.
1655 */
1656 gceSTATUS
1657 gckHARDWARE_Execute(
1658     IN gckHARDWARE Hardware,
1659     IN gctPOINTER Logical,
1660 #ifdef __QNXNTO__
1661     IN gctPOINTER Physical,
1662     IN gctBOOL PhysicalAddresses,
1663 #endif
1664     IN gctSIZE_T Bytes
1665     )
1666 {
1667     gceSTATUS status;
1668     gctUINT32 address = 0, control;
1669
1670     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Bytes=%lu",
1671                    Hardware, Logical, Bytes);
1672
1673     /* Verify the arguments. */
1674     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1675     gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
1676
1677 #ifdef __QNXNTO__
1678     if (PhysicalAddresses && (Hardware->mmuVersion == 0))
1679     {
1680         /* Convert physical into hardware specific address. */
1681         gcmkONERROR(
1682             gckHARDWARE_ConvertPhysical(Hardware, Physical, &address));
1683     }
1684     else
1685     {
1686 #endif
1687     /* Convert logical into hardware specific address. */
1688     gcmkONERROR(
1689         gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
1690 #ifdef __QNXNTO__
1691     }
1692 #endif
1693
1694     /* Enable all events. */
1695     gcmkONERROR(
1696         gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U));
1697
1698     /* Write address register. */
1699     gcmkONERROR(
1700         gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, address));
1701
1702     /* Build control register. */
1703     control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
1704             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
1705
1706     /* Set big endian */
1707     if (Hardware->bigEndian)
1708     {
1709         control |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:20) - (0 ? 21:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ? 21:20) - (0 ? 21:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20)));
1710     }
1711
1712     /* Write control register. */
1713     gcmkONERROR(
1714         gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
1715
1716     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
1717                   "Started command buffer @ 0x%08x",
1718                   address);
1719
1720     /* Success. */
1721     gcmkFOOTER_NO();
1722     return gcvSTATUS_OK;
1723
1724 OnError:
1725     /* Return the status. */
1726     gcmkFOOTER();
1727     return status;
1728 }
1729
1730 /*******************************************************************************
1731 **
1732 **  gckHARDWARE_WaitLink
1733 **
1734 **  Append a WAIT/LINK command sequence at the specified location in the command
1735 **  queue.
1736 **
1737 **  INPUT:
1738 **
1739 **      gckHARDWARE Hardware
1740 **          Pointer to an gckHARDWARE object.
1741 **
1742 **      gctPOINTER Logical
1743 **          Pointer to the current location inside the command queue to append
1744 **          WAIT/LINK command sequence at or gcvNULL just to query the size of the
1745 **          WAIT/LINK command sequence.
1746 **
1747 **      gctUINT32 Offset
1748 **          Offset into command buffer required for alignment.
1749 **
1750 **      gctSIZE_T * Bytes
1751 **          Pointer to the number of bytes available for the WAIT/LINK command
1752 **          sequence.  If 'Logical' is gcvNULL, this argument will be ignored.
1753 **
1754 **  OUTPUT:
1755 **
1756 **      gctSIZE_T * Bytes
1757 **          Pointer to a variable that will receive the number of bytes required
1758 **          by the WAIT/LINK command sequence.  If 'Bytes' is gcvNULL, nothing will
1759 **          be returned.
1760 **
1761 **      gctUINT32 * WaitOffset
1762 **          Pointer to a variable that will receive the offset of the WAIT command
1763 **          from the specified logcial pointer.
1764 **          If 'WaitOffset' is gcvNULL nothing will be returned.
1765 **
1766 **      gctSIZE_T * WaitSize
1767 **          Pointer to a variable that will receive the number of bytes used by
1768 **          the WAIT command.  If 'LinkSize' is gcvNULL nothing will be returned.
1769 */
1770 gceSTATUS
1771 gckHARDWARE_WaitLink(
1772     IN gckHARDWARE Hardware,
1773     IN gctPOINTER Logical,
1774     IN gctUINT32 Offset,
1775     IN OUT gctSIZE_T * Bytes,
1776     OUT gctUINT32 * WaitOffset,
1777     OUT gctSIZE_T * WaitSize
1778     )
1779 {
1780     static const gctUINT waitCount = 200;
1781
1782     gceSTATUS status;
1783     gctUINT32 address;
1784     gctUINT32_PTR logical;
1785     gctSIZE_T bytes;
1786
1787     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu",
1788                    Hardware, Logical, Offset, gcmOPT_VALUE(Bytes));
1789
1790     /* Verify the arguments. */
1791     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1792     gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL));
1793
1794     /* Compute number of bytes required. */
1795 #if gcd6000_SUPPORT
1796     bytes = gcmALIGN(Offset + 96, 8) - Offset;
1797 #else
1798     bytes = gcmALIGN(Offset + 16, 8) - Offset;
1799 #endif
1800
1801     /* Cast the input pointer. */
1802     logical = (gctUINT32_PTR) Logical;
1803
1804     if (logical != gcvNULL)
1805     {
1806         /* Not enough space? */
1807         if (*Bytes < bytes)
1808         {
1809             /* Command queue too small. */
1810             gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
1811         }
1812
1813         /* Convert logical into hardware specific address. */
1814         gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, &address));
1815
1816         /* Store the WAIT/LINK address. */
1817         Hardware->lastWaitLink = address;
1818
1819         /* Append WAIT(count). */
1820         logical[0]
1821             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1822             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (waitCount) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
1823
1824 #if gcd6000_SUPPORT
1825         /* Send FE-PE sempahore token. */
1826         logical[2]
1827             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1828             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
1829             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
1830
1831         logical[3]
1832             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
1833             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
1834
1835         /* Send FE-PE stall token. */
1836         logical[4]
1837             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
1838
1839         logical[5]
1840             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
1841             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
1842
1843         /*************************************************************/
1844         /* Enable chip ID 0. */
1845         logical[6] =
1846             ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1847             | (1 << 0);
1848
1849         /* Send semaphore from FE to ChipID 1. */
1850         logical[8] =
1851               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1852             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
1853             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
1854
1855         logical[9] =
1856               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
1857             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
1858             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
1859
1860         /* Send semaphore from FE to ChipID 1. */
1861         logical[10] =
1862               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
1863
1864         logical[11] =
1865               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
1866             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
1867             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
1868
1869         /*************************************************************/
1870         /* Enable chip ID 1. */
1871         logical[12] =
1872             ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1873             | (1 << 1);
1874
1875         /* Send semaphore from FE to ChipID 1. */
1876         logical[14] =
1877               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1878             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
1879             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
1880
1881         logical[15] =
1882               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
1883             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
1884             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
1885
1886         /* Wait for semaphore from ChipID 0. */
1887         logical[16] =
1888               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
1889
1890         logical[17] =
1891               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
1892             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)))
1893             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24)));
1894
1895         /*************************************************************/
1896         /* Enable all chips. */
1897         logical[18] =
1898             ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1899             | (0xFFFF);
1900
1901         /* LoadState(AQFlush, 1), flush. */
1902         logical[20]
1903             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1904             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
1905             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
1906
1907         logical[21]
1908             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
1909
1910         /* Append LINK(2, address). */
1911         logical[22]
1912             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1913             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
1914
1915         logical[23] = address;
1916 #else
1917         /* Append LINK(2, address). */
1918         logical[2]
1919             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
1920             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
1921
1922         logical[3] = address;
1923
1924         gcmkTRACE_ZONE(
1925             gcvLEVEL_INFO, gcvZONE_HARDWARE,
1926             "0x%08x: WAIT %u", address, waitCount
1927             );
1928
1929         gcmkTRACE_ZONE(
1930             gcvLEVEL_INFO, gcvZONE_HARDWARE,
1931             "0x%08x: LINK 0x%08x, #%lu",
1932             address + 8, address, bytes
1933             );
1934 #endif
1935
1936         if (WaitOffset != gcvNULL)
1937         {
1938             /* Return the offset pointer to WAIT command. */
1939             *WaitOffset = 0;
1940         }
1941
1942         if (WaitSize != gcvNULL)
1943         {
1944             /* Return number of bytes used by the WAIT command. */
1945             *WaitSize = 8;
1946         }
1947     }
1948
1949     if (Bytes != gcvNULL)
1950     {
1951         /* Return number of bytes required by the WAIT/LINK command
1952         ** sequence. */
1953         *Bytes = bytes;
1954     }
1955
1956     /* Success. */
1957     gcmkFOOTER_ARG("*Bytes=%lu *WaitOffset=0x%x *WaitSize=%lu",
1958                    gcmOPT_VALUE(Bytes), gcmOPT_VALUE(WaitOffset),
1959                    gcmOPT_VALUE(WaitSize));
1960     return gcvSTATUS_OK;
1961
1962 OnError:
1963     /* Return the status. */
1964     gcmkFOOTER();
1965     return status;
1966 }
1967
1968 /*******************************************************************************
1969 **
1970 **  gckHARDWARE_End
1971 **
1972 **  Append an END command at the specified location in the command queue.
1973 **
1974 **  INPUT:
1975 **
1976 **      gckHARDWARE Hardware
1977 **          Pointer to an gckHARDWARE object.
1978 **
1979 **      gctPOINTER Logical
1980 **          Pointer to the current location inside the command queue to append
1981 **          END command at or gcvNULL just to query the size of the END command.
1982 **
1983 **      gctSIZE_T * Bytes
1984 **          Pointer to the number of bytes available for the END command.  If
1985 **          'Logical' is gcvNULL, this argument will be ignored.
1986 **
1987 **  OUTPUT:
1988 **
1989 **      gctSIZE_T * Bytes
1990 **          Pointer to a variable that will receive the number of bytes required
1991 **          for the END command.  If 'Bytes' is gcvNULL, nothing will be returned.
1992 */
1993 gceSTATUS
1994 gckHARDWARE_End(
1995     IN gckHARDWARE Hardware,
1996     IN gctPOINTER Logical,
1997     IN OUT gctSIZE_T * Bytes
1998     )
1999 {
2000     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
2001     gceSTATUS status;
2002
2003     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
2004                    Hardware, Logical, gcmOPT_VALUE(Bytes));
2005
2006     /* Verify the arguments. */
2007     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2008     gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
2009
2010     if (Logical != gcvNULL)
2011     {
2012         if (*Bytes < 8)
2013         {
2014             /* Command queue too small. */
2015             gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
2016         }
2017
2018         /* Append END. */
2019        logical[0] =
2020             ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
2021
2022         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", Logical);
2023
2024         /* Make sure the CPU writes out the data to memory. */
2025         gcmkONERROR(
2026             gckOS_MemoryBarrier(Hardware->os, Logical));
2027     }
2028
2029     if (Bytes != gcvNULL)
2030     {
2031         /* Return number of bytes required by the END command. */
2032         *Bytes = 8;
2033     }
2034
2035     /* Success. */
2036     gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
2037     return gcvSTATUS_OK;
2038
2039 OnError:
2040     /* Return the status. */
2041     gcmkFOOTER();
2042     return status;
2043 }
2044
2045 /*******************************************************************************
2046 **
2047 **  gckHARDWARE_Nop
2048 **
2049 **  Append a NOP command at the specified location in the command queue.
2050 **
2051 **  INPUT:
2052 **
2053 **      gckHARDWARE Hardware
2054 **          Pointer to an gckHARDWARE object.
2055 **
2056 **      gctPOINTER Logical
2057 **          Pointer to the current location inside the command queue to append
2058 **          NOP command at or gcvNULL just to query the size of the NOP command.
2059 **
2060 **      gctSIZE_T * Bytes
2061 **          Pointer to the number of bytes available for the NOP command.  If
2062 **          'Logical' is gcvNULL, this argument will be ignored.
2063 **
2064 **  OUTPUT:
2065 **
2066 **      gctSIZE_T * Bytes
2067 **          Pointer to a variable that will receive the number of bytes required
2068 **          for the NOP command.  If 'Bytes' is gcvNULL, nothing will be returned.
2069 */
2070 gceSTATUS
2071 gckHARDWARE_Nop(
2072     IN gckHARDWARE Hardware,
2073     IN gctPOINTER Logical,
2074     IN OUT gctSIZE_T * Bytes
2075     )
2076 {
2077     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
2078     gceSTATUS status;
2079
2080     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
2081                    Hardware, Logical, gcmOPT_VALUE(Bytes));
2082
2083     /* Verify the arguments. */
2084     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2085     gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
2086
2087     if (Logical != gcvNULL)
2088     {
2089         if (*Bytes < 8)
2090         {
2091             /* Command queue too small. */
2092             gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
2093         }
2094
2095         /* Append NOP. */
2096         logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
2097
2098         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
2099     }
2100
2101     if (Bytes != gcvNULL)
2102     {
2103         /* Return number of bytes required by the NOP command. */
2104         *Bytes = 8;
2105     }
2106
2107     /* Success. */
2108     gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
2109     return gcvSTATUS_OK;
2110
2111 OnError:
2112     /* Return the status. */
2113     gcmkFOOTER();
2114     return status;
2115 }
2116
2117 /*******************************************************************************
2118 **
2119 **  gckHARDWARE_Wait
2120 **
2121 **  Append a WAIT command at the specified location in the command queue.
2122 **
2123 **  INPUT:
2124 **
2125 **      gckHARDWARE Hardware
2126 **          Pointer to an gckHARDWARE object.
2127 **
2128 **      gctPOINTER Logical
2129 **          Pointer to the current location inside the command queue to append
2130 **          WAIT command at or gcvNULL just to query the size of the WAIT command.
2131 **
2132 **      gctUINT32 Count
2133 **          Number of cycles to wait.
2134 **
2135 **      gctSIZE_T * Bytes
2136 **          Pointer to the number of bytes available for the WAIT command.  If
2137 **          'Logical' is gcvNULL, this argument will be ignored.
2138 **
2139 **  OUTPUT:
2140 **
2141 **      gctSIZE_T * Bytes
2142 **          Pointer to a variable that will receive the number of bytes required
2143 **          for the NOP command.  If 'Bytes' is gcvNULL, nothing will be returned.
2144 */
2145 gceSTATUS
2146 gckHARDWARE_Wait(
2147     IN gckHARDWARE Hardware,
2148     IN gctPOINTER Logical,
2149     IN gctUINT32 Count,
2150     IN OUT gctSIZE_T * Bytes
2151     )
2152 {
2153     gceSTATUS status;
2154     gctUINT32_PTR logical;
2155
2156     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Count=%u *Bytes=%lu",
2157                    Hardware, Logical, Count, gcmOPT_VALUE(Bytes));
2158
2159     /* Verify the arguments. */
2160     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2161     gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
2162
2163     /* Cast the input pointer. */
2164     logical = (gctUINT32_PTR) Logical;
2165
2166     if (Logical != gcvNULL)
2167     {
2168         if (*Bytes < 8)
2169         {
2170             /* Command queue too small. */
2171             gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
2172         }
2173
2174         /* Append WAIT. */
2175         logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
2176                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
2177
2178 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
2179         {
2180             gctUINT32 address;
2181
2182             /* Convert logical into hardware specific address. */
2183             gcmkONERROR(gckHARDWARE_ConvertLogical(
2184                 Hardware, logical, &address
2185                 ));
2186
2187             gcmkTRACE_ZONE(
2188                 gcvLEVEL_INFO, gcvZONE_HARDWARE,
2189                 "0x%08x: WAIT %u", address, Count
2190                 );
2191         }
2192 #endif
2193     }
2194
2195     if (Bytes != gcvNULL)
2196     {
2197         /* Return number of bytes required by the WAIT command. */
2198         *Bytes = 8;
2199     }
2200
2201     /* Success. */
2202     gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
2203     return gcvSTATUS_OK;
2204
2205 OnError:
2206     /* Return the status. */
2207     gcmkFOOTER();
2208     return status;
2209 }
2210
2211 /*******************************************************************************
2212 **
2213 **  gckHARDWARE_Event
2214 **
2215 **  Append an EVENT command at the specified location in the command queue.
2216 **
2217 **  INPUT:
2218 **
2219 **      gckHARDWARE Hardware
2220 **          Pointer to an gckHARDWARE object.
2221 **
2222 **      gctPOINTER Logical
2223 **          Pointer to the current location inside the command queue to append
2224 **          the EVENT command at or gcvNULL just to query the size of the EVENT
2225 **          command.
2226 **
2227 **      gctUINT8 Event
2228 **          Event ID to program.
2229 **
2230 **      gceKERNEL_WHERE FromWhere
2231 **          Location of the pipe to send the event.
2232 **
2233 **      gctSIZE_T * Bytes
2234 **          Pointer to the number of bytes available for the EVENT command.  If
2235 **          'Logical' is gcvNULL, this argument will be ignored.
2236 **
2237 **  OUTPUT:
2238 **
2239 **      gctSIZE_T * Bytes
2240 **          Pointer to a variable that will receive the number of bytes required
2241 **          for the EVENT command.  If 'Bytes' is gcvNULL, nothing will be
2242 **          returned.
2243 */
2244 gceSTATUS
2245 gckHARDWARE_Event(
2246     IN gckHARDWARE Hardware,
2247     IN gctPOINTER Logical,
2248     IN gctUINT8 Event,
2249     IN gceKERNEL_WHERE FromWhere,
2250     IN OUT gctSIZE_T * Bytes
2251     )
2252 {
2253     gctUINT size;
2254     gctUINT32 destination = 0;
2255     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
2256     gceSTATUS status;
2257
2258     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Event=%u FromWhere=%d *Bytes=%lu",
2259                    Hardware, Logical, Event, FromWhere, gcmOPT_VALUE(Bytes));
2260
2261     /* Verify the arguments. */
2262     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2263     gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
2264     gcmkVERIFY_ARGUMENT(Event < 32);
2265
2266     /* Determine the size of the command. */
2267
2268     size = (Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL))
2269          ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
2270          : 8;
2271
2272     if (Logical != gcvNULL)
2273     {
2274         if (*Bytes < size)
2275         {
2276             /* Command queue too small. */
2277             gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
2278         }
2279
2280         switch (FromWhere)
2281         {
2282         case gcvKERNEL_COMMAND:
2283             /* From command processor. */
2284             destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)));
2285             break;
2286
2287         case gcvKERNEL_PIXEL:
2288             /* From pixel engine. */
2289             destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
2290             break;
2291
2292         default:
2293             gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
2294         }
2295
2296         /* Append EVENT(Event, destiantion). */
2297         logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
2298                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
2299                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
2300
2301         logical[1] = ((((gctUINT32) (destination)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (Event) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
2302
2303         /* Make sure the event ID gets written out before GPU can access it. */
2304         gcmkONERROR(
2305             gckOS_MemoryBarrier(Hardware->os, logical + 1));
2306
2307 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
2308         {
2309             gctUINT32 phys;
2310             gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
2311             gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
2312                            "0x%08x: EVENT %d", phys, Event);
2313         }
2314 #endif
2315
2316         /* Append the extra states. These are needed for the chips that do not
2317         ** support back-to-back events due to the async interface. The extra
2318         ** states add the necessary delay to ensure that event IDs do not
2319         ** collide. */
2320         if (size > 8)
2321         {
2322             logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
2323                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0100) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
2324                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
2325             logical[3] = 0;
2326             logical[4] = 0;
2327             logical[5] = 0;
2328             logical[6] = 0;
2329             logical[7] = 0;
2330         }
2331     }
2332
2333     if (Bytes != gcvNULL)
2334     {
2335         /* Return number of bytes required by the EVENT command. */
2336         *Bytes = size;
2337     }
2338
2339     /* Success. */
2340     gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
2341     return gcvSTATUS_OK;
2342
2343 OnError:
2344     /* Return the status. */
2345     gcmkFOOTER();
2346     return status;
2347 }
2348
2349 /*******************************************************************************
2350 **
2351 **  gckHARDWARE_PipeSelect
2352 **
2353 **  Append a PIPESELECT command at the specified location in the command queue.
2354 **
2355 **  INPUT:
2356 **
2357 **      gckHARDWARE Hardware
2358 **          Pointer to an gckHARDWARE object.
2359 **
2360 **      gctPOINTER Logical
2361 **          Pointer to the current location inside the command queue to append
2362 **          the PIPESELECT command at or gcvNULL just to query the size of the
2363 **          PIPESELECT command.
2364 **
2365 **      gcePIPE_SELECT Pipe
2366 **          Pipe value to select.
2367 **
2368 **      gctSIZE_T * Bytes
2369 **          Pointer to the number of bytes available for the PIPESELECT command.
2370 **          If 'Logical' is gcvNULL, this argument will be ignored.
2371 **
2372 **  OUTPUT:
2373 **
2374 **      gctSIZE_T * Bytes
2375 **          Pointer to a variable that will receive the number of bytes required
2376 **          for the PIPESELECT command.  If 'Bytes' is gcvNULL, nothing will be
2377 **          returned.
2378 */
2379 gceSTATUS
2380 gckHARDWARE_PipeSelect(
2381     IN gckHARDWARE Hardware,
2382     IN gctPOINTER Logical,
2383     IN gcePIPE_SELECT Pipe,
2384     IN OUT gctSIZE_T * Bytes
2385     )
2386 {
2387     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
2388     gceSTATUS status;
2389
2390     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Pipe=%d *Bytes=%lu",
2391                    Hardware, Logical, Pipe, gcmOPT_VALUE(Bytes));
2392
2393     /* Verify the arguments. */
2394     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2395     gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
2396
2397     /* Append a PipeSelect. */
2398     if (Logical != gcvNULL)
2399     {
2400         gctUINT32 flush, stall;
2401
2402         if (*Bytes < 32)
2403         {
2404             /* Command queue too small. */
2405             gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
2406         }
2407
2408         flush = (Pipe == gcvPIPE_2D)
2409               ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
2410               | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
2411               : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
2412
2413         stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
2414               | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
2415
2416         /* LoadState(AQFlush, 1), flush. */
2417         logical[0]
2418             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
2419             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
2420             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
2421
2422         logical[1]
2423             = flush;
2424
2425         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
2426                        "0x%x: FLUSH 0x%x", logical, flush);
2427
2428         /* LoadState(AQSempahore, 1), stall. */
2429         logical[2]
2430             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
2431             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
2432             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
2433
2434         logical[3]
2435             = stall;
2436
2437         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
2438                        "0x%x: SEMAPHORE 0x%x", logical + 2, stall);
2439
2440         /* Stall, stall. */
2441         logical[4] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
2442         logical[5] = stall;
2443
2444         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
2445                        "0x%x: STALL 0x%x", logical + 4, stall);
2446
2447         /* LoadState(AQPipeSelect, 1), pipe. */
2448         logical[6]
2449             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
2450             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
2451             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
2452
2453         logical[7] = (Pipe == gcvPIPE_2D)
2454             ? 0x1
2455             : 0x0;
2456
2457         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
2458                        "0x%x: PIPE %d", logical + 6, Pipe);
2459     }
2460
2461     if (Bytes != gcvNULL)
2462     {
2463         /* Return number of bytes required by the PIPESELECT command. */
2464         *Bytes = 32;
2465     }
2466
2467     /* Success. */
2468     gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
2469     return gcvSTATUS_OK;
2470
2471 OnError:
2472     /* Return the status. */
2473     gcmkFOOTER();
2474     return status;
2475 }
2476
2477 /*******************************************************************************
2478 **
2479 **  gckHARDWARE_Link
2480 **
2481 **  Append a LINK command at the specified location in the command queue.
2482 **
2483 **  INPUT:
2484 **
2485 **      gckHARDWARE Hardware
2486 **          Pointer to an gckHARDWARE object.
2487 **
2488 **      gctPOINTER Logical
2489 **          Pointer to the current location inside the command queue to append
2490 **          the LINK command at or gcvNULL just to query the size of the LINK
2491 **          command.
2492 **
2493 **      gctPOINTER FetchAddress
2494 **          Logical address of destination of LINK.
2495 **
2496 **      gctSIZE_T FetchSize
2497 **          Number of bytes in destination of LINK.
2498 **
2499 **      gctSIZE_T * Bytes
2500 **          Pointer to the number of bytes available for the LINK command.  If
2501 **          'Logical' is gcvNULL, this argument will be ignored.
2502 **
2503 **  OUTPUT:
2504 **
2505 **      gctSIZE_T * Bytes
2506 **          Pointer to a variable that will receive the number of bytes required
2507 **          for the LINK command.  If 'Bytes' is gcvNULL, nothing will be returned.
2508 */
2509 gceSTATUS
2510 gckHARDWARE_Link(
2511     IN gckHARDWARE Hardware,
2512     IN gctPOINTER Logical,
2513     IN gctPOINTER FetchAddress,
2514     IN gctSIZE_T FetchSize,
2515     IN OUT gctSIZE_T * Bytes
2516     )
2517 {
2518     gceSTATUS status;
2519     gctSIZE_T bytes;
2520     gctUINT32 address;
2521     gctUINT32 link;
2522     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
2523
2524     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x FetchAddress=0x%x FetchSize=%lu "
2525                    "*Bytes=%lu",
2526                    Hardware, Logical, FetchAddress, FetchSize,
2527                    gcmOPT_VALUE(Bytes));
2528
2529     /* Verify the arguments. */
2530     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2531     gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
2532
2533     if (Logical != gcvNULL)
2534     {
2535         if (*Bytes < 8)
2536         {
2537             /* Command queue too small. */
2538             gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
2539         }
2540
2541         /* Convert logical address to hardware address. */
2542         gcmkONERROR(
2543             gckHARDWARE_ConvertLogical(Hardware, FetchAddress, &address));
2544
2545         gcmkONERROR(
2546             gckOS_WriteMemory(Hardware->os, logical + 1, address));
2547
2548         /* Make sure the address got written before the LINK command. */
2549         gcmkONERROR(
2550             gckOS_MemoryBarrier(Hardware->os, logical + 1));
2551
2552         /* Compute number of 64-byte aligned bytes to fetch. */
2553         bytes = gcmALIGN(address + FetchSize, 64) - address;
2554
2555         /* Append LINK(bytes / 8), FetchAddress. */
2556         link = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
2557              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
2558
2559         gcmkONERROR(
2560             gckOS_WriteMemory(Hardware->os, logical, link));
2561
2562         /* Memory barrier. */
2563         gcmkONERROR(
2564             gckOS_MemoryBarrier(Hardware->os, logical));
2565
2566 #if gcdLINK_QUEUE_SIZE && gcdVIRTUAL_COMMAND_BUFFER
2567         if (address >= 0x80000000)
2568         {
2569             gckLINKQUEUE_Enqueue(&Hardware->linkQueue, address, address + bytes);
2570         }
2571 #endif
2572     }
2573
2574     if (Bytes != gcvNULL)
2575     {
2576         /* Return number of bytes required by the LINK command. */
2577         *Bytes = 8;
2578     }
2579
2580     /* Success. */
2581     gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
2582     return gcvSTATUS_OK;
2583
2584 OnError:
2585     /* Return the status. */
2586     gcmkFOOTER();
2587     return status;
2588 }
2589
2590 /*******************************************************************************
2591 **
2592 **  gckHARDWARE_UpdateQueueTail
2593 **
2594 **  Update the tail of the command queue.
2595 **
2596 **  INPUT:
2597 **
2598 **      gckHARDWARE Hardware
2599 **          Pointer to an gckHARDWARE object.
2600 **
2601 **      gctPOINTER Logical
2602 **          Logical address of the start of the command queue.
2603 **
2604 **      gctUINT32 Offset
2605 **          Offset into the command queue of the tail (last command).
2606 **
2607 **  OUTPUT:
2608 **
2609 **      Nothing.
2610 */
2611 gceSTATUS
2612 gckHARDWARE_UpdateQueueTail(
2613     IN gckHARDWARE Hardware,
2614     IN gctPOINTER Logical,
2615     IN gctUINT32 Offset
2616     )
2617 {
2618     gceSTATUS status;
2619
2620     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x",
2621                    Hardware, Logical, Offset);
2622
2623     /* Verify the hardware. */
2624     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2625
2626     /* Force a barrier. */
2627     gcmkONERROR(
2628         gckOS_MemoryBarrier(Hardware->os, Logical));
2629
2630     /* Notify gckKERNEL object of change. */
2631     gcmkONERROR(
2632         gckKERNEL_Notify(Hardware->kernel,
2633                          gcvNOTIFY_COMMAND_QUEUE,
2634                          gcvFALSE));
2635
2636     if (status == gcvSTATUS_CHIP_NOT_READY)
2637     {
2638         gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
2639     }
2640
2641     /* Success. */
2642     gcmkFOOTER_NO();
2643     return gcvSTATUS_OK;
2644
2645 OnError:
2646     /* Return the status. */
2647     gcmkFOOTER();
2648     return status;
2649 }
2650
2651 /*******************************************************************************
2652 **
2653 **  gckHARDWARE_ConvertLogical
2654 **
2655 **  Convert a logical system address into a hardware specific address.
2656 **
2657 **  INPUT:
2658 **
2659 **      gckHARDWARE Hardware
2660 **          Pointer to an gckHARDWARE object.
2661 **
2662 **      gctPOINTER Logical
2663 **          Logical address to convert.
2664 **
2665 **      gctUINT32* Address
2666 **          Return hardware specific address.
2667 **
2668 **  OUTPUT:
2669 **
2670 **      Nothing.
2671 */
2672 gceSTATUS
2673 gckHARDWARE_ConvertLogical(
2674     IN gckHARDWARE Hardware,
2675     IN gctPOINTER Logical,
2676     OUT gctUINT32 * Address
2677     )
2678 {
2679     gctUINT32 address;
2680     gceSTATUS status;
2681     gctUINT32 baseAddress;
2682
2683     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
2684
2685     /* Verify the arguments. */
2686     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2687     gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
2688     gcmkVERIFY_ARGUMENT(Address != gcvNULL);
2689
2690 #if gcdVIRTUAL_COMMAND_BUFFER
2691     status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address);
2692
2693     if (status == gcvSTATUS_INVALID_ADDRESS)
2694 #endif
2695     {
2696         /* Convert logical address into a physical address. */
2697         gcmkONERROR(
2698             gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
2699
2700         /* For old MMU, get GPU address according to baseAddress. */
2701         if (Hardware->mmuVersion == 0)
2702         {
2703             gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
2704
2705             /* Subtract base address to get a GPU address. */
2706             gcmkASSERT(address >= baseAddress);
2707             address -= baseAddress;
2708         }
2709
2710         /* Return hardware specific address. */
2711         *Address = (Hardware->mmuVersion == 0)
2712                  ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
2713                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
2714                  : address;
2715     }
2716
2717     /* Success. */
2718     gcmkFOOTER_ARG("*Address=0x%08x", *Address);
2719     return gcvSTATUS_OK;
2720
2721 OnError:
2722     /* Return the status. */
2723     gcmkFOOTER();
2724     return status;
2725 }
2726
2727 /*******************************************************************************
2728 **
2729 **  gckHARDWARE_ConvertPhysical
2730 **
2731 **  Convert a physical address into a hardware specific address.
2732 **
2733 **  INPUT:
2734 **
2735 **      gckHARDWARE Hardware
2736 **          Pointer to an gckHARDWARE object.
2737 **
2738 **      gctPHYS_ADDR Physical
2739 **          Physical address to convert.
2740 **
2741 **      gctUINT32* Address
2742 **          Return hardware specific address.
2743 **
2744 **  OUTPUT:
2745 **
2746 **      Nothing.
2747 */
2748 gceSTATUS
2749 gckHARDWARE_ConvertPhysical(
2750     IN gckHARDWARE Hardware,
2751     IN gctPHYS_ADDR Physical,
2752     OUT gctUINT32 * Address
2753     )
2754 {
2755     gctUINT32 address;
2756     gctUINT32 baseAddress;
2757
2758     gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x", Hardware, Physical);
2759
2760     /* Verify the arguments. */
2761     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2762     gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
2763     gcmkVERIFY_ARGUMENT(Address != gcvNULL);
2764
2765     address = gcmPTR2INT(Physical);
2766
2767     /* For old MMU, get GPU address according to baseAddress. */
2768     if (Hardware->mmuVersion == 0)
2769     {
2770         gcmkVERIFY_OK(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
2771
2772         /* Subtract base address to get a GPU address. */
2773         gcmkASSERT(address >= baseAddress);
2774         address -= baseAddress;
2775     }
2776
2777     /* Return hardware specific address. */
2778     *Address = (Hardware->mmuVersion == 0)
2779              ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
2780                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
2781              : address;
2782
2783     /* Return the status. */
2784     gcmkFOOTER_ARG("*Address=0x%08x", *Address);
2785     return gcvSTATUS_OK;
2786 }
2787
2788 /*******************************************************************************
2789 **
2790 **  gckHARDWARE_Interrupt
2791 **
2792 **  Process an interrupt.
2793 **
2794 **  INPUT:
2795 **
2796 **      gckHARDWARE Hardware
2797 **          Pointer to an gckHARDWARE object.
2798 **
2799 **      gctBOOL InterruptValid
2800 **          If gcvTRUE, this function will read the interrupt acknowledge
2801 **          register, stores the data, and return whether or not the interrupt
2802 **          is ours or not.  If gcvFALSE, this functions will read the interrupt
2803 **          acknowledge register and combine it with any stored value to handle
2804 **          the event notifications.
2805 **
2806 **  OUTPUT:
2807 **
2808 **      Nothing.
2809 */
2810 gceSTATUS
2811 gckHARDWARE_Interrupt(
2812     IN gckHARDWARE Hardware,
2813     IN gctBOOL InterruptValid
2814     )
2815 {
2816     gckEVENT eventObj;
2817     gctUINT32 data;
2818     gceSTATUS status;
2819
2820     gcmkHEADER_ARG("Hardware=0x%x InterruptValid=%d", Hardware, InterruptValid);
2821
2822     /* Verify the arguments. */
2823     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2824
2825     /* Extract gckEVENT object. */
2826     eventObj = Hardware->kernel->eventObj;
2827     gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
2828
2829     if (InterruptValid)
2830     {
2831         /* Read AQIntrAcknowledge register. */
2832         gcmkONERROR(
2833             gckOS_ReadRegisterEx(Hardware->os,
2834                                  Hardware->core,
2835                                  0x00010,
2836                                  &data));
2837
2838         if (data == 0)
2839         {
2840             /* Not our interrupt. */
2841             status = gcvSTATUS_NOT_OUR_INTERRUPT;
2842         }
2843         else
2844         {
2845             /* Inform gckEVENT of the interrupt. */
2846             status = gckEVENT_Interrupt(eventObj, data);
2847         }
2848     }
2849     else
2850     {
2851         /* Handle events. */
2852         status = gckEVENT_Notify(eventObj, 0);
2853     }
2854
2855 OnError:
2856     /* Return the status. */
2857     gcmkFOOTER();
2858     return status;
2859 }
2860
2861 /*******************************************************************************
2862 **
2863 **  gckHARDWARE_QueryCommandBuffer
2864 **
2865 **  Query the command buffer alignment and number of reserved bytes.
2866 **
2867 **  INPUT:
2868 **
2869 **      gckHARDWARE Harwdare
2870 **          Pointer to an gckHARDWARE object.
2871 **
2872 **  OUTPUT:
2873 **
2874 **      gctSIZE_T * Alignment
2875 **          Pointer to a variable receiving the alignment for each command.
2876 **
2877 **      gctSIZE_T * ReservedHead
2878 **          Pointer to a variable receiving the number of reserved bytes at the
2879 **          head of each command buffer.
2880 **
2881 **      gctSIZE_T * ReservedTail
2882 **          Pointer to a variable receiving the number of bytes reserved at the
2883 **          tail of each command buffer.
2884 */
2885 gceSTATUS
2886 gckHARDWARE_QueryCommandBuffer(
2887     IN gckHARDWARE Hardware,
2888     OUT gctSIZE_T * Alignment,
2889     OUT gctSIZE_T * ReservedHead,
2890     OUT gctSIZE_T * ReservedTail
2891     )
2892 {
2893     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
2894
2895     /* Verify the arguments. */
2896     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2897
2898     if (Alignment != gcvNULL)
2899     {
2900         /* Align every 8 bytes. */
2901         *Alignment = 8;
2902     }
2903
2904     if (ReservedHead != gcvNULL)
2905     {
2906         /* Reserve space for SelectPipe(). */
2907         *ReservedHead = 32;
2908     }
2909
2910     if (ReservedTail != gcvNULL)
2911     {
2912         /* Reserve space for Link(). */
2913         *ReservedTail = 8;
2914     }
2915
2916     /* Success. */
2917     gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu",
2918                    gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead),
2919                    gcmOPT_VALUE(ReservedTail));
2920     return gcvSTATUS_OK;
2921 }
2922
2923 /*******************************************************************************
2924 **
2925 **  gckHARDWARE_QuerySystemMemory
2926 **
2927 **  Query the command buffer alignment and number of reserved bytes.
2928 **
2929 **  INPUT:
2930 **
2931 **      gckHARDWARE Harwdare
2932 **          Pointer to an gckHARDWARE object.
2933 **
2934 **  OUTPUT:
2935 **
2936 **      gctSIZE_T * SystemSize
2937 **          Pointer to a variable that receives the maximum size of the system
2938 **          memory.
2939 **
2940 **      gctUINT32 * SystemBaseAddress
2941 **          Poinetr to a variable that receives the base address for system
2942 **          memory.
2943 */
2944 gceSTATUS
2945 gckHARDWARE_QuerySystemMemory(
2946     IN gckHARDWARE Hardware,
2947     OUT gctSIZE_T * SystemSize,
2948     OUT gctUINT32 * SystemBaseAddress
2949     )
2950 {
2951     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
2952
2953     /* Verify the arguments. */
2954     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2955
2956     if (SystemSize != gcvNULL)
2957     {
2958         /* Maximum system memory can be 2GB. */
2959         *SystemSize = 1U << 31;
2960     }
2961
2962     if (SystemBaseAddress != gcvNULL)
2963     {
2964         /* Set system memory base address. */
2965         *SystemBaseAddress = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)));
2966     }
2967
2968     /* Success. */
2969     gcmkFOOTER_ARG("*SystemSize=%lu *SystemBaseAddress=%lu",
2970                    gcmOPT_VALUE(SystemSize), gcmOPT_VALUE(SystemBaseAddress));
2971     return gcvSTATUS_OK;
2972 }
2973
2974 #ifndef VIVANTE_NO_3D
2975 /*******************************************************************************
2976 **
2977 **  gckHARDWARE_QueryShaderCaps
2978 **
2979 **  Query the shader capabilities.
2980 **
2981 **  INPUT:
2982 **
2983 **      Nothing.
2984 **
2985 **  OUTPUT:
2986 **
2987 **      gctUINT * VertexUniforms
2988 **          Pointer to a variable receiving the number of uniforms in the vertex
2989 **          shader.
2990 **
2991 **      gctUINT * FragmentUniforms
2992 **          Pointer to a variable receiving the number of uniforms in the
2993 **          fragment shader.
2994 **
2995 **      gctUINT * Varyings
2996 **          Pointer to a variable receiving the maimum number of varyings.
2997 */
2998 gceSTATUS
2999 gckHARDWARE_QueryShaderCaps(
3000     IN gckHARDWARE Hardware,
3001     OUT gctUINT * VertexUniforms,
3002     OUT gctUINT * FragmentUniforms,
3003     OUT gctUINT * Varyings
3004     )
3005 {
3006     gctUINT32 vsConstMax;
3007     gctUINT32 psConstMax;
3008
3009     gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x "
3010                    "FragmentUniforms=0x%x Varyings=0x%x",
3011                    Hardware, VertexUniforms,
3012                    FragmentUniforms, Varyings);
3013
3014     if ((Hardware->identity.chipModel == gcv2000)
3015      && (Hardware->identity.chipRevision == 0x5118))
3016     {
3017         vsConstMax   = 256;
3018         psConstMax   = 64;
3019     }
3020     else if (Hardware->identity.numConstants > 256)
3021     {
3022         vsConstMax   = 256;
3023         psConstMax   = 256;
3024     }
3025     else if (Hardware->identity.numConstants == 256)
3026     {
3027         vsConstMax   = 256;
3028         psConstMax   = 256;
3029     }
3030     else
3031     {
3032         vsConstMax   = 168;
3033         psConstMax   = 64;
3034     }
3035
3036     if (VertexUniforms != gcvNULL)
3037     {
3038         *VertexUniforms = vsConstMax;
3039     }
3040
3041     if (FragmentUniforms != gcvNULL)
3042     {
3043         *FragmentUniforms = psConstMax;
3044     }
3045
3046     if (Varyings != gcvNULL)
3047     {
3048                 /* Return the shader varyings count. */
3049         *Varyings = Hardware->identity.varyingsCount;
3050     }
3051
3052     /* Success. */
3053     gcmkFOOTER_NO();
3054     return gcvSTATUS_OK;
3055 }
3056 #endif
3057
3058 /*******************************************************************************
3059 **
3060 **  gckHARDWARE_SetMMU
3061 **
3062 **  Set the page table base address.
3063 **
3064 **  INPUT:
3065 **
3066 **      gckHARDWARE Harwdare
3067 **          Pointer to an gckHARDWARE object.
3068 **
3069 **      gctPOINTER Logical
3070 **          Logical address of the page table.
3071 **
3072 **  OUTPUT:
3073 **
3074 **      Nothing.
3075 */
3076 gceSTATUS
3077 gckHARDWARE_SetMMU(
3078     IN gckHARDWARE Hardware,
3079     IN gctPOINTER Logical
3080     )
3081 {
3082     gceSTATUS status;
3083     gctUINT32 address = 0;
3084     gctUINT32 baseAddress;
3085
3086     gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
3087
3088     /* Verify the arguments. */
3089     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
3090     gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
3091
3092     /* Convert the logical address into an hardware address. */
3093     gcmkONERROR(
3094         gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
3095
3096     /* Also get the base address - we need a real physical address. */
3097     gcmkONERROR(
3098         gckOS_GetBaseAddress(Hardware->os, &baseAddress));
3099
3100     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3101                    "Setting page table to 0x%08X",
3102                    address + baseAddress);
3103
3104     /* Write the AQMemoryFePageTable register. */
3105     gcmkONERROR(
3106         gckOS_WriteRegisterEx(Hardware->os,
3107                               Hardware->core,
3108                               0x00400,
3109                               address + baseAddress));
3110
3111     /* Write the AQMemoryRaPageTable register. */
3112     gcmkONERROR(
3113         gckOS_WriteRegisterEx(Hardware->os,
3114                               Hardware->core,
3115                               0x00410,
3116                               address + baseAddress));
3117
3118     /* Write the AQMemoryTxPageTable register. */
3119     gcmkONERROR(
3120         gckOS_WriteRegisterEx(Hardware->os,
3121                               Hardware->core,
3122                               0x00404,
3123                               address + baseAddress));
3124
3125
3126     /* Write the AQMemoryPePageTable register. */
3127     gcmkONERROR(
3128         gckOS_WriteRegisterEx(Hardware->os,
3129                               Hardware->core,
3130                               0x00408,
3131                               address + baseAddress));
3132
3133     /* Write the AQMemoryPezPageTable register. */
3134     gcmkONERROR(
3135         gckOS_WriteRegisterEx(Hardware->os,
3136                               Hardware->core,
3137                               0x0040C,
3138                               address + baseAddress));
3139
3140     /* Return the status. */
3141     gcmkFOOTER_NO();
3142     return status;
3143
3144 OnError:
3145     /* Return the status. */
3146     gcmkFOOTER();
3147     return status;
3148 }
3149
3150 /*******************************************************************************
3151 **
3152 **  gckHARDWARE_FlushMMU
3153 **
3154 **  Flush the page table.
3155 **
3156 **  INPUT:
3157 **
3158 **      gckHARDWARE Harwdare
3159 **          Pointer to an gckHARDWARE object.
3160 **
3161 **  OUTPUT:
3162 **
3163 **      Nothing.
3164 */
3165 gceSTATUS
3166 gckHARDWARE_FlushMMU(
3167     IN gckHARDWARE Hardware
3168     )
3169 {
3170     gceSTATUS status;
3171     gckCOMMAND command;
3172     gctUINT32_PTR buffer;
3173     gctSIZE_T bufferSize;
3174     gctBOOL commitEntered = gcvFALSE;
3175     gctPOINTER pointer = gcvNULL;
3176     gctUINT32 flushSize;
3177     gctUINT32 count;
3178     gctUINT32 physical;
3179
3180     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
3181
3182     /* Verify the arguments. */
3183     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
3184
3185     /* Verify the gckCOMMAND object pointer. */
3186     command = Hardware->kernel->command;
3187
3188     /* Acquire the command queue. */
3189     gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
3190     commitEntered = gcvTRUE;
3191
3192     /* Flush the memory controller. */
3193     if (Hardware->mmuVersion == 0)
3194     {
3195         gcmkONERROR(gckCOMMAND_Reserve(
3196             command, 8, &pointer, &bufferSize
3197             ));
3198
3199         buffer = (gctUINT32_PTR) pointer;
3200
3201         buffer[0]
3202             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3203             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E04) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3204             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3205
3206         buffer[1]
3207             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
3208             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
3209             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
3210             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
3211             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
3212
3213         gcmkONERROR(gckCOMMAND_Execute(command, 8));
3214     }
3215     else
3216     {
3217         flushSize =  16 * 4;
3218
3219         gcmkONERROR(gckCOMMAND_Reserve(
3220             command, flushSize, &pointer, &bufferSize
3221             ));
3222
3223         buffer = (gctUINT32_PTR) pointer;
3224
3225         count = (bufferSize - flushSize + 7) >> 3;
3226
3227         gcmkONERROR(gckOS_GetPhysicalAddress(command->os, buffer, &physical));
3228
3229         /* Flush cache. */
3230         buffer[0]
3231             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3232             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
3233             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
3234
3235         buffer[1]
3236             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
3237             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
3238             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
3239             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)))
3240             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
3241             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
3242
3243         /* Arm the PE-FE Semaphore. */
3244         buffer[2]
3245             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3246             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
3247             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
3248
3249         buffer[3]
3250             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
3251             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
3252
3253         /* STALL FE until PE is done flushing. */
3254         buffer[4]
3255             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
3256
3257         buffer[5]
3258             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
3259             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
3260
3261         /* LINK to next slot to flush FE FIFO. */
3262         buffer[6]
3263             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3264             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
3265
3266         buffer[7]
3267             = physical + 8 * gcmSIZEOF(gctUINT32);
3268
3269         /* Flush MMU cache. */
3270         buffer[8]
3271             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3272             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3273             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3274
3275         buffer[9]
3276             = (((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) &  ((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
3277
3278         /* Arm the PE-FE Semaphore. */
3279         buffer[10]
3280             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3281             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
3282             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
3283
3284         buffer[11]
3285             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
3286             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
3287
3288         /* STALL FE until PE is done flushing. */
3289         buffer[12]
3290             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
3291
3292         buffer[13]
3293             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
3294             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
3295
3296         /* LINK to next slot to flush FE FIFO. */
3297         buffer[14]
3298             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3299             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
3300
3301         buffer[15]
3302             = physical + flushSize;
3303
3304         gcmkONERROR(gckCOMMAND_Execute(command, flushSize));
3305     }
3306
3307     /* Release the command queue. */
3308     gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
3309     commitEntered = gcvFALSE;
3310
3311     /* Success. */
3312     gcmkFOOTER_NO();
3313     return gcvSTATUS_OK;
3314
3315 OnError:
3316     if (commitEntered)
3317     {
3318         /* Release the command queue mutex. */
3319         gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
3320                                             gcvFALSE));
3321     }
3322
3323     /* Return the status. */
3324     gcmkFOOTER();
3325     return status;
3326 }
3327
3328 /*******************************************************************************
3329 **
3330 **  gckHARDWARE_SetMMUv2
3331 **
3332 **  Set the page table base address.
3333 **
3334 **  INPUT:
3335 **
3336 **      gckHARDWARE Harwdare
3337 **          Pointer to an gckHARDWARE object.
3338 **
3339 **  OUTPUT:
3340 **
3341 **      Nothing.
3342 */
3343 gceSTATUS
3344 gckHARDWARE_SetMMUv2(
3345     IN gckHARDWARE Hardware,
3346     IN gctBOOL Enable,
3347     IN gctPOINTER MtlbAddress,
3348     IN gceMMU_MODE Mode,
3349     IN gctPOINTER SafeAddress,
3350     IN gctBOOL FromPower
3351     )
3352 {
3353     gceSTATUS status;
3354     gctUINT32 config, address;
3355     gckCOMMAND command;
3356     gctUINT32_PTR buffer;
3357     gctSIZE_T bufferSize;
3358     gctBOOL commitEntered = gcvFALSE;
3359     gctPOINTER pointer = gcvNULL;
3360     gctBOOL acquired = gcvFALSE;
3361     gctBOOL config2D;
3362     gctSIZE_T configSize;
3363
3364     gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable);
3365
3366     /* Verify the arguments. */
3367     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
3368
3369     config2D =  gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_3D)
3370              && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PIPE_2D);
3371
3372     configSize = 4 * 4;
3373
3374     if (config2D)
3375     {
3376         configSize +=
3377             /* Pipe Select. */
3378             4 * 4
3379             /* Configure MMU States. */
3380           + 4 * 4;
3381     }
3382
3383     /* Convert logical address into physical address. */
3384     gcmkONERROR(
3385         gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &config));
3386
3387     gcmkONERROR(
3388         gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &address));
3389
3390     if (address & 0x3F)
3391     {
3392         gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
3393     }
3394
3395     switch (Mode)
3396     {
3397     case gcvMMU_MODE_1K:
3398         if (config & 0x3FF)
3399         {
3400             gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
3401         }
3402
3403         config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
3404
3405         break;
3406
3407     case gcvMMU_MODE_4K:
3408         if (config & 0xFFF)
3409         {
3410             gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
3411         }
3412
3413         config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
3414
3415         break;
3416
3417     default:
3418         gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
3419     }
3420
3421     /* Verify the gckCOMMAND object pointer. */
3422     command = Hardware->kernel->command;
3423
3424     /* Acquire the command queue. */
3425     gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
3426     commitEntered = gcvTRUE;
3427
3428     gcmkONERROR(gckCOMMAND_Reserve(
3429         command, configSize, &pointer, &bufferSize
3430         ));
3431
3432     buffer = pointer;
3433
3434     buffer[0]
3435         = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3436         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3437         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3438
3439     buffer[1] = config;
3440
3441     buffer[2]
3442         = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3443         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3444         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3445
3446     buffer[3] = address;
3447
3448     if (config2D)
3449     {
3450         /* LoadState(AQPipeSelect, 1), pipe. */
3451         buffer[4]
3452             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3453             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3454             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3455
3456         buffer[5] = 0x1;
3457
3458         buffer[6]
3459             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3460             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3461             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3462
3463         buffer[7] = config;
3464
3465         buffer[8]
3466             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3467             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3468             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3469
3470         buffer[9] = address;
3471
3472         /* LoadState(AQPipeSelect, 1), pipe. */
3473         buffer[10]
3474             = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3475             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3476             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3477
3478         buffer[11] = 0x0;
3479     }
3480
3481     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3482         "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address);
3483
3484     gcmkONERROR(gckCOMMAND_Execute(command, configSize));
3485
3486     if (FromPower == gcvFALSE)
3487     {
3488         /* Acquire global semaphore to suspend power management until MMU
3489         ** is enabled. And acquired it before gckCOMMAND_ExitCommit to
3490         ** make sure GPU keeps ON. */
3491         gcmkONERROR(
3492             gckOS_AcquireSemaphore(Hardware->os, Hardware->globalSemaphore));
3493
3494         acquired = gcvTRUE;
3495     }
3496
3497     /* Release the command queue. */
3498     gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
3499     commitEntered = gcvFALSE;
3500
3501     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3502         "call gckCOMMAND_Stall to make sure the config is done.\n ");
3503
3504     gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
3505
3506     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3507         "Enable MMU through GCREG_MMU_CONTROL.");
3508
3509     /* Enable MMU. */
3510     gcmkONERROR(
3511         gckOS_WriteRegisterEx(Hardware->os,
3512                               Hardware->core,
3513                               0x0018C,
3514                               ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Enable) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))));
3515
3516     if (FromPower == gcvFALSE)
3517     {
3518         /* Relase global semaphore. */
3519         gcmkVERIFY_OK(
3520             gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
3521
3522         acquired = gcvFALSE;
3523     }
3524
3525     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3526         "call gckCOMMAND_Stall to check MMU available.\n");
3527
3528     gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
3529
3530     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3531         "The MMU is available.\n");
3532
3533     /* Return the status. */
3534     gcmkFOOTER_NO();
3535     return status;
3536
3537 OnError:
3538     if (commitEntered)
3539     {
3540         /* Release the command queue mutex. */
3541         gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
3542                                             FromPower));
3543     }
3544
3545     if (acquired)
3546     {
3547         gcmkVERIFY_OK(
3548             gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
3549     }
3550
3551     /* Return the status. */
3552     gcmkFOOTER();
3553     return status;
3554 }
3555
3556 /*******************************************************************************
3557 **
3558 **  gckHARDWARE_BuildVirtualAddress
3559 **
3560 **  Build a virtual address.
3561 **
3562 **  INPUT:
3563 **
3564 **      gckHARDWARE Harwdare
3565 **          Pointer to an gckHARDWARE object.
3566 **
3567 **      gctUINT32 Index
3568 **          Index into page table.
3569 **
3570 **      gctUINT32 Offset
3571 **          Offset into page.
3572 **
3573 **  OUTPUT:
3574 **
3575 **      gctUINT32 * Address
3576 **          Pointer to a variable receiving te hardware address.
3577 */
3578 gceSTATUS
3579 gckHARDWARE_BuildVirtualAddress(
3580     IN gckHARDWARE Hardware,
3581     IN gctUINT32 Index,
3582     IN gctUINT32 Offset,
3583     OUT gctUINT32 * Address
3584     )
3585 {
3586     gcmkHEADER_ARG("Hardware=0x%x Index=%u Offset=%u", Hardware, Index, Offset);
3587
3588     /* Verify the arguments. */
3589     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
3590     gcmkVERIFY_ARGUMENT(Address != gcvNULL);
3591
3592     /* Build virtual address. */
3593     *Address = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
3594              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (Offset | (Index << 12)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)));
3595
3596     /* Success. */
3597     gcmkFOOTER_ARG("*Address=0x%08x", *Address);
3598     return gcvSTATUS_OK;
3599 }
3600
3601 gceSTATUS
3602 gckHARDWARE_GetIdle(
3603     IN gckHARDWARE Hardware,
3604     IN gctBOOL Wait,
3605     OUT gctUINT32 * Data
3606     )
3607 {
3608     gceSTATUS status;
3609     gctUINT32 idle = 0;
3610     gctINT retry, poll, pollCount;
3611
3612     gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait);
3613
3614     /* Verify the arguments. */
3615     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
3616     gcmkVERIFY_ARGUMENT(Data != gcvNULL);
3617
3618
3619     /* If we have to wait, try 100 polls per millisecond. */
3620     pollCount = Wait ? 100 : 1;
3621
3622     /* At most, try for 1 second. */
3623     for (retry = 0; retry < 1000; ++retry)
3624     {
3625         /* If we have to wait, try 100 polls per millisecond. */
3626         for (poll = pollCount; poll > 0; --poll)
3627         {
3628             /* Read register. */
3629             gcmkONERROR(
3630                 gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
3631
3632             /* See if we have to wait for FE idle. */
3633             if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
3634             {
3635                 /* FE is idle. */
3636                 break;
3637             }
3638         }
3639
3640         /* Check if we need to wait for FE and FE is busy. */
3641         if (Wait && !(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
3642         {
3643             /* Wait a little. */
3644             gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3645                            "%s: Waiting for idle: 0x%08X",
3646                            __FUNCTION__, idle);
3647
3648             gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
3649         }
3650         else
3651         {
3652             break;
3653         }
3654     }
3655
3656     /* Return idle to caller. */
3657     *Data = idle;
3658
3659     /* Success. */
3660     gcmkFOOTER_ARG("*Data=0x%08x", *Data);
3661     return gcvSTATUS_OK;
3662
3663 OnError:
3664     /* Return the status. */
3665     gcmkFOOTER();
3666     return status;
3667 }
3668
3669 /* Flush the caches. */
3670 gceSTATUS
3671 gckHARDWARE_Flush(
3672     IN gckHARDWARE Hardware,
3673     IN gceKERNEL_FLUSH Flush,
3674     IN gctPOINTER Logical,
3675     IN OUT gctSIZE_T * Bytes
3676     )
3677 {
3678     gctUINT32 pipe;
3679     gctUINT32 flush = 0;
3680     gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
3681     gceSTATUS status;
3682     gctBOOL fcFlushStall;
3683     gctUINT32 reserveBytes = 8;
3684
3685     gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
3686                    Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
3687
3688     /* Verify the arguments. */
3689     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
3690
3691     /* Get current pipe. */
3692     pipe = Hardware->kernel->command->pipeSelect;
3693
3694     fcFlushStall
3695         = ((((gctUINT32) (Hardware->identity.chipMinorFeatures1)) >> (0 ? 31:31) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))))
3696         && (Flush == gcvFLUSH_ALL)
3697         ;
3698
3699     if (fcFlushStall)
3700     {
3701         reserveBytes += 8;
3702     }
3703
3704     /* Flush 3D color cache. */
3705     if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
3706     {
3707         flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)));
3708     }
3709
3710     /* Flush 3D depth cache. */
3711     if ((Flush & gcvFLUSH_DEPTH) && (pipe == 0x0))
3712     {
3713         flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
3714     }
3715
3716     /* Flush 3D texture cache. */
3717     if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0))
3718     {
3719         flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)));
3720         flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
3721     }
3722
3723     /* Flush 2D cache. */
3724     if ((Flush & gcvFLUSH_2D) && (pipe == 0x1))
3725     {
3726         flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
3727     }
3728
3729     /* See if there is a valid flush. */
3730     if (flush == 0)
3731     {
3732         if (Bytes != gcvNULL)
3733         {
3734             /* No bytes required. */
3735             *Bytes = 0;
3736         }
3737     }
3738
3739     else
3740     {
3741         /* Copy to command queue. */
3742         if (Logical != gcvNULL)
3743         {
3744             if (*Bytes < reserveBytes)
3745             {
3746                 /* Command queue too small. */
3747                 gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
3748             }
3749
3750             /* Append LOAD_STATE to AQFlush. */
3751             logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3752                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3753                        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3754
3755             logical[1] = flush;
3756
3757             gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3758                            "0x%x: FLUSH 0x%x", logical, flush);
3759
3760             if (fcFlushStall)
3761             {
3762                 logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
3763                            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
3764                            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
3765
3766                 logical[3] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
3767
3768
3769                 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3770                                "0x%x: FLUSH 0x%x", logical + 3, logical[3]);
3771             }
3772
3773         }
3774
3775         if (Bytes != gcvNULL)
3776         {
3777             /* bytes required. */
3778             *Bytes = reserveBytes;
3779         }
3780     }
3781
3782     /* Success. */
3783     gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
3784     return gcvSTATUS_OK;
3785
3786 OnError:
3787     /* Return the status. */
3788     gcmkFOOTER();
3789     return status;
3790 }
3791
3792 gceSTATUS
3793 gckHARDWARE_SetFastClear(
3794     IN gckHARDWARE Hardware,
3795     IN gctINT Enable,
3796     IN gctINT Compression
3797     )
3798 {
3799 #ifndef VIVANTE_NO_3D
3800     gctUINT32 debug;
3801     gceSTATUS status;
3802
3803     gcmkHEADER_ARG("Hardware=0x%x Enable=%d Compression=%d",
3804                    Hardware, Enable, Compression);
3805
3806     /* Only process if fast clear is available. */
3807     if ((((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
3808     {
3809         if (Enable == -1)
3810         {
3811             /* Determine automatic value for fast clear. */
3812             Enable = ((Hardware->identity.chipModel    != gcv500)
3813                      || (Hardware->identity.chipRevision >= 3)
3814                      ) ? 1 : 0;
3815         }
3816
3817         if (Compression == -1)
3818         {
3819             /* Determine automatic value for compression. */
3820             Compression = Enable
3821                         & (((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) );
3822         }
3823
3824         /* Read AQMemoryDebug register. */
3825         gcmkONERROR(
3826             gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &debug));
3827
3828         /* Set fast clear bypass. */
3829         debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
3830
3831         if (
3832             ((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) ||
3833             (Hardware->identity.chipModel >= gcv4000))
3834         {
3835             /* Set compression bypass. */
3836             debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))) | (((gctUINT32) ((gctUINT32) (Compression == 0) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21)));
3837         }
3838
3839         /* Write back AQMemoryDebug register. */
3840         gcmkONERROR(
3841             gckOS_WriteRegisterEx(Hardware->os,
3842                                   Hardware->core,
3843                                   0x00414,
3844                                   debug));
3845
3846         /* Store fast clear and comprersison flags. */
3847         Hardware->allowFastClear   = Enable;
3848         Hardware->allowCompression = Compression;
3849
3850         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
3851                        "FastClear=%d Compression=%d", Enable, Compression);
3852     }
3853
3854     /* Success. */
3855     gcmkFOOTER_NO();
3856     return gcvSTATUS_OK;
3857
3858 OnError:
3859     /* Return the status. */
3860     gcmkFOOTER();
3861     return status;
3862 #else
3863     return gcvSTATUS_OK;
3864 #endif
3865 }
3866
3867 typedef enum
3868 {
3869     gcvPOWER_FLAG_INITIALIZE    = 1 << 0,
3870     gcvPOWER_FLAG_STALL         = 1 << 1,
3871     gcvPOWER_FLAG_STOP          = 1 << 2,
3872     gcvPOWER_FLAG_START         = 1 << 3,
3873     gcvPOWER_FLAG_RELEASE       = 1 << 4,
3874     gcvPOWER_FLAG_DELAY         = 1 << 5,
3875     gcvPOWER_FLAG_SAVE          = 1 << 6,
3876     gcvPOWER_FLAG_ACQUIRE       = 1 << 7,
3877     gcvPOWER_FLAG_POWER_OFF     = 1 << 8,
3878     gcvPOWER_FLAG_CLOCK_OFF     = 1 << 9,
3879     gcvPOWER_FLAG_CLOCK_ON      = 1 << 10,
3880 }
3881 gcePOWER_FLAGS;
3882
3883 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
3884 static gctCONST_STRING
3885 _PowerEnum(gceCHIPPOWERSTATE State)
3886 {
3887     const gctCONST_STRING states[] =
3888     {
3889         gcmSTRING(gcvPOWER_ON),
3890         gcmSTRING(gcvPOWER_OFF),
3891         gcmSTRING(gcvPOWER_IDLE),
3892         gcmSTRING(gcvPOWER_SUSPEND),
3893         gcmSTRING(gcvPOWER_SUSPEND_ATPOWERON),
3894         gcmSTRING(gcvPOWER_OFF_ATPOWERON),
3895         gcmSTRING(gcvPOWER_IDLE_BROADCAST),
3896         gcmSTRING(gcvPOWER_SUSPEND_BROADCAST),
3897         gcmSTRING(gcvPOWER_OFF_BROADCAST),
3898         gcmSTRING(gcvPOWER_OFF_RECOVERY),
3899         gcmSTRING(gcvPOWER_ON_AUTO)
3900     };
3901
3902     if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO))
3903     {
3904         return states[State - gcvPOWER_ON];
3905     }
3906
3907     return "unknown";
3908 }
3909 #endif
3910
3911 /*******************************************************************************
3912 **
3913 **  gckHARDWARE_SetPowerManagementState
3914 **
3915 **  Set GPU to a specified power state.
3916 **
3917 **  INPUT:
3918 **
3919 **      gckHARDWARE Harwdare
3920 **          Pointer to an gckHARDWARE object.
3921 **
3922 **      gceCHIPPOWERSTATE State
3923 **          Power State.
3924 **
3925 */
3926 gceSTATUS
3927 gckHARDWARE_SetPowerManagementState(
3928     IN gckHARDWARE Hardware,
3929     IN gceCHIPPOWERSTATE State
3930     )
3931 {
3932     gceSTATUS status;
3933     gckCOMMAND command = gcvNULL;
3934     gckOS os;
3935     gctUINT flag, clock;
3936     gctPOINTER buffer;
3937     gctSIZE_T bytes, requested;
3938     gctBOOL acquired = gcvFALSE;
3939     gctBOOL mutexAcquired = gcvFALSE;
3940     gctBOOL stall = gcvTRUE;
3941     gctBOOL broadcast = gcvFALSE;
3942 #if gcdPOWEROFF_TIMEOUT
3943     gctBOOL timeout = gcvFALSE;
3944     gctBOOL isAfter = gcvFALSE;
3945     gctUINT32 currentTime;
3946 #endif
3947     gctUINT32 process, thread;
3948     gctBOOL commitEntered = gcvFALSE;
3949     gctBOOL commandStarted = gcvFALSE;
3950     gctBOOL isrStarted = gcvFALSE;
3951
3952 #if gcdENABLE_PROFILING
3953     gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
3954               initTime, offTime, startTime, totalTime;
3955 #endif
3956     gctBOOL global = gcvFALSE;
3957     gctBOOL globalAcquired = gcvFALSE;
3958     gctBOOL configMmu = gcvFALSE;
3959
3960     /* State transition flags. */
3961     static const gctUINT flags[4][4] =
3962     {
3963         /* gcvPOWER_ON           */
3964         {   /* ON                */ 0,
3965             /* OFF               */ gcvPOWER_FLAG_ACQUIRE   |
3966                                     gcvPOWER_FLAG_STALL     |
3967                                     gcvPOWER_FLAG_STOP      |
3968                                     gcvPOWER_FLAG_POWER_OFF |
3969                                     gcvPOWER_FLAG_CLOCK_OFF,
3970             /* IDLE              */ gcvPOWER_FLAG_ACQUIRE   |
3971                                     gcvPOWER_FLAG_STALL,
3972             /* SUSPEND           */ gcvPOWER_FLAG_ACQUIRE   |
3973                                     gcvPOWER_FLAG_STALL     |
3974                                     gcvPOWER_FLAG_STOP      |
3975                                     gcvPOWER_FLAG_CLOCK_OFF,
3976         },
3977
3978         /* gcvPOWER_OFF          */
3979         {   /* ON                */ gcvPOWER_FLAG_INITIALIZE |
3980                                     gcvPOWER_FLAG_START      |
3981                                     gcvPOWER_FLAG_RELEASE    |
3982                                     gcvPOWER_FLAG_DELAY,
3983             /* OFF               */ 0,
3984             /* IDLE              */ gcvPOWER_FLAG_INITIALIZE |
3985                                     gcvPOWER_FLAG_START      |
3986                                     gcvPOWER_FLAG_DELAY,
3987             /* SUSPEND           */ gcvPOWER_FLAG_INITIALIZE |
3988                                     gcvPOWER_FLAG_CLOCK_OFF,
3989         },
3990
3991         /* gcvPOWER_IDLE         */
3992         {   /* ON                */ gcvPOWER_FLAG_RELEASE,
3993             /* OFF               */ gcvPOWER_FLAG_STOP      |
3994                                     gcvPOWER_FLAG_POWER_OFF |
3995                                     gcvPOWER_FLAG_CLOCK_OFF,
3996             /* IDLE              */ 0,
3997             /* SUSPEND           */ gcvPOWER_FLAG_STOP      |
3998                                     gcvPOWER_FLAG_CLOCK_OFF,
3999         },
4000
4001         /* gcvPOWER_SUSPEND      */
4002         {   /* ON                */ gcvPOWER_FLAG_START     |
4003                                     gcvPOWER_FLAG_RELEASE   |
4004                                     gcvPOWER_FLAG_DELAY     |
4005                                     gcvPOWER_FLAG_CLOCK_ON,
4006             /* OFF               */ gcvPOWER_FLAG_SAVE      |
4007                                     gcvPOWER_FLAG_POWER_OFF |
4008                                     gcvPOWER_FLAG_CLOCK_OFF,
4009             /* IDLE              */ gcvPOWER_FLAG_START     |
4010                                     gcvPOWER_FLAG_DELAY     |
4011                                     gcvPOWER_FLAG_CLOCK_ON,
4012             /* SUSPEND           */ 0,
4013         },
4014     };
4015
4016     /* Clocks. */
4017     static const gctUINT clocks[4] =
4018     {
4019         /* gcvPOWER_ON */
4020         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
4021         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
4022         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
4023         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
4024
4025         /* gcvPOWER_OFF */
4026         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
4027         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
4028         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
4029         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
4030
4031         /* gcvPOWER_IDLE */
4032         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
4033         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
4034         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
4035         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
4036
4037         /* gcvPOWER_SUSPEND */
4038         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
4039         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
4040         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
4041         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
4042     };
4043
4044     gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
4045 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
4046     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
4047                    "Switching to power state %d(%s)",
4048                    State, _PowerEnum(State));
4049 #endif
4050
4051     /* Verify the arguments. */
4052     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
4053
4054     /* Get the gckOS object pointer. */
4055     os = Hardware->os;
4056     gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
4057
4058     /* Get the gckCOMMAND object pointer. */
4059     gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
4060     command = Hardware->kernel->command;
4061     gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
4062
4063     if (Hardware->powerManagement == gcvFALSE)
4064     {
4065         gcmkFOOTER_NO();
4066         return gcvSTATUS_OK;
4067     }
4068
4069     /* Start profiler. */
4070     gcmkPROFILE_INIT(freq, time);
4071
4072     /* Convert the broadcast power state. */
4073     switch (State)
4074     {
4075     case gcvPOWER_SUSPEND_ATPOWERON:
4076         /* Convert to SUSPEND and don't wait for STALL. */
4077         State = gcvPOWER_SUSPEND;
4078         stall = gcvFALSE;
4079         break;
4080
4081     case gcvPOWER_OFF_ATPOWERON:
4082         /* Convert to OFF and don't wait for STALL. */
4083         State = gcvPOWER_OFF;
4084         stall = gcvFALSE;
4085         break;
4086
4087     case gcvPOWER_IDLE_BROADCAST:
4088         /* Convert to IDLE and note we are inside broadcast. */
4089         State     = gcvPOWER_IDLE;
4090         broadcast = gcvTRUE;
4091         break;
4092
4093     case gcvPOWER_SUSPEND_BROADCAST:
4094         /* Convert to SUSPEND and note we are inside broadcast. */
4095         State     = gcvPOWER_SUSPEND;
4096         broadcast = gcvTRUE;
4097         break;
4098
4099     case gcvPOWER_OFF_BROADCAST:
4100         /* Convert to OFF and note we are inside broadcast. */
4101         State     = gcvPOWER_OFF;
4102         broadcast = gcvTRUE;
4103         break;
4104
4105     case gcvPOWER_OFF_RECOVERY:
4106         /* Convert to OFF and note we are inside recovery. */
4107         State     = gcvPOWER_OFF;
4108         stall     = gcvFALSE;
4109         broadcast = gcvTRUE;
4110         break;
4111
4112     case gcvPOWER_ON_AUTO:
4113         /* Convert to ON and note we are inside recovery. */
4114         State = gcvPOWER_ON;
4115         break;
4116
4117     case gcvPOWER_ON:
4118     case gcvPOWER_IDLE:
4119     case gcvPOWER_SUSPEND:
4120     case gcvPOWER_OFF:
4121         /* Mark as global power management. */
4122         global = gcvTRUE;
4123         break;
4124
4125 #if gcdPOWEROFF_TIMEOUT
4126     case gcvPOWER_OFF_TIMEOUT:
4127         /* Convert to OFF and note we are inside broadcast. */
4128         State     = gcvPOWER_OFF;
4129         broadcast = gcvTRUE;
4130         /* Check time out */
4131         timeout = gcvTRUE;
4132         break;
4133 #endif
4134
4135     default:
4136         break;
4137     }
4138
4139     /* Get current process and thread IDs. */
4140     gcmkONERROR(gckOS_GetProcessID(&process));
4141     gcmkONERROR(gckOS_GetThreadID(&thread));
4142
4143     if (broadcast)
4144     {
4145         /* Try to acquire the power mutex. */
4146         status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
4147
4148         if (status == gcvSTATUS_TIMEOUT)
4149         {
4150             /* Check if we already own this mutex. */
4151             if ((Hardware->powerProcess == process)
4152             &&  (Hardware->powerThread  == thread)
4153             )
4154             {
4155                 /* Bail out on recursive power management. */
4156                 gcmkFOOTER_NO();
4157                 return gcvSTATUS_OK;
4158             }
4159             else if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
4160             {
4161                 /* Called from IST,
4162                 ** so waiting here will cause deadlock,
4163                 ** if lock holder call gckCOMMAND_Stall() */
4164                 gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
4165             }
4166 #if gcdPOWEROFF_TIMEOUT
4167             else if(State == gcvPOWER_OFF && timeout == gcvTRUE)
4168             {
4169                 /*
4170                 ** try to aqcuire the mutex with more milliseconds,
4171                 ** flush_delayed_work should be running with timeout,
4172                 ** so waiting here will cause deadlock */
4173                 status = gckOS_AcquireMutex(os, Hardware->powerMutex, gcdPOWEROFF_TIMEOUT);
4174
4175                 if (status == gcvSTATUS_TIMEOUT)
4176                 {
4177                     gckOS_Print("GPU Timer deadlock, exit by timeout!!!!\n");
4178
4179                     gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
4180                 }
4181             }
4182 #endif
4183             else
4184             {
4185                 /* Acquire the power mutex. */
4186                 gcmkONERROR(gckOS_AcquireMutex(os,
4187                                                Hardware->powerMutex,
4188                                                gcvINFINITE));
4189             }
4190         }
4191     }
4192     else
4193     {
4194         /* Acquire the power mutex. */
4195         gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
4196     }
4197
4198     /* Get time until mtuex acquired. */
4199     gcmkPROFILE_QUERY(time, mutexTime);
4200
4201     Hardware->powerProcess = process;
4202     Hardware->powerThread  = thread;
4203     mutexAcquired          = gcvTRUE;
4204
4205     /* Grab control flags and clock. */
4206     flag  = flags[Hardware->chipPowerState][State];
4207     clock = clocks[State];
4208
4209 #if gcdENABLE_FSCALE_VAL_ADJUST
4210     if (State == gcvPOWER_ON)
4211     {
4212         clock = ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (Hardware->powerOnFscaleVal) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)));
4213     }
4214 #endif
4215
4216     if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
4217     {
4218 #if gcdPOWER_SUSNPEND_WHEN_IDLE
4219         /* Do nothing */
4220
4221         /* Release the power mutex. */
4222         gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
4223
4224         gcmkFOOTER_NO();
4225         return gcvSTATUS_OK;
4226 #else
4227         /* Clock should be on when switch power from off to suspend */
4228         clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
4229                 ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
4230                 ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
4231                 ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) ;
4232 #endif
4233     }
4234
4235 #if gcdPOWEROFF_TIMEOUT
4236     if (timeout)
4237     {
4238         gcmkONERROR(gckOS_GetTicks(&currentTime));
4239
4240         gcmkONERROR(
4241             gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
4242
4243         /* powerOffTime is pushed forward, give up.*/
4244         if (isAfter
4245         /* Expect a transition start from IDLE or SUSPEND. */
4246         ||  (Hardware->chipPowerState == gcvPOWER_ON)
4247         ||  (Hardware->chipPowerState == gcvPOWER_OFF)
4248         )
4249         {
4250             /* Release the power mutex. */
4251             gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
4252
4253             /* No need to do anything. */
4254             gcmkFOOTER_NO();
4255             return gcvSTATUS_OK;
4256         }
4257
4258         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
4259                        "Power Off GPU[%d] at %u [supposed to be at %u]",
4260                        Hardware->core, currentTime, Hardware->powerOffTime);
4261     }
4262 #endif
4263
4264     if (flag == 0)
4265     {
4266         /* Release the power mutex. */
4267         gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
4268
4269         /* No need to do anything. */
4270         gcmkFOOTER_NO();
4271         return gcvSTATUS_OK;
4272     }
4273
4274     /* If this is an internal power management, we have to check if we can grab
4275     ** the global power semaphore. If we cannot, we have to wait until the
4276     ** external world changes power management. */
4277     if (!global)
4278     {
4279         /* Try to acquire the global semaphore. */
4280         status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
4281         if (status == gcvSTATUS_TIMEOUT)
4282         {
4283             if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
4284             {
4285                 /* Called from thread routine which should NEVER sleep.*/
4286                 gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
4287             }
4288
4289             /* Release the power mutex. */
4290             gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
4291                            "Releasing the power mutex.");
4292             gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
4293             mutexAcquired = gcvFALSE;
4294
4295             /* Wait for the semaphore. */
4296             gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
4297                            "Waiting for global semaphore.");
4298             gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
4299             globalAcquired = gcvTRUE;
4300
4301             /* Acquire the power mutex. */
4302             gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
4303                            "Reacquiring the power mutex.");
4304             gcmkONERROR(gckOS_AcquireMutex(os,
4305                                            Hardware->powerMutex,
4306                                            gcvINFINITE));
4307             mutexAcquired = gcvTRUE;
4308
4309             /* chipPowerState may be changed by external world during the time
4310             ** we give up powerMutex, so updating flag now is necessary. */
4311             flag = flags[Hardware->chipPowerState][State];
4312
4313             if (flag == 0)
4314             {
4315                 gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
4316                 globalAcquired = gcvFALSE;
4317
4318                 gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
4319                 mutexAcquired = gcvFALSE;
4320
4321                 gcmkFOOTER_NO();
4322                 return gcvSTATUS_OK;
4323             }
4324         }
4325         else
4326         {
4327             /* Error. */
4328             gcmkONERROR(status);
4329         }
4330
4331         /* Release the global semaphore again. */
4332         gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
4333         globalAcquired = gcvFALSE;
4334     }
4335     else
4336     {
4337         if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
4338         {
4339             /* Acquire the global semaphore if it has not been acquired. */
4340             status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
4341             if (status == gcvSTATUS_OK)
4342             {
4343                 globalAcquired = gcvTRUE;
4344             }
4345             else if (status != gcvSTATUS_TIMEOUT)
4346             {
4347                 /* Other errors. */
4348                 gcmkONERROR(status);
4349             }
4350             /* Ignore gcvSTATUS_TIMEOUT and leave globalAcquired as gcvFALSE.
4351             ** gcvSTATUS_TIMEOUT means global semaphore has already
4352             ** been acquired before this operation, so even if we fail,
4353             ** we should not release it in our error handling. It should be
4354             ** released by the next successful global gcvPOWER_ON. */
4355         }
4356
4357         /* Global power management can't be aborted, so sync with
4358         ** proceeding last commit. */
4359         if (flag & gcvPOWER_FLAG_ACQUIRE)
4360         {
4361             /* Acquire the power management semaphore. */
4362             gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
4363             acquired = gcvTRUE;
4364
4365             /* avoid acquiring again. */
4366             flag &= ~gcvPOWER_FLAG_ACQUIRE;
4367         }
4368     }
4369
4370     if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
4371     {
4372         /* Turn on the power. */
4373         gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
4374
4375         /* Mark clock and power as enabled. */
4376         Hardware->clockState = gcvTRUE;
4377         Hardware->powerState = gcvTRUE;
4378
4379         for (;;)
4380         {
4381             /* Check if GPU is present and awake. */
4382             status = _IsGPUPresent(Hardware);
4383
4384             /* Check if the GPU is not responding. */
4385             if (status == gcvSTATUS_GPU_NOT_RESPONDING)
4386             {
4387                 /* Turn off the power and clock. */
4388                 gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvFALSE, gcvFALSE));
4389
4390                 Hardware->clockState = gcvFALSE;
4391                 Hardware->powerState = gcvFALSE;
4392
4393                 /* Wait a little. */
4394                 gckOS_Delay(os, 1);
4395
4396                 /* Turn on the power and clock. */
4397                 gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
4398
4399                 Hardware->clockState = gcvTRUE;
4400                 Hardware->powerState = gcvTRUE;
4401
4402                 /* We need to initialize the hardware and start the command
4403                  * processor. */
4404                 flag |= gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_START;
4405             }
4406             else
4407             {
4408                 /* Test for error. */
4409                 gcmkONERROR(status);
4410
4411                 /* Break out of loop. */
4412                 break;
4413             }
4414         }
4415     }
4416
4417     /* Get time until powered on. */
4418     gcmkPROFILE_QUERY(time, onTime);
4419
4420     if ((flag & gcvPOWER_FLAG_STALL) && stall)
4421     {
4422         gctBOOL idle;
4423         gctINT32 atomValue;
4424
4425         /* For global operation, all pending commits have already been
4426         ** blocked by globalSemaphore or powerSemaphore.*/
4427         if (!global)
4428         {
4429             /* Check commit atom. */
4430             gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
4431
4432             if (atomValue > 0)
4433             {
4434                 /* Commits are pending - abort power management. */
4435                 status = broadcast ? gcvSTATUS_CHIP_NOT_READY
4436                                    : gcvSTATUS_MORE_DATA;
4437                 goto OnError;
4438             }
4439         }
4440
4441         if (broadcast)
4442         {
4443             /* Check for idle. */
4444             gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
4445
4446             if (!idle)
4447             {
4448                 status = gcvSTATUS_CHIP_NOT_READY;
4449                 goto OnError;
4450             }
4451         }
4452
4453         else
4454         {
4455             /* Acquire the command queue. */
4456             gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvTRUE));
4457             commitEntered = gcvTRUE;
4458
4459             /* Get the size of the flush command. */
4460             gcmkONERROR(gckHARDWARE_Flush(Hardware,
4461                                           gcvFLUSH_ALL,
4462                                           gcvNULL,
4463                                           &requested));
4464
4465             /* Reserve space in the command queue. */
4466             gcmkONERROR(gckCOMMAND_Reserve(command,
4467                                            requested,
4468                                            &buffer,
4469                                            &bytes));
4470
4471             /* Append a flush. */
4472             gcmkONERROR(gckHARDWARE_Flush(
4473                 Hardware, gcvFLUSH_ALL, buffer, &bytes
4474                 ));
4475
4476             /* Execute the command queue. */
4477             gcmkONERROR(gckCOMMAND_Execute(command, requested));
4478
4479             /* Release the command queue. */
4480             gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvTRUE));
4481             commitEntered = gcvFALSE;
4482
4483             /* Wait to finish all commands. */
4484             gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
4485         }
4486     }
4487
4488     /* Get time until stalled. */
4489     gcmkPROFILE_QUERY(time, stallTime);
4490
4491     if (flag & gcvPOWER_FLAG_ACQUIRE)
4492     {
4493         /* Acquire the power management semaphore. */
4494         gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
4495         acquired = gcvTRUE;
4496     }
4497
4498     if (flag & gcvPOWER_FLAG_STOP)
4499     {
4500         /* Stop the command parser. */
4501         gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
4502
4503         /* Stop the Isr. */
4504         if (Hardware->stopIsr)
4505         {
4506             gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
4507         }
4508     }
4509
4510     /* Flush Cache before Power Off. */
4511     if (flag & gcvPOWER_FLAG_POWER_OFF)
4512     {
4513         if (Hardware->clockState == gcvFALSE)
4514         {
4515             /* Turn off the GPU power. */
4516             gcmkONERROR(
4517                     gckOS_SetGPUPower(os,
4518                         Hardware->core,
4519                         gcvTRUE,
4520                         gcvTRUE));
4521
4522             Hardware->clockState = gcvTRUE;
4523
4524             if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE)
4525             {
4526                 /* Write the clock control register. */
4527                 gcmkONERROR(gckOS_WriteRegisterEx(os,
4528                                                   Hardware->core,
4529                                                   0x00000,
4530                                                   clocks[0]));
4531
4532                 /* Done loading the frequency scaler. */
4533                 gcmkONERROR(gckOS_WriteRegisterEx(os,
4534                                                   Hardware->core,
4535                                                   0x00000,
4536                                                   ((((gctUINT32) (clocks[0])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
4537             }
4538         }
4539
4540         gcmkONERROR(gckCOMMAND_Start(command));
4541
4542         gcmkONERROR(_FlushCache(Hardware, command));
4543
4544         gckOS_Delay(gcvNULL, 1);
4545
4546         /* Stop the command parser. */
4547         gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
4548
4549         flag |= gcvPOWER_FLAG_CLOCK_OFF;
4550     }
4551
4552     /* Get time until stopped. */
4553     gcmkPROFILE_QUERY(time, stopTime);
4554
4555     /* Only process this when hardware is enabled. */
4556     if (Hardware->clockState && Hardware->powerState
4557     /* Don't touch clock control if dynamic frequency scaling is available. */
4558     && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE
4559     )
4560     {
4561         if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
4562         {
4563             if (Hardware->identity.chipModel == gcv4000
4564             && Hardware->identity.chipRevision == 0x5208)
4565             {
4566                 clock &= ~2U;
4567             }
4568         }
4569
4570         /* Write the clock control register. */
4571         gcmkONERROR(gckOS_WriteRegisterEx(os,
4572                                           Hardware->core,
4573                                           0x00000,
4574                                           clock));
4575
4576         /* Done loading the frequency scaler. */
4577         gcmkONERROR(gckOS_WriteRegisterEx(os,
4578                                           Hardware->core,
4579                                           0x00000,
4580                                           ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
4581     }
4582
4583     if (flag & gcvPOWER_FLAG_DELAY)
4584     {
4585         /* Wait for the specified amount of time to settle coming back from
4586         ** power-off or suspend state. */
4587         gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
4588     }
4589
4590     /* Get time until delayed. */
4591     gcmkPROFILE_QUERY(time, delayTime);
4592
4593     if (flag & gcvPOWER_FLAG_INITIALIZE)
4594     {
4595         /* Initialize hardware. */
4596         gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
4597
4598         gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
4599                                              Hardware->allowFastClear,
4600                                              Hardware->allowCompression));
4601
4602         /* Force the command queue to reload the next context. */
4603         command->currContext = gcvNULL;
4604
4605         /* Need to config mmu after command start. */
4606         configMmu = gcvTRUE;
4607     }
4608
4609     /* Get time until initialized. */
4610     gcmkPROFILE_QUERY(time, initTime);
4611
4612     if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
4613     {
4614         /* Turn off the GPU power. */
4615         gcmkONERROR(
4616             gckOS_SetGPUPower(os,
4617                               Hardware->core,
4618                               (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
4619                                                                : gcvTRUE,
4620                               (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
4621                                                                : gcvTRUE));
4622
4623         /* Save current hardware power and clock states. */
4624         Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
4625                                                                 : gcvTRUE;
4626         Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
4627                                                                 : gcvTRUE;
4628     }
4629
4630     /* Get time until off. */
4631     gcmkPROFILE_QUERY(time, offTime);
4632
4633     if (flag & gcvPOWER_FLAG_START)
4634     {
4635         /* Start the command processor. */
4636         gcmkONERROR(gckCOMMAND_Start(command));
4637         commandStarted = gcvTRUE;
4638
4639         if (Hardware->startIsr)
4640         {
4641             /* Start the Isr. */
4642             gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
4643             isrStarted = gcvTRUE;
4644         }
4645
4646         /* Set NEW MMU. */
4647         if (Hardware->mmuVersion != 0 && configMmu)
4648         {
4649             gcmkONERROR(
4650                     gckHARDWARE_SetMMUv2(
4651                         Hardware,
4652                         gcvTRUE,
4653                         Hardware->kernel->mmu->mtlbLogical,
4654                         gcvMMU_MODE_4K,
4655                         (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
4656                         gcvTRUE
4657                         ));
4658         }
4659     }
4660
4661     /* Get time until started. */
4662     gcmkPROFILE_QUERY(time, startTime);
4663
4664     if (flag & gcvPOWER_FLAG_RELEASE)
4665     {
4666         /* Release the power management semaphore. */
4667         gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
4668         acquired = gcvFALSE;
4669
4670         if (global)
4671         {
4672             /* Verify global semaphore has been acquired already before
4673             ** we release it.
4674             ** If it was acquired, gckOS_TryAcquireSemaphore will return
4675             ** gcvSTATUS_TIMEOUT and we release it. Otherwise, global
4676             ** semaphore will be acquried now, but it still is released
4677             ** immediately. */
4678             status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
4679             if (status != gcvSTATUS_TIMEOUT)
4680             {
4681                 gcmkONERROR(status);
4682             }
4683
4684             /* Release the global semaphore. */
4685             gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
4686             globalAcquired = gcvFALSE;
4687         }
4688     }
4689
4690     /* Save the new power state. */
4691     Hardware->chipPowerState = State;
4692
4693 #if gcdDVFS
4694     if (State == gcvPOWER_ON && Hardware->kernel->dvfs)
4695     {
4696         gckDVFS_Start(Hardware->kernel->dvfs);
4697     }
4698 #endif
4699
4700 #if gcdPOWEROFF_TIMEOUT
4701     /* Reset power off time */
4702     gcmkONERROR(gckOS_GetTicks(&currentTime));
4703
4704     Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
4705
4706     if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
4707     {
4708         /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
4709         gcmkVERIFY_OK(gckOS_StartTimer(os,
4710                                        Hardware->powerOffTimer,
4711                                        Hardware->powerOffTimeout));
4712     }
4713     else
4714     {
4715         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
4716
4717         /* Cancel running timer when GPU enters ON or OFF. */
4718         gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
4719     }
4720 #endif
4721
4722     /* Release the power mutex. */
4723     gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
4724
4725     /* Get total time. */
4726     gcmkPROFILE_QUERY(time, totalTime);
4727 #if gcdENABLE_PROFILING
4728     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
4729                    "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
4730                    freq, mutexTime, onTime, stallTime, stopTime);
4731     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
4732                    "  delay:%llu init:%llu off:%llu start:%llu total:%llu",
4733                    delayTime, initTime, offTime, startTime, totalTime);
4734 #endif
4735
4736     /* Success. */
4737     gcmkFOOTER_NO();
4738     return gcvSTATUS_OK;
4739
4740 OnError:
4741     if (commandStarted)
4742     {
4743         gcmkVERIFY_OK(gckCOMMAND_Stop(command, gcvFALSE));
4744     }
4745
4746     if (isrStarted)
4747     {
4748         gcmkVERIFY_OK(Hardware->stopIsr(Hardware->isrContext));
4749     }
4750
4751     if (commitEntered)
4752     {
4753         /* Release the command queue mutex. */
4754         gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvTRUE));
4755     }
4756
4757     if (acquired)
4758     {
4759         /* Release semaphore. */
4760         gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
4761                                              command->powerSemaphore));
4762     }
4763
4764     if (globalAcquired)
4765     {
4766         gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
4767                                              Hardware->globalSemaphore));
4768     }
4769
4770     if (mutexAcquired)
4771     {
4772         gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
4773     }
4774
4775     /* Return the status. */
4776     gcmkFOOTER();
4777     return status;
4778 }
4779
4780 /*******************************************************************************
4781 **
4782 **  gckHARDWARE_QueryPowerManagementState
4783 **
4784 **  Get GPU power state.
4785 **
4786 **  INPUT:
4787 **
4788 **      gckHARDWARE Harwdare
4789 **          Pointer to an gckHARDWARE object.
4790 **
4791 **      gceCHIPPOWERSTATE* State
4792 **          Power State.
4793 **
4794 */
4795 gceSTATUS
4796 gckHARDWARE_QueryPowerManagementState(
4797     IN gckHARDWARE Hardware,
4798     OUT gceCHIPPOWERSTATE* State
4799     )
4800 {
4801     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
4802
4803     /* Verify the arguments. */
4804     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
4805     gcmkVERIFY_ARGUMENT(State != gcvNULL);
4806
4807     /* Return the statue. */
4808     *State = Hardware->chipPowerState;
4809
4810     /* Success. */
4811     gcmkFOOTER_ARG("*State=%d", *State);
4812     return gcvSTATUS_OK;
4813 }
4814
4815 /*******************************************************************************
4816 **
4817 **  gckHARDWARE_SetPowerManagement
4818 **
4819 **  Configure GPU power management function.
4820 **  Only used in driver initialization stage.
4821 **
4822 **  INPUT:
4823 **
4824 **      gckHARDWARE Harwdare
4825 **          Pointer to an gckHARDWARE object.
4826 **
4827 **      gctBOOL PowerManagement
4828 **          Power Mangement State.
4829 **
4830 */
4831 gceSTATUS
4832 gckHARDWARE_SetPowerManagement(
4833     IN gckHARDWARE Hardware,
4834     IN gctBOOL PowerManagement
4835     )
4836 {
4837     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
4838
4839     /* Verify the arguments. */
4840     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
4841
4842     Hardware->powerManagement = PowerManagement;
4843
4844     /* Success. */
4845     gcmkFOOTER_NO();
4846     return gcvSTATUS_OK;
4847 }
4848
4849 /*******************************************************************************
4850 **
4851 **  gckHARDWARE_SetGpuProfiler
4852 **
4853 **  Configure GPU profiler function.
4854 **  Only used in driver initialization stage.
4855 **
4856 **  INPUT:
4857 **
4858 **      gckHARDWARE Harwdare
4859 **          Pointer to an gckHARDWARE object.
4860 **
4861 **      gctBOOL GpuProfiler
4862 **          GOU Profiler State.
4863 **
4864 */
4865 gceSTATUS
4866 gckHARDWARE_SetGpuProfiler(
4867     IN gckHARDWARE Hardware,
4868     IN gctBOOL GpuProfiler
4869     )
4870 {
4871     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
4872
4873     /* Verify the arguments. */
4874     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
4875
4876     Hardware->gpuProfiler = GpuProfiler;
4877
4878     /* Success. */
4879     gcmkFOOTER_NO();
4880     return gcvSTATUS_OK;
4881 }
4882
4883 #if gcdENABLE_FSCALE_VAL_ADJUST
4884 gceSTATUS
4885 gckHARDWARE_SetFscaleValue(
4886     IN gckHARDWARE Hardware,
4887     IN gctUINT32   FscaleValue
4888     )
4889 {
4890     gceSTATUS status;
4891     gctUINT32 clock;
4892     gctBOOL acquired = gcvFALSE;
4893
4894     gcmkHEADER_ARG("Hardware=0x%x FscaleValue=%d", Hardware, FscaleValue);
4895
4896     gcmkVERIFY_ARGUMENT(FscaleValue > 0 && FscaleValue <= 64);
4897
4898     gcmkONERROR(
4899         gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
4900     acquired =  gcvTRUE;
4901
4902     Hardware->powerOnFscaleVal = FscaleValue;
4903
4904     if (Hardware->chipPowerState == gcvPOWER_ON)
4905     {
4906                 gctUINT32 data;
4907
4908         gcmkONERROR(
4909             gckOS_ReadRegisterEx(Hardware->os,
4910                                  Hardware->core,
4911                                  Hardware->powerBaseAddress
4912                                  + 0x00104,
4913                                  &data));
4914
4915         /* Disable all clock gating. */
4916         gcmkONERROR(
4917             gckOS_WriteRegisterEx(Hardware->os,
4918                                   Hardware->core,
4919                                   Hardware->powerBaseAddress
4920                                   + 0x00104,
4921                                   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
4922                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
4923                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
4924                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
4925                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)))
4926                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
4927                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)))
4928                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)))
4929                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
4930                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))
4931                                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1))))))) << (0 ? 11:11)))));
4932
4933         clock = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
4934               | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
4935               | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (FscaleValue) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)))
4936               | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
4937
4938         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
4939                                           Hardware->core,
4940                                           0x00000,
4941                                           clock));
4942
4943         /* Done loading the frequency scaler. */
4944         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
4945                                           Hardware->core,
4946                                           0x00000,
4947                                           ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
4948
4949         /* Restore all clock gating. */
4950         gcmkONERROR(
4951             gckOS_WriteRegisterEx(Hardware->os,
4952                                   Hardware->core,
4953                                   Hardware->powerBaseAddress
4954                                   + 0x00104,
4955                                   data));
4956     }
4957
4958     gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
4959
4960     gcmkFOOTER_NO();
4961     return gcvSTATUS_OK;
4962
4963 OnError:
4964     if (acquired)
4965     {
4966         gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
4967     }
4968
4969     gcmkFOOTER();
4970     return status;
4971 }
4972
4973 gceSTATUS
4974 gckHARDWARE_GetFscaleValue(
4975     IN gckHARDWARE Hardware,
4976     IN gctUINT * FscaleValue,
4977     IN gctUINT * MinFscaleValue,
4978     IN gctUINT * MaxFscaleValue
4979     )
4980 {
4981     *FscaleValue = Hardware->powerOnFscaleVal;
4982     if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR))
4983         *MinFscaleValue = gpu3DMinClock;
4984     else
4985         *MinFscaleValue = 1;
4986     *MaxFscaleValue = 64;
4987
4988     return gcvSTATUS_OK;
4989 }
4990
4991 #endif
4992
4993 #if gcdPOWEROFF_TIMEOUT
4994 gceSTATUS
4995 gckHARDWARE_SetPowerOffTimeout(
4996     IN gckHARDWARE  Hardware,
4997     IN gctUINT32    Timeout
4998 )
4999 {
5000     gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
5001
5002     Hardware->powerOffTimeout = Timeout;
5003
5004     gcmkFOOTER_NO();
5005     return gcvSTATUS_OK;
5006 }
5007
5008
5009 gceSTATUS
5010 gckHARDWARE_QueryPowerOffTimeout(
5011     IN gckHARDWARE  Hardware,
5012     OUT gctUINT32*  Timeout
5013 )
5014 {
5015     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
5016
5017     *Timeout = Hardware->powerOffTimeout;
5018
5019     gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
5020     return gcvSTATUS_OK;
5021 }
5022 #endif
5023
5024 gceSTATUS
5025 gckHARDWARE_QueryIdle(
5026     IN gckHARDWARE Hardware,
5027     OUT gctBOOL_PTR IsIdle
5028     )
5029 {
5030     gceSTATUS status;
5031     gctUINT32 idle, address;
5032
5033     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
5034
5035     /* Verify the arguments. */
5036     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
5037     gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
5038
5039     /* We are idle when the power is not ON. */
5040     if (Hardware->chipPowerState != gcvPOWER_ON)
5041     {
5042         *IsIdle = gcvTRUE;
5043     }
5044
5045     else
5046     {
5047         /* Read idle register. */
5048         gcmkONERROR(
5049             gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
5050
5051         /* Pipe must be idle. */
5052         if (((((((gctUINT32) (idle)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) ) != 1)
5053         ||  ((((((gctUINT32) (idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1)
5054         ||  ((((((gctUINT32) (idle)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) != 1)
5055         ||  ((((((gctUINT32) (idle)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) != 1)
5056         ||  ((((((gctUINT32) (idle)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) != 1)
5057         ||  ((((((gctUINT32) (idle)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) != 1)
5058         ||  ((((((gctUINT32) (idle)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) != 1)
5059         )
5060         {
5061             /* Something is busy. */
5062             *IsIdle = gcvFALSE;
5063         }
5064
5065         else
5066         {
5067             /* Read the current FE address. */
5068             gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
5069                                              Hardware->core,
5070                                              0x00664,
5071                                              &address));
5072
5073             /* Test if address is inside the last WAIT/LINK sequence. */
5074             if ((address >= Hardware->lastWaitLink)
5075             &&  (address <= Hardware->lastWaitLink + 16)
5076             )
5077             {
5078                 /* FE is in last WAIT/LINK and the pipe is idle. */
5079                 *IsIdle = gcvTRUE;
5080             }
5081             else
5082             {
5083                 /* FE is not in WAIT/LINK yet. */
5084                 *IsIdle = gcvFALSE;
5085             }
5086         }
5087     }
5088
5089     /* Success. */
5090     gcmkFOOTER_NO();
5091     return gcvSTATUS_OK;
5092
5093 OnError:
5094     /* Return the status. */
5095     gcmkFOOTER();
5096     return status;
5097 }
5098
5099 /*******************************************************************************
5100 ** Handy macros that will help in reading those debug registers.
5101 */
5102
5103 #define gcmkREAD_DEBUG_REGISTER(control, block, index, data) \
5104     gcmkONERROR(\
5105         gckOS_WriteRegisterEx(Hardware->os, \
5106                               Hardware->core, \
5107                               GC_DEBUG_CONTROL##control##_Address, \
5108                               gcmSETFIELD(0, \
5109                                           GC_DEBUG_CONTROL##control, \
5110                                           block, \
5111                                           index))); \
5112     gcmkONERROR(\
5113         gckOS_ReadRegisterEx(Hardware->os, \
5114                              Hardware->core, \
5115                              GC_DEBUG_SIGNALS_##block##_Address, \
5116                              &profiler->data))
5117
5118 #define gcmkREAD_DEBUG_REGISTER_N(control, block, index, data) \
5119     gcmkONERROR(\
5120         gckOS_WriteRegisterEx(Hardware->os, \
5121                               Hardware->core, \
5122                               GC_DEBUG_CONTROL##control##_Address, \
5123                               gcmSETFIELD(0, \
5124                                           GC_DEBUG_CONTROL##control, \
5125                                           block, \
5126                                           index))); \
5127     gcmkONERROR(\
5128         gckOS_ReadRegisterEx(Hardware->os, \
5129                              Hardware->core, \
5130                              GC_DEBUG_SIGNALS_##block##_Address, \
5131                              &data))
5132
5133 #define gcmkRESET_DEBUG_REGISTER(control, block) \
5134     gcmkONERROR(\
5135         gckOS_WriteRegisterEx(Hardware->os, \
5136                               Hardware->core, \
5137                               GC_DEBUG_CONTROL##control##_Address, \
5138                               gcmSETFIELD(0, \
5139                                           GC_DEBUG_CONTROL##control, \
5140                                           block, \
5141                                           15))); \
5142     gcmkONERROR(\
5143         gckOS_WriteRegisterEx(Hardware->os, \
5144                               Hardware->core, \
5145                               GC_DEBUG_CONTROL##control##_Address, \
5146                               gcmSETFIELD(0, \
5147                                           GC_DEBUG_CONTROL##control, \
5148                                           block, \
5149                                           0)))
5150
5151 /*******************************************************************************
5152 **
5153 **  gckHARDWARE_ProfileEngine2D
5154 **
5155 **  Read the profile registers available in the 2D engine and sets them in the
5156 **  profile.  The function will also reset the pixelsRendered counter every time.
5157 **
5158 **  INPUT:
5159 **
5160 **      gckHARDWARE Hardware
5161 **          Pointer to an gckHARDWARE object.
5162 **
5163 **      OPTIONAL gcs2D_PROFILE_PTR Profile
5164 **          Pointer to a gcs2D_Profile structure.
5165 **
5166 **  OUTPUT:
5167 **
5168 **      Nothing.
5169 */
5170 gceSTATUS
5171 gckHARDWARE_ProfileEngine2D(
5172     IN gckHARDWARE Hardware,
5173     OPTIONAL gcs2D_PROFILE_PTR Profile
5174     )
5175 {
5176     gceSTATUS status;
5177     gcs2D_PROFILE_PTR profiler = Profile;
5178
5179     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
5180
5181     /* Verify the arguments. */
5182     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
5183
5184     if (Profile != gcvNULL)
5185     {
5186         /* Read the cycle count. */
5187         gcmkONERROR(
5188             gckOS_ReadRegisterEx(Hardware->os,
5189                                  Hardware->core,
5190                                  0x00438,
5191                                  &Profile->cycleCount));
5192
5193         /* Read pixels rendered by 2D engine. */
5194         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5195 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pixelsRendered));
5196
5197         /* Reset counter. */
5198         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5199 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
5200 ));
5201     }
5202
5203     /* Success. */
5204     gcmkFOOTER_NO();
5205     return gcvSTATUS_OK;
5206
5207 OnError:
5208     /* Return the status. */
5209     gcmkFOOTER();
5210     return status;
5211 }
5212
5213 #if VIVANTE_PROFILER
5214 gceSTATUS
5215 gckHARDWARE_QueryProfileRegisters(
5216     IN gckHARDWARE Hardware,
5217     IN gctBOOL   Reset,
5218     OUT gcsPROFILER_COUNTERS * Counters
5219     )
5220 {
5221     gceSTATUS status;
5222     gcsPROFILER_COUNTERS * profiler = Counters;
5223     gctUINT i, clock;
5224     gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
5225     gctUINT32 totalRead, totalWrite;
5226
5227     gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
5228
5229     /* Verify the arguments. */
5230     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
5231
5232     /* Read the counters. */
5233     gcmkONERROR(
5234         gckOS_ReadRegisterEx(Hardware->os,
5235                              Hardware->core,
5236                              0x00438,
5237                              &profiler->gpuCyclesCounter));
5238
5239     gcmkONERROR(
5240         gckOS_ReadRegisterEx(Hardware->os,
5241                              Hardware->core,
5242                              0x00078,
5243                              &profiler->gpuTotalCyclesCounter));
5244
5245     gcmkONERROR(
5246         gckOS_ReadRegisterEx(Hardware->os,
5247                              Hardware->core,
5248                              0x0007C,
5249                              &profiler->gpuIdleCyclesCounter));
5250
5251
5252     /* Read clock control register. */
5253     gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
5254                                      Hardware->core,
5255                                      0x00000,
5256                                      &clock));
5257
5258     profiler->gpuTotalRead64BytesPerFrame = 0;
5259     profiler->gpuTotalWrite64BytesPerFrame = 0;
5260     profiler->pe_pixel_count_killed_by_color_pipe = 0;
5261     profiler->pe_pixel_count_killed_by_depth_pipe = 0;
5262     profiler->pe_pixel_count_drawn_by_color_pipe = 0;
5263     profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
5264
5265      /* Walk through all avaiable pixel pipes. */
5266     for (i = 0; i < Hardware->identity.pixelPipes; ++i)
5267     {
5268         /* Select proper pipe. */
5269         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
5270                                            Hardware->core,
5271                                            0x00000,
5272                                            ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
5273
5274         /* BW */
5275         gcmkONERROR(
5276         gckOS_ReadRegisterEx(Hardware->os,
5277                              Hardware->core,
5278                              0x00040,
5279                              &totalRead));
5280         gcmkONERROR(
5281         gckOS_ReadRegisterEx(Hardware->os,
5282                              Hardware->core,
5283                              0x00044,
5284                              &totalWrite));
5285
5286         profiler->gpuTotalRead64BytesPerFrame += totalRead;
5287         profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
5288
5289         /* PE */
5290         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorKilled));
5291         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthKilled));
5292         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorDrawn));
5293         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthDrawn));
5294
5295         profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
5296         profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
5297         profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
5298         profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
5299     }
5300
5301     /* Reset clock control register. */
5302     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
5303                                       Hardware->core,
5304                                       0x00000,
5305                                       clock));
5306
5307     if(Reset){
5308             /* Reset counters. */
5309             gcmkONERROR(
5310                 gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
5311             gcmkONERROR(
5312                 gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
5313             gcmkONERROR(
5314                 gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
5315             gcmkONERROR(
5316                 gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
5317             gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5318 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
5319 ));
5320     }
5321
5322     /* SH */
5323     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5324 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
5325     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5326 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
5327     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5328 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
5329     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5330 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
5331     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5332 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
5333     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5334 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
5335     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5336 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
5337     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5338 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
5339     if(Reset){  gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5340 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
5341 ));}
5342
5343     /* PA */
5344     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5345 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
5346     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5347 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
5348     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5349 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
5350     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5351 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
5352     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5353 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
5354     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5355 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
5356     if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5357 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
5358 ));}
5359
5360     /* SE */
5361     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5362 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
5363     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5364 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
5365     if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5366 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
5367 ));}
5368
5369     /* RA */
5370     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5371 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
5372     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5373 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
5374     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5375 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
5376     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5377 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
5378     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5379 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
5380     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5381 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
5382     if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5383 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
5384 ));}
5385
5386     /* TX */
5387     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5388 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
5389     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5390 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
5391     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5392 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
5393     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5394 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
5395     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5396 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
5397     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5398 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
5399     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5400 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
5401     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5402 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
5403     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5404 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
5405     if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5406 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
5407 ));}
5408
5409     /* MC */
5410     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5411 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
5412     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5413 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
5414     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5415 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
5416     if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5417 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
5418 ));}
5419
5420     /* HI */
5421     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5422 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
5423     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5424 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
5425     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5426 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
5427     if(Reset){ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5428 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
5429 ));}
5430
5431     /* Success. */
5432     gcmkFOOTER_NO();
5433     return gcvSTATUS_OK;
5434
5435 OnError:
5436     /* Return the status. */
5437     gcmkFOOTER();
5438     return status;
5439 }
5440 #endif
5441
5442 #if VIVANTE_PROFILER_CONTEXT
5443 #define gcmkUPDATE_PROFILE_DATA(data) \
5444     profilerHistroy->data += profiler->data
5445
5446 gceSTATUS
5447 gckHARDWARE_QueryContextProfile(
5448     IN gckHARDWARE Hardware,
5449     IN gctBOOL   Reset,
5450     IN gckCONTEXT Context,
5451     OUT gcsPROFILER_COUNTERS * Counters
5452     )
5453 {
5454     gceSTATUS status;
5455     gckCOMMAND command = Hardware->kernel->command;
5456     gcsPROFILER_COUNTERS * profiler = Counters;
5457
5458     gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
5459
5460     /* Verify the arguments. */
5461     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
5462
5463     /* Acquire the context sequnence mutex. */
5464     gcmkONERROR(gckOS_AcquireMutex(
5465         command->os, command->mutexContextSeq, gcvINFINITE
5466         ));
5467
5468     /* Read the counters. */
5469     gcmkVERIFY_OK(gckOS_MemCopy(
5470         profiler, &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
5471         ));
5472
5473     if (Reset)
5474     {
5475         /* Reset counters. */
5476         gcmkVERIFY_OK(gckOS_ZeroMemory(
5477             &Context->histroyProfiler, gcmSIZEOF(gcsPROFILER_COUNTERS)
5478             ));
5479     }
5480
5481     gcmkVERIFY_OK(gckOS_ReleaseMutex(
5482         command->os, command->mutexContextSeq
5483         ));
5484
5485     /* Success. */
5486     gcmkFOOTER_NO();
5487     return gcvSTATUS_OK;
5488
5489 OnError:
5490     /* Return the status. */
5491     gcmkFOOTER();
5492     return status;
5493 }
5494
5495
5496 gceSTATUS
5497 gckHARDWARE_UpdateContextProfile(
5498     IN gckHARDWARE Hardware,
5499     IN gckCONTEXT Context
5500     )
5501 {
5502     gceSTATUS status;
5503     gcsPROFILER_COUNTERS * profiler = &Context->latestProfiler;
5504     gcsPROFILER_COUNTERS * profilerHistroy = &Context->histroyProfiler;
5505     gctUINT i, clock;
5506     gctUINT32 colorKilled, colorDrawn, depthKilled, depthDrawn;
5507     gctUINT32 totalRead, totalWrite;
5508     gceCHIPMODEL chipModel;
5509     gctUINT32 chipRevision;
5510     gctUINT32 temp;
5511     gctBOOL needResetShader = gcvFALSE;
5512
5513     gcmkHEADER_ARG("Hardware=0x%x Context=0x%x", Hardware, Context);
5514
5515     /* Verify the arguments. */
5516     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
5517     gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
5518
5519     chipModel = Hardware->identity.chipModel;
5520     chipRevision = Hardware->identity.chipRevision;
5521     if (chipModel == gcv2000 || (chipModel == gcv2100 && chipRevision == 0x5118))
5522     {
5523         needResetShader = gcvTRUE;
5524     }
5525
5526     /* Read the counters. */
5527     gcmkONERROR(
5528         gckOS_ReadRegisterEx(Hardware->os,
5529                              Hardware->core,
5530                              0x00438,
5531                              &profiler->gpuCyclesCounter));
5532     gcmkUPDATE_PROFILE_DATA(gpuCyclesCounter);
5533
5534     gcmkONERROR(
5535         gckOS_ReadRegisterEx(Hardware->os,
5536                              Hardware->core,
5537                              0x00078,
5538                              &profiler->gpuTotalCyclesCounter));
5539     gcmkUPDATE_PROFILE_DATA(gpuTotalCyclesCounter);
5540
5541     gcmkONERROR(
5542         gckOS_ReadRegisterEx(Hardware->os,
5543                              Hardware->core,
5544                              0x0007C,
5545                              &profiler->gpuIdleCyclesCounter));
5546     gcmkUPDATE_PROFILE_DATA(gpuIdleCyclesCounter);
5547
5548     /* Read clock control register. */
5549     gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
5550                                      Hardware->core,
5551                                      0x00000,
5552                                      &clock));
5553
5554     profiler->gpuTotalRead64BytesPerFrame = 0;
5555     profiler->gpuTotalWrite64BytesPerFrame = 0;
5556     profiler->pe_pixel_count_killed_by_color_pipe = 0;
5557     profiler->pe_pixel_count_killed_by_depth_pipe = 0;
5558     profiler->pe_pixel_count_drawn_by_color_pipe = 0;
5559     profiler->pe_pixel_count_drawn_by_depth_pipe = 0;
5560
5561     /* Walk through all avaiable pixel pipes. */
5562     for (i = 0; i < Hardware->identity.pixelPipes; ++i)
5563     {
5564         /* Select proper pipe. */
5565         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
5566                                            Hardware->core,
5567                                            0x00000,
5568                                            ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
5569
5570         /* BW */
5571         gcmkONERROR(
5572         gckOS_ReadRegisterEx(Hardware->os,
5573                              Hardware->core,
5574                              0x00040,
5575                              &totalRead));
5576         gcmkONERROR(
5577         gckOS_ReadRegisterEx(Hardware->os,
5578                              Hardware->core,
5579                              0x00044,
5580                              &totalWrite));
5581
5582         profiler->gpuTotalRead64BytesPerFrame += totalRead;
5583         profiler->gpuTotalWrite64BytesPerFrame += totalWrite;
5584         gcmkUPDATE_PROFILE_DATA(gpuTotalRead64BytesPerFrame);
5585         gcmkUPDATE_PROFILE_DATA(gpuTotalWrite64BytesPerFrame);
5586
5587         /* PE */
5588         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorKilled));
5589         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthKilled));
5590         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &colorDrawn));
5591         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))));gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &depthDrawn));
5592
5593         profiler->pe_pixel_count_killed_by_color_pipe += colorKilled;
5594         profiler->pe_pixel_count_killed_by_depth_pipe += depthKilled;
5595         profiler->pe_pixel_count_drawn_by_color_pipe += colorDrawn;
5596         profiler->pe_pixel_count_drawn_by_depth_pipe += depthDrawn;
5597         gcmkUPDATE_PROFILE_DATA(pe_pixel_count_killed_by_color_pipe);
5598         gcmkUPDATE_PROFILE_DATA(pe_pixel_count_killed_by_depth_pipe);
5599         gcmkUPDATE_PROFILE_DATA(pe_pixel_count_drawn_by_color_pipe);
5600         gcmkUPDATE_PROFILE_DATA(pe_pixel_count_drawn_by_depth_pipe);
5601     }
5602
5603     /* Reset clock control register. */
5604     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
5605                                       Hardware->core,
5606                                       0x00000,
5607                                       clock));
5608
5609
5610
5611
5612     /* Reset counters. */
5613     gcmkONERROR(
5614         gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
5615     gcmkONERROR(
5616         gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
5617     gcmkONERROR(
5618         gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
5619     gcmkONERROR(
5620         gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
5621     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5622 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
5623 ));
5624
5625     /* SH */
5626     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5627 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
5628     if (needResetShader)
5629     {
5630         temp = profiler->ps_inst_counter;
5631         profiler->ps_inst_counter -= Context->prevPSInstCount;
5632         Context->prevPSInstCount = temp;
5633     }
5634     gcmkUPDATE_PROFILE_DATA(ps_inst_counter);
5635
5636     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5637 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
5638     if (needResetShader)
5639     {
5640         temp = profiler->rendered_pixel_counter;
5641         profiler->rendered_pixel_counter -= Context->prevPSPixelCount;
5642         Context->prevPSPixelCount = temp;
5643     }
5644     gcmkUPDATE_PROFILE_DATA(rendered_pixel_counter);
5645
5646     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5647 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
5648     if (needResetShader)
5649     {
5650         temp = profiler->vs_inst_counter;
5651         profiler->vs_inst_counter -= Context->prevVSInstCount;
5652         Context->prevVSInstCount = temp;
5653     }
5654     gcmkUPDATE_PROFILE_DATA(vs_inst_counter);
5655
5656     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5657 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
5658     if (needResetShader)
5659     {
5660         temp = profiler->rendered_vertice_counter;
5661         profiler->rendered_vertice_counter -= Context->prevVSVertexCount;
5662         Context->prevVSVertexCount = temp;
5663     }
5664     gcmkUPDATE_PROFILE_DATA(rendered_vertice_counter);
5665
5666     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5667 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
5668     if (needResetShader)
5669     {
5670         temp = profiler->vtx_branch_inst_counter;
5671         profiler->vtx_branch_inst_counter -= Context->prevVSBranchInstCount;
5672         Context->prevVSBranchInstCount = temp;
5673     }
5674     gcmkUPDATE_PROFILE_DATA(vtx_branch_inst_counter);
5675
5676     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5677 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
5678     if (needResetShader)
5679     {
5680         temp = profiler->vtx_texld_inst_counter;
5681         profiler->vtx_texld_inst_counter -= Context->prevVSTexInstCount;
5682         Context->prevVSTexInstCount = temp;
5683     }
5684     gcmkUPDATE_PROFILE_DATA(vtx_texld_inst_counter);
5685
5686     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5687 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
5688     if (needResetShader)
5689     {
5690         temp = profiler->pxl_branch_inst_counter;
5691         profiler->pxl_branch_inst_counter -= Context->prevPSBranchInstCount;
5692         Context->prevPSBranchInstCount = temp;
5693     }
5694     gcmkUPDATE_PROFILE_DATA(pxl_branch_inst_counter);
5695
5696     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5697 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
5698     if (needResetShader)
5699     {
5700         temp = profiler->pxl_texld_inst_counter;
5701         profiler->pxl_texld_inst_counter -= Context->prevPSTexInstCount;
5702         Context->prevPSTexInstCount = temp;
5703     }
5704     gcmkUPDATE_PROFILE_DATA(pxl_texld_inst_counter);
5705
5706     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5707 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
5708 ));
5709
5710     /* PA */
5711     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5712 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
5713     gcmkUPDATE_PROFILE_DATA(pa_input_vtx_counter);
5714     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5715 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
5716     gcmkUPDATE_PROFILE_DATA(pa_input_prim_counter);
5717     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5718 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
5719     gcmkUPDATE_PROFILE_DATA(pa_output_prim_counter);
5720     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5721 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
5722     gcmkUPDATE_PROFILE_DATA(pa_depth_clipped_counter);
5723     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5724 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
5725     gcmkUPDATE_PROFILE_DATA(pa_trivial_rejected_counter);
5726     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5727 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
5728     gcmkUPDATE_PROFILE_DATA(pa_culled_counter);
5729     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5730 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
5731 ));
5732
5733     /* SE */
5734     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5735 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
5736     gcmkUPDATE_PROFILE_DATA(se_culled_triangle_count);
5737     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5738 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
5739     gcmkUPDATE_PROFILE_DATA(se_culled_lines_count);
5740     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5741 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
5742 ));
5743
5744     /* RA */
5745     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5746 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
5747     gcmkUPDATE_PROFILE_DATA(ra_valid_pixel_count);
5748     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5749 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
5750     gcmkUPDATE_PROFILE_DATA(ra_total_quad_count);
5751     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5752 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
5753     gcmkUPDATE_PROFILE_DATA(ra_valid_quad_count_after_early_z);
5754     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5755 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
5756     gcmkUPDATE_PROFILE_DATA(ra_total_primitive_count);
5757     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5758 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
5759     gcmkUPDATE_PROFILE_DATA(ra_pipe_cache_miss_counter);
5760     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5761 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
5762     gcmkUPDATE_PROFILE_DATA(ra_prefetch_cache_miss_counter);
5763     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) ));
5764 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 23:16) - (0 ? 23:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
5765 ));
5766
5767     /* TX */
5768     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5769 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
5770     gcmkUPDATE_PROFILE_DATA(tx_total_bilinear_requests);
5771     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5772 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
5773     gcmkUPDATE_PROFILE_DATA(tx_total_trilinear_requests);
5774     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5775 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
5776     gcmkUPDATE_PROFILE_DATA(tx_total_discarded_texture_requests);
5777     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5778 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
5779     gcmkUPDATE_PROFILE_DATA(tx_total_texture_requests);
5780     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5781 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
5782     gcmkUPDATE_PROFILE_DATA(tx_mem_read_count);
5783     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5784 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
5785     gcmkUPDATE_PROFILE_DATA(tx_mem_read_in_8B_count);
5786     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5787 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
5788     gcmkUPDATE_PROFILE_DATA(tx_cache_miss_count);
5789     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5790 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
5791     gcmkUPDATE_PROFILE_DATA(tx_cache_hit_texel_count);
5792     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5793 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
5794     gcmkUPDATE_PROFILE_DATA(tx_cache_miss_texel_count);
5795     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) ));
5796 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1))))))) << (0 ? 31:24)))
5797 ));
5798
5799     /* MC */
5800     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5801 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
5802     gcmkUPDATE_PROFILE_DATA(mc_total_read_req_8B_from_pipeline);
5803     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5804 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
5805     gcmkUPDATE_PROFILE_DATA(mc_total_read_req_8B_from_IP);
5806     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5807 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
5808     gcmkUPDATE_PROFILE_DATA(mc_total_write_req_8B_from_pipeline);
5809     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) ));
5810 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
5811 ));
5812
5813     /* HI */
5814     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5815 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
5816     gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_read_request_stalled);
5817     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5818 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
5819     gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_write_request_stalled);
5820     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5821 gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
5822     gcmkUPDATE_PROFILE_DATA(hi_axi_cycles_write_data_stalled);
5823     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) ));
5824 gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478,   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))
5825 ));
5826
5827     /* Success. */
5828     gcmkFOOTER_NO();
5829     return gcvSTATUS_OK;
5830
5831 OnError:
5832     /* Return the status. */
5833     gcmkFOOTER();
5834     return status;
5835 }
5836 #endif
5837
5838 static gceSTATUS
5839 _ResetGPU(
5840     IN gckHARDWARE Hardware,
5841     IN gckOS Os,
5842     IN gceCORE Core
5843     )
5844 {
5845     gctUINT32 control, idle;
5846     gceSTATUS status;
5847
5848     for (;;)
5849     {
5850         /* Disable clock gating. */
5851         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5852                     Core,
5853                     Hardware->powerBaseAddress +
5854                     0x00104,
5855                     0x00000000));
5856
5857         control = ((((gctUINT32) (0x01590880)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17)));
5858
5859         /* Disable pulse-eater. */
5860         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5861                     Core,
5862                     0x0010C,
5863                     control));
5864
5865         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5866                     Core,
5867                     0x0010C,
5868                     ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))));
5869
5870         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5871                     Core,
5872                     0x0010C,
5873                     control));
5874
5875         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5876                     Core,
5877                     0x00000,
5878                     ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
5879
5880         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5881                     Core,
5882                     0x00000,
5883                     0x00000900));
5884
5885         /* Wait for clock being stable. */
5886         gcmkONERROR(gckOS_Delay(Os, 1));
5887
5888         /* Isolate the GPU. */
5889         control = ((((gctUINT32) (0x00000900)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
5890
5891         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5892                                           Core,
5893                                           0x00000,
5894                                           control));
5895
5896         /* Set soft reset. */
5897         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5898                                           Core,
5899                                           0x00000,
5900                                           ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
5901
5902         /* Wait for reset. */
5903         gcmkONERROR(gckOS_Delay(Os, 1));
5904
5905         /* Reset soft reset bit. */
5906         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5907                                           Core,
5908                                           0x00000,
5909                                           ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
5910
5911         /* Reset GPU isolation. */
5912         control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
5913
5914         gcmkONERROR(gckOS_WriteRegisterEx(Os,
5915                                           Core,
5916                                           0x00000,
5917                                           control));
5918
5919         /* Read idle register. */
5920         gcmkONERROR(gckOS_ReadRegisterEx(Os,
5921                                          Core,
5922                                          0x00004,
5923                                          &idle));
5924
5925         if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0)
5926         {
5927             continue;
5928         }
5929
5930         /* Read reset register. */
5931         gcmkONERROR(gckOS_ReadRegisterEx(Os,
5932                                          Core,
5933                                          0x00000,
5934                                          &control));
5935
5936         if (((((((gctUINT32) (control)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0)
5937         ||  ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
5938         )
5939         {
5940             continue;
5941         }
5942
5943         /* GPU is idle. */
5944         break;
5945     }
5946
5947     /* Success. */
5948     return gcvSTATUS_OK;
5949
5950 OnError:
5951
5952     /* Return the error. */
5953     return status;
5954 }
5955
5956 gceSTATUS
5957 gckHARDWARE_Reset(
5958     IN gckHARDWARE Hardware
5959     )
5960 {
5961     gceSTATUS status;
5962     gckCOMMAND command;
5963     gctBOOL acquired = gcvFALSE;
5964     gctBOOL mutexAcquired = gcvFALSE;
5965     gctUINT32 process, thread;
5966
5967     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
5968
5969     /* Verify the arguments. */
5970     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
5971     gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
5972     command = Hardware->kernel->command;
5973     gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
5974
5975     if (Hardware->identity.chipRevision < 0x4600)
5976     {
5977         /* Not supported - we need the isolation bit. */
5978         gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
5979     }
5980
5981     status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0);
5982     if (status == gcvSTATUS_TIMEOUT)
5983     {
5984         gcmkONERROR(gckOS_GetProcessID(&process));
5985         gcmkONERROR(gckOS_GetThreadID(&thread));
5986
5987         if ((Hardware->powerProcess == process)
5988         &&  (Hardware->powerThread  == thread))
5989         {
5990             /* No way to recovery from a error in power management. */
5991             gcmkFOOTER_NO();
5992             return gcvSTATUS_OK;
5993         }
5994     }
5995     else
5996     {
5997         mutexAcquired = gcvTRUE;
5998     }
5999
6000     if (Hardware->chipPowerState == gcvPOWER_ON)
6001     {
6002         /* Acquire the power management semaphore. */
6003         gcmkONERROR(
6004             gckOS_AcquireSemaphore(Hardware->os, command->powerSemaphore));
6005         acquired = gcvTRUE;
6006     }
6007
6008     if ((Hardware->chipPowerState == gcvPOWER_ON)
6009     ||  (Hardware->chipPowerState == gcvPOWER_IDLE)
6010     )
6011     {
6012         /* Stop the command processor. */
6013         gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE));
6014     }
6015
6016     /* Stop isr, we will start it again when power on GPU. */
6017     if (Hardware->stopIsr)
6018     {
6019         gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
6020     }
6021
6022     /* Hardware reset. */
6023     status = gckOS_ResetGPU(Hardware->os, Hardware->core);
6024
6025     if (gcmIS_ERROR(status))
6026     {
6027         /* Soft reset. */
6028         gcmkONERROR(_ResetGPU(Hardware, Hardware->os, Hardware->core));
6029     }
6030
6031     /* Force an OFF to ON power switch. */
6032     Hardware->chipPowerState = gcvPOWER_OFF;
6033
6034     gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
6035     mutexAcquired = gcvFALSE;
6036
6037     /* Success. */
6038     gcmkFOOTER_NO();
6039     return gcvSTATUS_OK;
6040
6041 OnError:
6042     if (acquired)
6043     {
6044         /* Release the power management semaphore. */
6045         gcmkVERIFY_OK(
6046             gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore));
6047     }
6048
6049     if (mutexAcquired)
6050     {
6051         gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
6052     }
6053
6054     /* Return the error. */
6055     gcmkFOOTER();
6056     return status;
6057 }
6058
6059 gceSTATUS
6060 gckHARDWARE_GetBaseAddress(
6061     IN gckHARDWARE Hardware,
6062     OUT gctUINT32_PTR BaseAddress
6063     )
6064 {
6065     gceSTATUS status;
6066
6067     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
6068
6069     /* Verify the arguments. */
6070     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
6071     gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
6072
6073     /* Test if we have a new Memory Controller. */
6074     if (((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 22:22) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1))))))))
6075     {
6076         /* No base address required. */
6077         *BaseAddress = 0;
6078     }
6079     else
6080     {
6081         /* Get the base address from the OS. */
6082         gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, BaseAddress));
6083     }
6084
6085     /* Success. */
6086     gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
6087     return gcvSTATUS_OK;
6088
6089 OnError:
6090     /* Return the status. */
6091     gcmkFOOTER();
6092     return status;
6093 }
6094
6095 gceSTATUS
6096 gckHARDWARE_NeedBaseAddress(
6097     IN gckHARDWARE Hardware,
6098     IN gctUINT32 State,
6099     OUT gctBOOL_PTR NeedBase
6100     )
6101 {
6102     gctBOOL need = gcvFALSE;
6103
6104     gcmkHEADER_ARG("Hardware=0x%x State=0x%08x", Hardware, State);
6105
6106     /* Verify the arguments. */
6107     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
6108     gcmkVERIFY_ARGUMENT(NeedBase != gcvNULL);
6109
6110     /* Make sure this is a load state. */
6111     if (((((gctUINT32) (State)) >> (0 ? 31:27) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))))
6112     {
6113 #ifndef VIVANTE_NO_3D
6114         /* Get the state address. */
6115         switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) ))
6116         {
6117         case 0x0596:
6118         case 0x0597:
6119         case 0x0599:
6120         case 0x059A:
6121         case 0x05A9:
6122             /* These states need a TRUE physical address. */
6123             need = gcvTRUE;
6124             break;
6125         }
6126 #else
6127         /* 2D addresses don't need a base address. */
6128 #endif
6129     }
6130
6131     /* Return the flag. */
6132     *NeedBase = need;
6133
6134     /* Success. */
6135     gcmkFOOTER_ARG("*NeedBase=%d", *NeedBase);
6136     return gcvSTATUS_OK;
6137 }
6138
6139 gceSTATUS
6140 gckHARDWARE_SetIsrManager(
6141    IN gckHARDWARE Hardware,
6142    IN gctISRMANAGERFUNC StartIsr,
6143    IN gctISRMANAGERFUNC StopIsr,
6144    IN gctPOINTER Context
6145    )
6146 {
6147     gceSTATUS status = gcvSTATUS_OK;
6148
6149     gcmkHEADER_ARG("Hardware=0x%x, StartIsr=0x%x, StopIsr=0x%x, Context=0x%x",
6150                    Hardware, StartIsr, StopIsr, Context);
6151
6152     /* Verify the arguments. */
6153     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
6154
6155     if (StartIsr == gcvNULL ||
6156         StopIsr == gcvNULL ||
6157         Context == gcvNULL)
6158     {
6159         status = gcvSTATUS_INVALID_ARGUMENT;
6160
6161         gcmkFOOTER();
6162         return status;
6163     }
6164
6165     Hardware->startIsr = StartIsr;
6166     Hardware->stopIsr = StopIsr;
6167     Hardware->isrContext = Context;
6168
6169     /* Success. */
6170     gcmkFOOTER();
6171
6172     return status;
6173 }
6174
6175 /*******************************************************************************
6176 **
6177 **  gckHARDWARE_Compose
6178 **
6179 **  Start a composition.
6180 **
6181 **  INPUT:
6182 **
6183 **      gckHARDWARE Hardware
6184 **          Pointer to the gckHARDWARE object.
6185 **
6186 **  OUTPUT:
6187 **
6188 **      Nothing.
6189 */
6190 gceSTATUS
6191 gckHARDWARE_Compose(
6192     IN gckHARDWARE Hardware,
6193     IN gctUINT32 ProcessID,
6194     IN gctPHYS_ADDR Physical,
6195     IN gctPOINTER Logical,
6196     IN gctSIZE_T Offset,
6197     IN gctSIZE_T Size,
6198     IN gctUINT8 EventID
6199     )
6200 {
6201 #ifndef VIVANTE_NO_3D
6202     gceSTATUS status;
6203     gctUINT32_PTR triggerState;
6204
6205     gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x Logical=0x%x"
6206                    " Offset=%d Size=%d EventID=%d",
6207                    Hardware, Physical, Logical, Offset, Size, EventID);
6208
6209     /* Verify the arguments. */
6210     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
6211     gcmkVERIFY_ARGUMENT(((Size + 8) & 63) == 0);
6212     gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
6213
6214     /* Program the trigger state. */
6215     triggerState = (gctUINT32_PTR) ((gctUINT8_PTR) Logical + Offset + Size);
6216     triggerState[0] = 0x0C03;
6217     triggerState[1]
6218         = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)))
6219         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:4) - (0 ? 5:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:4) - (0 ? 5:4) + 1))))))) << (0 ? 5:4))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 5:4) - (0 ? 5:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:4) - (0 ? 5:4) + 1))))))) << (0 ? 5:4)))
6220         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
6221         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24)))
6222         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))
6223         | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:16) - (0 ? 20:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16))) | (((gctUINT32) ((gctUINT32) (EventID) & ((gctUINT32) ((((1 ? 20:16) - (0 ? 20:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16)))
6224         ;
6225
6226 #if gcdNONPAGED_MEMORY_CACHEABLE
6227     /* Flush the cache for the wait/link. */
6228     gcmkONERROR(gckOS_CacheClean(
6229         Hardware->os, ProcessID, gcvNULL,
6230         Physical, Logical, Offset + Size
6231         ));
6232 #endif
6233
6234     /* Start composition. */
6235     gcmkONERROR(gckOS_WriteRegisterEx(
6236         Hardware->os, Hardware->core, 0x00554,
6237         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)))
6238         ));
6239
6240     /* Success. */
6241     gcmkFOOTER_NO();
6242     return gcvSTATUS_OK;
6243
6244 OnError:
6245     /* Return the status. */
6246     gcmkFOOTER();
6247     return status;
6248 #else
6249     /* Return the status. */
6250     return gcvSTATUS_NOT_SUPPORTED;
6251 #endif
6252 }
6253
6254 /*******************************************************************************
6255 **
6256 **  gckHARDWARE_IsFeatureAvailable
6257 **
6258 **  Verifies whether the specified feature is available in hardware.
6259 **
6260 **  INPUT:
6261 **
6262 **      gckHARDWARE Hardware
6263 **          Pointer to an gckHARDWARE object.
6264 **
6265 **      gceFEATURE Feature
6266 **          Feature to be verified.
6267 */
6268 gceSTATUS
6269 gckHARDWARE_IsFeatureAvailable(
6270     IN gckHARDWARE Hardware,
6271     IN gceFEATURE Feature
6272     )
6273 {
6274     gctBOOL available;
6275
6276     gcmkHEADER_ARG("Hardware=0x%x Feature=%d", Hardware, Feature);
6277
6278     /* Verify the arguments. */
6279     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
6280
6281     /* Only features needed by common kernel logic added here. */
6282     switch (Feature)
6283     {
6284     case gcvFEATURE_END_EVENT:
6285         /*available = gcmVERIFYFIELDVALUE(Hardware->identity.chipMinorFeatures2,
6286             GC_MINOR_FEATURES2, END_EVENT, AVAILABLE
6287             );*/
6288         available = gcvFALSE;
6289         break;
6290     case gcvFEATURE_MC20:
6291         available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures)) >> (0 ? 22:22) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) == (0x1  & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))));
6292         break;
6293     case gcvFEATURE_DYNAMIC_FREQUENCY_SCALING:
6294         /* This feature doesn't apply for 2D cores. */
6295         available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 14:14) & ((gctUINT32) ((((1 ? 14:14) - (0 ? 14:14) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 14:14) - (0 ? 14:14) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 14:14) - (0 ? 14:14) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 14:14) - (0 ? 14:14) + 1)))))))
6296             &&      ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 2:2) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))));
6297         break;
6298
6299     case gcvFEATURE_PIPE_2D:
6300         available = ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 9:9) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) == (0x1  & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))));
6301         break;
6302
6303     case gcvFEATURE_PIPE_3D:
6304 #ifndef VIVANTE_NO_3D
6305         available = ((((gctUINT32) (Hardware->identity.chipFeatures)) >> (0 ? 2:2) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) == (0x1  & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))));
6306 #else
6307         available = gcvFALSE;
6308 #endif
6309         break;
6310
6311     case gcvFEATURE_HALTI2:
6312         available = ((((gctUINT32) (Hardware->identity.chipMinorFeatures4)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))));
6313         break;
6314
6315     default:
6316         gcmkFATAL("Invalid feature has been requested.");
6317         available = gcvFALSE;
6318     }
6319
6320     /* Return result. */
6321     gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_OK);
6322     return available ? gcvSTATUS_TRUE : gcvSTATUS_OK;
6323 }
6324
6325 /*******************************************************************************
6326 **
6327 **  gckHARDWARE_DumpMMUException
6328 **
6329 **  Dump the MMU debug info on an MMU exception.
6330 **
6331 **  INPUT:
6332 **
6333 **      gckHARDWARE Harwdare
6334 **          Pointer to an gckHARDWARE object.
6335 **
6336 **  OUTPUT:
6337 **
6338 **      Nothing.
6339 */
6340 gceSTATUS
6341 gckHARDWARE_DumpMMUException(
6342     IN gckHARDWARE Hardware
6343     )
6344 {
6345 #if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT
6346     gctUINT32 mmu, mmuStatus, address, i;
6347 #if gcdDEBUG
6348     gctUINT32 mtlb, stlb, offset;
6349 #endif
6350
6351     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
6352
6353     /* Verify the arguments. */
6354     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
6355
6356     gcmkPRINT("GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
6357               Hardware->core,
6358               Hardware->identity.chipModel,
6359               Hardware->identity.chipRevision);
6360
6361     gcmkPRINT("**************************\n");
6362     gcmkPRINT("***   MMU ERROR DUMP   ***\n");
6363     gcmkPRINT("**************************\n");
6364
6365     gcmkVERIFY_OK(
6366         gckOS_ReadRegisterEx(Hardware->os,
6367                              Hardware->core,
6368                              0x00188,
6369                              &mmuStatus));
6370
6371     gcmkPRINT("  MMU status = 0x%08X\n", mmuStatus);
6372
6373     for (i = 0; i < 4; i += 1)
6374     {
6375         mmu = mmuStatus & 0xF;
6376         mmuStatus >>= 4;
6377
6378         if (mmu == 0)
6379         {
6380             continue;
6381         }
6382
6383         switch (mmu)
6384         {
6385         case 1:
6386               gcmkPRINT("  MMU%d: slave not present\n", i);
6387               break;
6388
6389         case 2:
6390               gcmkPRINT("  MMU%d: page not present\n", i);
6391               break;
6392
6393         case 3:
6394               gcmkPRINT("  MMU%d: write violation\n", i);
6395               break;
6396
6397         default:
6398               gcmkPRINT("  MMU%d: unknown state\n", i);
6399         }
6400
6401         gcmkVERIFY_OK(
6402             gckOS_ReadRegisterEx(Hardware->os,
6403                                  Hardware->core,
6404                                  0x00190 + i * 4,
6405                                  &address));
6406
6407         mtlb   = (address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
6408         stlb   = (address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
6409         offset =  address & gcdMMU_OFFSET_4K_MASK;
6410
6411         gcmkPRINT("  MMU%d: exception address = 0x%08X\n", i, address);
6412
6413         gcmkPRINT("    MTLB entry = %d\n", mtlb);
6414
6415         gcmkPRINT("    STLB entry = %d\n", stlb);
6416
6417         gcmkPRINT("    Offset = 0x%08X (%d)\n", offset, offset);
6418
6419         gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
6420
6421     }
6422
6423         gcmkFOOTER_NO();
6424 #else
6425     /* If clock could be off automatically, we can't read mmu debug
6426     ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0
6427     ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */
6428     gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__);
6429 #endif
6430
6431     return gcvSTATUS_OK;
6432 }
6433
6434 /*******************************************************************************
6435 **
6436 **  gckHARDWARE_DumpGPUState
6437 **
6438 **  Dump the GPU debug registers.
6439 **
6440 **  INPUT:
6441 **
6442 **      gckHARDWARE Harwdare
6443 **          Pointer to an gckHARDWARE object.
6444 **
6445 **  OUTPUT:
6446 **
6447 **      Nothing.
6448 */
6449 gceSTATUS
6450 gckHARDWARE_DumpGPUState(
6451     IN gckHARDWARE Hardware
6452     )
6453 {
6454     static gctCONST_STRING _cmdState[] =
6455     {
6456         "PAR_IDLE_ST", "PAR_DEC_ST", "PAR_ADR0_ST", "PAR_LOAD0_ST",
6457         "PAR_ADR1_ST", "PAR_LOAD1_ST", "PAR_3DADR_ST", "PAR_3DCMD_ST",
6458         "PAR_3DCNTL_ST", "PAR_3DIDXCNTL_ST", "PAR_INITREQDMA_ST",
6459         "PAR_DRAWIDX_ST", "PAR_DRAW_ST", "PAR_2DRECT0_ST", "PAR_2DRECT1_ST",
6460         "PAR_2DDATA0_ST", "PAR_2DDATA1_ST", "PAR_WAITFIFO_ST", "PAR_WAIT_ST",
6461         "PAR_LINK_ST", "PAR_END_ST", "PAR_STALL_ST"
6462     };
6463
6464     static gctCONST_STRING _cmdDmaState[] =
6465     {
6466         "CMD_IDLE_ST", "CMD_START_ST", "CMD_REQ_ST", "CMD_END_ST"
6467     };
6468
6469     static gctCONST_STRING _cmdFetState[] =
6470     {
6471         "FET_IDLE_ST", "FET_RAMVALID_ST", "FET_VALID_ST"
6472     };
6473
6474     static gctCONST_STRING _reqDmaState[] =
6475     {
6476         "REQ_IDLE_ST", "REQ_WAITIDX_ST", "REQ_CAL_ST"
6477     };
6478
6479     static gctCONST_STRING _calState[] =
6480     {
6481         "CAL_IDLE_ST", "CAL_LDADR_ST", "CAL_IDXCALC_ST"
6482     };
6483
6484     static gctCONST_STRING _veReqState[] =
6485     {
6486         "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST"
6487     };
6488
6489     static gcsiDEBUG_REGISTERS _dbgRegs[] =
6490     {
6491         { "RA", 0x474, 16, 0x448, 16, 0x12344321 },
6492         { "TX", 0x474, 24, 0x44C, 16, 0x12211221 },
6493         { "FE", 0x470, 0, 0x450, 16, 0xBABEF00D },
6494         { "PE", 0x470, 16, 0x454, 16, 0xBABEF00D },
6495         { "DE", 0x470, 8, 0x458, 16, 0xBABEF00D },
6496         { "SH", 0x470, 24, 0x45C, 16, 0xDEADBEEF },
6497         { "PA", 0x474, 0, 0x460, 16, 0x0000AAAA },
6498         { "SE", 0x474, 8, 0x464, 16, 0x5E5E5E5E },
6499         { "MC", 0x478, 0, 0x468, 16, 0x12345678 },
6500         { "HI", 0x478, 8, 0x46C, 16, 0xAAAAAAAA }
6501     };
6502
6503     static gctUINT32 _otherRegs[] =
6504     {
6505         0x040, 0x044, 0x04C, 0x050, 0x054, 0x058, 0x05C, 0x060,
6506         0x43c, 0x440, 0x444, 0x414,
6507     };
6508
6509     gceSTATUS status;
6510     gckKERNEL kernel;
6511     gctUINT32 idle, axi;
6512     gctUINT32 dmaAddress1, dmaAddress2;
6513     gctUINT32 dmaState1, dmaState2;
6514     gctUINT32 dmaLow, dmaHigh;
6515     gctUINT32 cmdState, cmdDmaState, cmdFetState;
6516     gctUINT32 dmaReqState, calState, veReqState;
6517     gctUINT i;
6518     gctUINT pipe, pixelPipes;
6519     gctUINT32 control, oldControl;
6520     gckOS os = Hardware->os;
6521     gceCORE core = Hardware->core;
6522
6523     gcmkHEADER_ARG("Hardware=0x%X", Hardware);
6524
6525     kernel = Hardware->kernel;
6526
6527     gcmkPRINT_N(12, "GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
6528                 core,
6529                 Hardware->identity.chipModel,
6530                 Hardware->identity.chipRevision);
6531
6532     pixelPipes = Hardware->identity.pixelPipes
6533                ? Hardware->identity.pixelPipes
6534                : 1;
6535
6536     /* Reset register values. */
6537     idle        = axi         =
6538     dmaState1   = dmaState2   =
6539     dmaAddress1 = dmaAddress2 =
6540     dmaLow      = dmaHigh     = 0;
6541
6542     /* Verify whether DMA is running. */
6543     gcmkONERROR(_VerifyDMA(
6544         os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
6545         ));
6546
6547     cmdState    =  dmaState2        & 0x1F;
6548     cmdDmaState = (dmaState2 >>  8) & 0x03;
6549     cmdFetState = (dmaState2 >> 10) & 0x03;
6550     dmaReqState = (dmaState2 >> 12) & 0x03;
6551     calState    = (dmaState2 >> 14) & 0x03;
6552     veReqState  = (dmaState2 >> 16) & 0x03;
6553
6554     gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x004, &idle));
6555     gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x00C, &axi));
6556     gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x668, &dmaLow));
6557     gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x66C, &dmaHigh));
6558
6559     gcmkPRINT_N(0, "**************************\n");
6560     gcmkPRINT_N(0, "***   GPU STATE DUMP   ***\n");
6561     gcmkPRINT_N(0, "**************************\n");
6562
6563     gcmkPRINT_N(4, "  axi      = 0x%08X\n", axi);
6564
6565     gcmkPRINT_N(4, "  idle     = 0x%08X\n", idle);
6566     if ((idle & 0x00000001) == 0) gcmkPRINT_N(0, "    FE not idle\n");
6567     if ((idle & 0x00000002) == 0) gcmkPRINT_N(0, "    DE not idle\n");
6568     if ((idle & 0x00000004) == 0) gcmkPRINT_N(0, "    PE not idle\n");
6569     if ((idle & 0x00000008) == 0) gcmkPRINT_N(0, "    SH not idle\n");
6570     if ((idle & 0x00000010) == 0) gcmkPRINT_N(0, "    PA not idle\n");
6571     if ((idle & 0x00000020) == 0) gcmkPRINT_N(0, "    SE not idle\n");
6572     if ((idle & 0x00000040) == 0) gcmkPRINT_N(0, "    RA not idle\n");
6573     if ((idle & 0x00000080) == 0) gcmkPRINT_N(0, "    TX not idle\n");
6574     if ((idle & 0x00000100) == 0) gcmkPRINT_N(0, "    VG not idle\n");
6575     if ((idle & 0x00000200) == 0) gcmkPRINT_N(0, "    IM not idle\n");
6576     if ((idle & 0x00000400) == 0) gcmkPRINT_N(0, "    FP not idle\n");
6577     if ((idle & 0x00000800) == 0) gcmkPRINT_N(0, "    TS not idle\n");
6578     if ((idle & 0x80000000) != 0) gcmkPRINT_N(0, "    AXI low power mode\n");
6579
6580     if (
6581         (dmaAddress1 == dmaAddress2)
6582      && (dmaState1 == dmaState2)
6583     )
6584     {
6585         gcmkPRINT_N(0, "  DMA appears to be stuck at this address:\n");
6586         gcmkPRINT_N(4, "    0x%08X\n", dmaAddress1);
6587     }
6588     else
6589     {
6590         if (dmaAddress1 == dmaAddress2)
6591         {
6592             gcmkPRINT_N(0, "  DMA address is constant, but state is changing:\n");
6593             gcmkPRINT_N(4, "    0x%08X\n", dmaState1);
6594             gcmkPRINT_N(4, "    0x%08X\n", dmaState2);
6595         }
6596         else
6597         {
6598             gcmkPRINT_N(0, "  DMA is running; known addresses are:\n");
6599             gcmkPRINT_N(4, "    0x%08X\n", dmaAddress1);
6600             gcmkPRINT_N(4, "    0x%08X\n", dmaAddress2);
6601         }
6602     }
6603     gcmkPRINT_N(4, "  dmaLow   = 0x%08X\n", dmaLow);
6604     gcmkPRINT_N(4, "  dmaHigh  = 0x%08X\n", dmaHigh);
6605     gcmkPRINT_N(4, "  dmaState = 0x%08X\n", dmaState2);
6606     gcmkPRINT_N(8, "    command state       = %d (%s)\n", cmdState, _cmdState   [cmdState]);
6607     gcmkPRINT_N(8, "    command DMA state   = %d (%s)\n", cmdDmaState, _cmdDmaState[cmdDmaState]);
6608     gcmkPRINT_N(8, "    command fetch state = %d (%s)\n", cmdFetState, _cmdFetState[cmdFetState]);
6609     gcmkPRINT_N(8, "    DMA request state   = %d (%s)\n", dmaReqState, _reqDmaState[dmaReqState]);
6610     gcmkPRINT_N(8, "    cal state           = %d (%s)\n", calState, _calState   [calState]);
6611     gcmkPRINT_N(8, "    VE request state    = %d (%s)\n", veReqState, _veReqState [veReqState]);
6612
6613     /* Record control. */
6614     gckOS_ReadRegisterEx(os, core, 0x0, &oldControl);
6615
6616     for (pipe = 0; pipe < pixelPipes; pipe++)
6617     {
6618         gcmkPRINT_N(4, "  Debug registers of pipe[%d]:\n", pipe);
6619
6620         /* Switch pipe. */
6621         gckOS_ReadRegisterEx(os, core, 0x0, &control);
6622         control &= ~(0xF << 20);
6623         control |= (pipe << 20);
6624         gckOS_WriteRegisterEx(os, core, 0x0, control);
6625
6626         for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
6627         {
6628             gcmkONERROR(_DumpDebugRegisters(os, core, &_dbgRegs[i]));
6629         }
6630
6631         gcmkPRINT_N(0, "    Other Registers:\n");
6632         for (i = 0; i < gcmCOUNTOF(_otherRegs); i += 1)
6633         {
6634             gctUINT32 read;
6635             gcmkONERROR(gckOS_ReadRegisterEx(os, core, _otherRegs[i], &read));
6636             gcmkPRINT_N(12, "      [0x%04X] 0x%08X\n", _otherRegs[i], read);
6637         }
6638     }
6639
6640     if (kernel->hardware->identity.chipFeatures & (1 << 4))
6641     {
6642         gctUINT32 read0, read1, write;
6643
6644         read0 = read1 = write = 0;
6645
6646         gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x43C, &read0));
6647         gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x440, &read1));
6648         gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x444, &write));
6649
6650         gcmkPRINT_N(4, "  read0    = 0x%08X\n", read0);
6651         gcmkPRINT_N(4, "  read1    = 0x%08X\n", read1);
6652         gcmkPRINT_N(4, "  write    = 0x%08X\n", write);
6653     }
6654
6655     /* Restore control. */
6656     gckOS_WriteRegisterEx(os, core, 0x0, oldControl);
6657
6658     /* dump stack. */
6659     gckOS_DumpCallStack(os);
6660
6661 OnError:
6662
6663     /* Return the error. */
6664     gcmkFOOTER();
6665     return status;
6666 }
6667
6668
6669 #if gcdFRAME_DB
6670 static gceSTATUS
6671 gckHARDWARE_ReadPerformanceRegister(
6672     IN gckHARDWARE Hardware,
6673     IN gctUINT PerformanceAddress,
6674     IN gctUINT IndexAddress,
6675     IN gctUINT IndexShift,
6676     IN gctUINT Index,
6677     OUT gctUINT32_PTR Value
6678     )
6679 {
6680     gceSTATUS status;
6681
6682     gcmkHEADER_ARG("Hardware=0x%x PerformanceAddress=0x%x IndexAddress=0x%x "
6683                    "IndexShift=%u Index=%u",
6684                    Hardware, PerformanceAddress, IndexAddress, IndexShift,
6685                    Index);
6686
6687     /* Write the index. */
6688     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
6689                                       Hardware->core,
6690                                       IndexAddress,
6691                                       Index << IndexShift));
6692
6693     /* Read the register. */
6694     gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6695                                      Hardware->core,
6696                                      PerformanceAddress,
6697                                      Value));
6698
6699     /* Test for reset. */
6700     if (Index == 15)
6701     {
6702         /* Index another register to get out of reset. */
6703         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, IndexAddress, 0));
6704     }
6705
6706     /* Success. */
6707     gcmkFOOTER_ARG("*Value=0x%x", *Value);
6708     return gcvSTATUS_OK;
6709
6710 OnError:
6711     /* Return the status. */
6712     gcmkFOOTER();
6713     return status;
6714 }
6715
6716 gceSTATUS
6717 gckHARDWARE_GetFrameInfo(
6718     IN gckHARDWARE Hardware,
6719     OUT gcsHAL_FRAME_INFO * FrameInfo
6720     )
6721 {
6722     gceSTATUS status;
6723     gctUINT i, clock;
6724     gcsHAL_FRAME_INFO info;
6725 #if gcdFRAME_DB_RESET
6726         gctUINT reset;
6727 #endif
6728
6729     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
6730
6731     /* Get profile tick. */
6732     gcmkONERROR(gckOS_GetProfileTick(&info.ticks));
6733
6734     /* Read SH counters and reset them. */
6735     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6736         Hardware,
6737         0x0045C,
6738         0x00470,
6739         24,
6740         4,
6741         &info.shaderCycles));
6742     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6743         Hardware,
6744         0x0045C,
6745         0x00470,
6746         24,
6747         9,
6748         &info.vsInstructionCount));
6749     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6750         Hardware,
6751         0x0045C,
6752         0x00470,
6753         24,
6754         12,
6755         &info.vsTextureCount));
6756     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6757         Hardware,
6758         0x0045C,
6759         0x00470,
6760         24,
6761         7,
6762         &info.psInstructionCount));
6763     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6764         Hardware,
6765         0x0045C,
6766         0x00470,
6767         24,
6768         14,
6769         &info.psTextureCount));
6770 #if gcdFRAME_DB_RESET
6771     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6772         Hardware,
6773         0x0045C,
6774         0x00470,
6775         24,
6776         15,
6777         &reset));
6778 #endif
6779
6780     /* Read PA counters and reset them. */
6781     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6782         Hardware,
6783         0x00460,
6784         0x00474,
6785         0,
6786         3,
6787         &info.vertexCount));
6788     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6789         Hardware,
6790         0x00460,
6791         0x00474,
6792         0,
6793         4,
6794         &info.primitiveCount));
6795     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6796         Hardware,
6797         0x00460,
6798         0x00474,
6799         0,
6800         7,
6801         &info.rejectedPrimitives));
6802     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6803         Hardware,
6804         0x00460,
6805         0x00474,
6806         0,
6807         8,
6808         &info.culledPrimitives));
6809     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6810         Hardware,
6811         0x00460,
6812         0x00474,
6813         0,
6814         6,
6815         &info.clippedPrimitives));
6816     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6817         Hardware,
6818         0x00460,
6819         0x00474,
6820         0,
6821         5,
6822         &info.outPrimitives));
6823 #if gcdFRAME_DB_RESET
6824     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6825         Hardware,
6826         0x00460,
6827         0x00474,
6828         0,
6829         15,
6830         &reset));
6831 #endif
6832
6833     /* Read RA counters and reset them. */
6834     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6835         Hardware,
6836         0x00448,
6837         0x00474,
6838         16,
6839         3,
6840         &info.inPrimitives));
6841     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6842         Hardware,
6843         0x00448,
6844         0x00474,
6845         16,
6846         11,
6847         &info.culledQuadCount));
6848     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6849         Hardware,
6850         0x00448,
6851         0x00474,
6852         16,
6853         1,
6854         &info.totalQuadCount));
6855     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6856         Hardware,
6857         0x00448,
6858         0x00474,
6859         16,
6860         2,
6861         &info.quadCount));
6862     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6863         Hardware,
6864         0x00448,
6865         0x00474,
6866         16,
6867         0,
6868         &info.totalPixelCount));
6869 #if gcdFRAME_DB_RESET
6870     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6871         Hardware,
6872         0x00448,
6873         0x00474,
6874         16,
6875         15,
6876         &reset));
6877 #endif
6878
6879     /* Read TX counters and reset them. */
6880     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6881         Hardware,
6882         0x0044C,
6883         0x00474,
6884         24,
6885         0,
6886         &info.bilinearRequests));
6887     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6888         Hardware,
6889         0x0044C,
6890         0x00474,
6891         24,
6892         1,
6893         &info.trilinearRequests));
6894     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6895         Hardware,
6896         0x0044C,
6897         0x00474,
6898         24,
6899         8,
6900         &info.txHitCount));
6901     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6902         Hardware,
6903         0x0044C,
6904         0x00474,
6905         24,
6906         9,
6907         &info.txMissCount));
6908     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6909         Hardware,
6910         0x0044C,
6911         0x00474,
6912         24,
6913         6,
6914         &info.txBytes8));
6915 #if gcdFRAME_DB_RESET
6916     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6917         Hardware,
6918         0x0044C,
6919         0x00474,
6920         24,
6921         15,
6922         &reset));
6923 #endif
6924
6925     /* Read clock control register. */
6926     gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6927                                      Hardware->core,
6928                                      0x00000,
6929                                      &clock));
6930
6931     /* Walk through all avaiable pixel pipes. */
6932     for (i = 0; i < Hardware->identity.pixelPipes; ++i)
6933     {
6934         /* Select proper pipe. */
6935         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
6936                                           Hardware->core,
6937                                           0x00000,
6938                                           ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20)))));
6939
6940         /* Read cycle registers. */
6941         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6942                                          Hardware->core,
6943                                          0x00078,
6944                                          &info.cycles[i]));
6945         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6946                                          Hardware->core,
6947                                          0x0007C,
6948                                          &info.idleCycles[i]));
6949         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6950                                          Hardware->core,
6951                                          0x00438,
6952                                          &info.mcCycles[i]));
6953
6954         /* Read bandwidth registers. */
6955         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6956                                          Hardware->core,
6957                                          0x0005C,
6958                                          &info.readRequests[i]));
6959         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6960                                          Hardware->core,
6961                                          0x00040,
6962                                          &info.readBytes8[i]));
6963         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6964                                          Hardware->core,
6965                                          0x00050,
6966                                          &info.writeRequests[i]));
6967         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
6968                                          Hardware->core,
6969                                          0x00044,
6970                                          &info.writeBytes8[i]));
6971
6972         /* Read PE counters. */
6973         gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6974             Hardware,
6975             0x00454,
6976             0x00470,
6977             16,
6978             0,
6979             &info.colorKilled[i]));
6980         gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6981             Hardware,
6982             0x00454,
6983             0x00470,
6984             16,
6985             2,
6986             &info.colorDrawn[i]));
6987         gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6988             Hardware,
6989             0x00454,
6990             0x00470,
6991             16,
6992             1,
6993             &info.depthKilled[i]));
6994         gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
6995             Hardware,
6996             0x00454,
6997             0x00470,
6998             16,
6999             3,
7000             &info.depthDrawn[i]));
7001     }
7002
7003     /* Zero out remaning reserved counters. */
7004     for (; i < 8; ++i)
7005     {
7006         info.readBytes8[i]    = 0;
7007         info.writeBytes8[i]   = 0;
7008         info.cycles[i]        = 0;
7009         info.idleCycles[i]    = 0;
7010         info.mcCycles[i]      = 0;
7011         info.readRequests[i]  = 0;
7012         info.writeRequests[i] = 0;
7013         info.colorKilled[i]   = 0;
7014         info.colorDrawn[i]    = 0;
7015         info.depthKilled[i]   = 0;
7016         info.depthDrawn[i]    = 0;
7017     }
7018
7019     /* Reset clock control register. */
7020     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
7021                                       Hardware->core,
7022                                       0x00000,
7023                                       clock));
7024
7025     /* Reset cycle and bandwidth counters. */
7026     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
7027                                       Hardware->core,
7028                                       0x0003C,
7029                                       1));
7030     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
7031                                       Hardware->core,
7032                                       0x0003C,
7033                                       0));
7034     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
7035                                       Hardware->core,
7036                                       0x00078,
7037                                       0));
7038
7039 #if gcdFRAME_DB_RESET
7040     /* Reset PE counters. */
7041     gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
7042         Hardware,
7043         0x00454,
7044         0x00470,
7045         16,
7046         15,
7047         &reset));
7048 #endif
7049
7050     /* Copy to user. */
7051     gcmkONERROR(gckOS_CopyToUserData(Hardware->os,
7052                                      &info,
7053                                      FrameInfo,
7054                                      gcmSIZEOF(info)));
7055
7056     /* Success. */
7057     gcmkFOOTER_NO();
7058     return gcvSTATUS_OK;
7059
7060 OnError:
7061     /* Return the status. */
7062     gcmkFOOTER();
7063     return status;
7064 }
7065 #endif
7066
7067 #if gcdDVFS
7068 #define READ_FROM_EATER1 0
7069
7070 gceSTATUS
7071 gckHARDWARE_QueryLoad(
7072     IN gckHARDWARE Hardware,
7073     OUT gctUINT32 * Load
7074     )
7075 {
7076     gctUINT32 debug1;
7077     gceSTATUS status;
7078     gcmkHEADER_ARG("Hardware=0x%X", Hardware);
7079
7080     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
7081     gcmkVERIFY_ARGUMENT(Load != gcvNULL);
7082
7083     gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
7084
7085     if (Hardware->chipPowerState == gcvPOWER_ON)
7086     {
7087         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
7088                                          Hardware->core,
7089                                          0x00110,
7090                                          Load));
7091 #if READ_FROM_EATER1
7092         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
7093                                          Hardware->core,
7094                                          0x00134,
7095                                          Load));
7096 #endif
7097
7098         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
7099                                          Hardware->core,
7100                                          0x00114,
7101                                          &debug1));
7102
7103         /* Patch result of 0x110 with result of 0x114. */
7104         if ((debug1 & 0xFF) == 1)
7105         {
7106             *Load &= ~0xFF;
7107             *Load |= 1;
7108         }
7109
7110         if (((debug1 & 0xFF00) >> 8) == 1)
7111         {
7112             *Load &= ~(0xFF << 8);
7113             *Load |= 1 << 8;
7114         }
7115
7116         if (((debug1 & 0xFF0000) >> 16) == 1)
7117         {
7118             *Load &= ~(0xFF << 16);
7119             *Load |= 1 << 16;
7120         }
7121
7122         if (((debug1 & 0xFF000000) >> 24) == 1)
7123         {
7124             *Load &= ~(0xFF << 24);
7125             *Load |= 1 << 24;
7126         }
7127     }
7128     else
7129     {
7130         status = gcvSTATUS_INVALID_REQUEST;
7131     }
7132
7133 OnError:
7134
7135     gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
7136
7137     gcmkFOOTER();
7138     return status;
7139 }
7140
7141 gceSTATUS
7142 gckHARDWARE_SetDVFSPeroid(
7143     IN gckHARDWARE Hardware,
7144     OUT gctUINT32 Frequency
7145     )
7146 {
7147     gceSTATUS status;
7148     gctUINT32 period;
7149     gctUINT32 eater;
7150
7151 #if READ_FROM_EATER1
7152     gctUINT32 period1;
7153     gctUINT32 eater1;
7154 #endif
7155
7156     gcmkHEADER_ARG("Hardware=0x%X Frequency=%d", Hardware, Frequency);
7157
7158     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
7159
7160     period = 0;
7161
7162     while((64 << period) < (gcdDVFS_ANAYLSE_WINDOW * Frequency * 1000) )
7163     {
7164         period++;
7165     }
7166
7167 #if READ_FROM_EATER1
7168     /*
7169     *  Peroid = F * 1000 * 1000 / (60 * 16 * 1024);
7170     */
7171     period1 = Frequency * 6250 / 6114;
7172 #endif
7173
7174     gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
7175
7176     if (Hardware->chipPowerState == gcvPOWER_ON)
7177     {
7178         /* Get current configure. */
7179         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
7180                                          Hardware->core,
7181                                          0x0010C,
7182                                          &eater));
7183
7184         /* Change peroid. */
7185         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
7186                                           Hardware->core,
7187                                           0x0010C,
7188                                           ((((gctUINT32) (eater)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8))) | (((gctUINT32) ((gctUINT32) (period) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1))))))) << (0 ? 15:8)))));
7189
7190 #if READ_FROM_EATER1
7191         /* Config eater1. */
7192         gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
7193                                          Hardware->core,
7194                                          0x00130,
7195                                          &eater1));
7196
7197         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
7198                                           Hardware->core,
7199                                           0x00130,
7200                                           ((((gctUINT32) (eater1)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16))) | (((gctUINT32) ((gctUINT32) (period1) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1))))))) << (0 ? 31:16)))));
7201 #endif
7202     }
7203     else
7204     {
7205         status = gcvSTATUS_INVALID_REQUEST;
7206     }
7207
7208 OnError:
7209     gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
7210
7211     gcmkFOOTER();
7212     return status;
7213 }
7214
7215 gceSTATUS
7216 gckHARDWARE_InitDVFS(
7217     IN gckHARDWARE Hardware
7218     )
7219 {
7220     gceSTATUS status;
7221     gctUINT32 data;
7222
7223     gcmkHEADER_ARG("Hardware=0x%X", Hardware);
7224
7225     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
7226
7227     gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
7228                                      Hardware->core,
7229                                      0x0010C,
7230                                      &data));
7231
7232     data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
7233     data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1))))))) << (0 ? 18:18)));
7234     data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
7235     data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
7236     data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1))))))) << (0 ? 23:23)));
7237     data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1))))))) << (0 ? 22:22))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1))))))) << (0 ? 22:22)));
7238
7239     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
7240                    "DVFS Configure=0x%X",
7241                    data);
7242
7243     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
7244                                       Hardware->core,
7245                                       0x0010C,
7246                                       data));
7247
7248     gcmkFOOTER_NO();
7249     return gcvSTATUS_OK;
7250
7251 OnError:
7252     gcmkFOOTER();
7253     return status;
7254 }
7255 #endif
7256
7257