1 /****************************************************************************
3 * Copyright (C) 2005 - 2013 by Vivante Corp.
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.
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.
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.
19 *****************************************************************************/
23 #include "gc_hal_kernel.h"
24 #include "gc_hal_kernel_hardware_command_vg.h"
28 #define _GC_OBJ_ZONE gcvZONE_HARDWARE
32 gcvPOWER_FLAG_INITIALIZE = 1 << 0,
33 gcvPOWER_FLAG_STALL = 1 << 1,
34 gcvPOWER_FLAG_STOP = 1 << 2,
35 gcvPOWER_FLAG_START = 1 << 3,
36 gcvPOWER_FLAG_RELEASE = 1 << 4,
37 gcvPOWER_FLAG_DELAY = 1 << 5,
38 gcvPOWER_FLAG_SAVE = 1 << 6,
39 gcvPOWER_FLAG_ACQUIRE = 1 << 7,
40 gcvPOWER_FLAG_POWER_OFF = 1 << 8,
41 gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
42 gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
43 gcvPOWER_FLAG_NOP = 1 << 11,
47 /******************************************************************************\
48 ********************************* Support Code *********************************
49 \******************************************************************************/
55 gctUINT32 control, idle;
59 gcmkONERROR(gckOS_ReadRegisterEx(Os,
66 /* Disable clock gating. */
67 gcmkONERROR(gckOS_WriteRegisterEx(Os,
72 /* Wait for clock being stable. */
73 gcmkONERROR(gckOS_Delay(Os, 1));
75 /* Isolate the GPU. */
76 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) (1) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19)));
78 gcmkONERROR(gckOS_WriteRegisterEx(Os,
84 gcmkONERROR(gckOS_WriteRegisterEx(Os,
87 ((((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)))));
90 gcmkONERROR(gckOS_Delay(Os, 1));
92 /* Reset soft reset bit. */
93 gcmkONERROR(gckOS_WriteRegisterEx(Os,
96 ((((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)))));
98 /* Reset GPU isolation. */
99 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)));
101 gcmkONERROR(gckOS_WriteRegisterEx(Os,
106 /* Read idle register. */
107 gcmkONERROR(gckOS_ReadRegisterEx(Os,
112 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)
117 /* Read reset register. */
118 gcmkONERROR(gckOS_ReadRegisterEx(Os,
123 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)
124 || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
139 /* Return the error. */
147 OUT gceCHIPMODEL * ChipModel,
148 OUT gctUINT32 * ChipRevision,
149 OUT gctUINT32 * ChipFeatures,
150 OUT gctUINT32 * ChipMinorFeatures,
151 OUT gctUINT32 * ChipMinorFeatures2
155 gctUINT32 chipIdentity;
159 /* Read chip identity register. */
160 gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG, 0x00018, &chipIdentity));
162 /* Special case for older graphic cores. */
163 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))))))))
166 *ChipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
171 /* Read chip identity register. */
172 gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
174 (gctUINT32 *) ChipModel));
176 /* Read CHIP_REV register. */
177 gcmkERR_BREAK(gckOS_ReadRegisterEx(Os, gcvCORE_VG,
182 /* Read chip feature register. */
183 gcmkERR_BREAK(gckOS_ReadRegisterEx(
184 Os, gcvCORE_VG, 0x0001C, ChipFeatures
187 /* Read chip minor feature register. */
188 gcmkERR_BREAK(gckOS_ReadRegisterEx(
189 Os, gcvCORE_VG, 0x00034, ChipMinorFeatures
192 /* Read chip minor feature register #2. */
193 gcmkERR_BREAK(gckOS_ReadRegisterEx(
194 Os, gcvCORE_VG, 0x00074, ChipMinorFeatures2
200 "ChipRevision=0x%08X\n"
201 "ChipFeatures=0x%08X\n"
202 "ChipMinorFeatures=0x%08X\n"
203 "ChipMinorFeatures2=0x%08X\n",
216 /* Return the status. */
220 #if gcdPOWEROFF_TIMEOUT
222 _VGPowerTimerFunction(
226 gckVGHARDWARE hardware = (gckVGHARDWARE)Data;
228 gckVGHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
232 /******************************************************************************\
233 ****************************** gckVGHARDWARE API code *****************************
234 \******************************************************************************/
236 /*******************************************************************************
238 ** gckVGHARDWARE_Construct
240 ** Construct a new gckVGHARDWARE object.
245 ** Pointer to an initialized gckOS object.
249 ** gckVGHARDWARE * Hardware
250 ** Pointer to a variable that will hold the pointer to the gckVGHARDWARE
254 gckVGHARDWARE_Construct(
256 OUT gckVGHARDWARE * Hardware
259 gckVGHARDWARE hardware = gcvNULL;
261 gceCHIPMODEL chipModel;
262 gctUINT32 chipRevision;
263 gctUINT32 chipFeatures;
264 gctUINT32 chipMinorFeatures;
265 gctUINT32 chipMinorFeatures2;
267 gcmkHEADER_ARG("Os=0x%x Hardware=0x%x ", Os, Hardware);
269 /* Verify the arguments. */
270 gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
271 gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
275 gcmkERR_BREAK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvTRUE, gcvTRUE));
277 status = _ResetGPU(Os);
279 if (status != gcvSTATUS_OK)
281 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
282 "_ResetGPU failed: status=%d\n", status);
285 /* Identify the hardware. */
286 gcmkERR_BREAK(_IdentifyHardware(Os,
287 &chipModel, &chipRevision,
288 &chipFeatures, &chipMinorFeatures, &chipMinorFeatures2
291 /* Allocate the gckVGHARDWARE object. */
292 gcmkERR_BREAK(gckOS_Allocate(Os,
293 gcmSIZEOF(struct _gckVGHARDWARE), (gctPOINTER *) &hardware
296 /* Initialize the gckVGHARDWARE object. */
297 hardware->object.type = gcvOBJ_HARDWARE;
300 /* Set chip identity. */
301 hardware->chipModel = chipModel;
302 hardware->chipRevision = chipRevision;
303 hardware->chipFeatures = chipFeatures;
304 hardware->chipMinorFeatures = chipMinorFeatures;
305 hardware->chipMinorFeatures2 = chipMinorFeatures2;
307 hardware->powerMutex = gcvNULL;
308 hardware->chipPowerState = gcvPOWER_ON;
309 hardware->chipPowerStateGlobal = gcvPOWER_ON;
310 hardware->clockState = gcvTRUE;
311 hardware->powerState = gcvTRUE;
313 hardware->powerOffTime = 0;
314 #if gcdPOWEROFF_TIMEOUT
315 hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
317 gcmkVERIFY_OK(gckOS_CreateTimer(Os,
318 _VGPowerTimerFunction,
319 (gctPOINTER)hardware,
320 &hardware->powerOffTimer));
323 /* Determine whether FE 2.0 is present. */
324 hardware->fe20 = ((((gctUINT32) (hardware->chipFeatures)) >> (0 ? 28:28) & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))));
326 /* Determine whether VG 2.0 is present. */
327 hardware->vg20 = ((((gctUINT32) (hardware->chipMinorFeatures)) >> (0 ? 13:13) & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1)))))));
329 /* Determine whether VG 2.1 is present. */
330 hardware->vg21 = ((((gctUINT32) (hardware->chipMinorFeatures)) >> (0 ? 18:18) & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 18:18) - (0 ? 18:18) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 18:18) - (0 ? 18:18) + 1)))))));
332 /* Set default event mask. */
333 hardware->eventMask = 0xFFFFFFFF;
335 gcmkERR_BREAK(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
337 /* Set fast clear to auto. */
338 gcmkVERIFY_OK(gckVGHARDWARE_SetFastClear(hardware, -1));
340 gcmkERR_BREAK(gckOS_CreateMutex(Os, &hardware->powerMutex));
342 /* Enable power management by default. */
343 hardware->powerManagement = gcvTRUE;
345 /* Return pointer to the gckVGHARDWARE object. */
346 *Hardware = hardware;
354 #if gcdPOWEROFF_TIMEOUT
355 if (hardware->powerOffTimer != gcvNULL)
357 gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
358 gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
362 if (hardware->pageTableDirty != gcvNULL)
364 gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
367 if (hardware != gcvNULL)
369 gcmkVERIFY_OK(gckOS_Free(Os, hardware));
372 gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvCORE_VG, gcvFALSE, gcvFALSE));
375 /* Return the status. */
379 /*******************************************************************************
381 ** gckVGHARDWARE_Destroy
383 ** Destroy an gckVGHARDWARE object.
387 ** gckVGHARDWARE Hardware
388 ** Pointer to the gckVGHARDWARE object that needs to be destroyed.
395 gckVGHARDWARE_Destroy(
396 IN gckVGHARDWARE Hardware
400 gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
401 /* Verify the arguments. */
402 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
404 /* Mark the object as unknown. */
405 Hardware->object.type = gcvOBJ_UNKNOWN;
407 if (Hardware->powerMutex != gcvNULL)
409 gcmkVERIFY_OK(gckOS_DeleteMutex(
410 Hardware->os, Hardware->powerMutex));
413 #if gcdPOWEROFF_TIMEOUT
414 gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
415 gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
418 if (Hardware->pageTableDirty != gcvNULL)
420 gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
423 /* Free the object. */
424 status = gckOS_Free(Hardware->os, Hardware);
429 /*******************************************************************************
431 ** gckVGHARDWARE_QueryMemory
433 ** Query the amount of memory available on the hardware.
437 ** gckVGHARDWARE Hardware
438 ** Pointer to the gckVGHARDWARE object.
442 ** gctSIZE_T * InternalSize
443 ** Pointer to a variable that will hold the size of the internal video
444 ** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
445 ** internal memory will be returned.
447 ** gctUINT32 * InternalBaseAddress
448 ** Pointer to a variable that will hold the hardware's base address for
449 ** the internal video memory. This pointer cannot be gcvNULL if
450 ** 'InternalSize' is also non-gcvNULL.
452 ** gctUINT32 * InternalAlignment
453 ** Pointer to a variable that will hold the hardware's base address for
454 ** the internal video memory. This pointer cannot be gcvNULL if
455 ** 'InternalSize' is also non-gcvNULL.
457 ** gctSIZE_T * ExternalSize
458 ** Pointer to a variable that will hold the size of the external video
459 ** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
460 ** external memory will be returned.
462 ** gctUINT32 * ExternalBaseAddress
463 ** Pointer to a variable that will hold the hardware's base address for
464 ** the external video memory. This pointer cannot be gcvNULL if
465 ** 'ExternalSize' is also non-gcvNULL.
467 ** gctUINT32 * ExternalAlignment
468 ** Pointer to a variable that will hold the hardware's base address for
469 ** the external video memory. This pointer cannot be gcvNULL if
470 ** 'ExternalSize' is also non-gcvNULL.
472 ** gctUINT32 * HorizontalTileSize
473 ** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
474 ** gcvNULL, no horizontal pixel per tile will be returned.
476 ** gctUINT32 * VerticalTileSize
477 ** Number of vertical pixels per tile. If 'VerticalTileSize' is
478 ** gcvNULL, no vertical pixel per tile will be returned.
481 gckVGHARDWARE_QueryMemory(
482 IN gckVGHARDWARE Hardware,
483 OUT gctSIZE_T * InternalSize,
484 OUT gctUINT32 * InternalBaseAddress,
485 OUT gctUINT32 * InternalAlignment,
486 OUT gctSIZE_T * ExternalSize,
487 OUT gctUINT32 * ExternalBaseAddress,
488 OUT gctUINT32 * ExternalAlignment,
489 OUT gctUINT32 * HorizontalTileSize,
490 OUT gctUINT32 * VerticalTileSize
493 gcmkHEADER_ARG("Hardware=0x%x InternalSize=0x%x InternalBaseAddress=0x%x InternalAlignment=0x%x"
494 "ExternalSize=0x%x ExternalBaseAddress=0x%x ExternalAlignment=0x%x HorizontalTileSize=0x%x VerticalTileSize=0x%x",
495 Hardware, InternalSize, InternalBaseAddress, InternalAlignment,
496 ExternalSize, ExternalBaseAddress, ExternalAlignment, HorizontalTileSize, VerticalTileSize);
498 /* Verify the arguments. */
499 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
501 if (InternalSize != gcvNULL)
503 /* No internal memory. */
507 if (ExternalSize != gcvNULL)
509 /* No external memory. */
513 if (HorizontalTileSize != gcvNULL)
516 *HorizontalTileSize = 4;
519 if (VerticalTileSize != gcvNULL)
522 *VerticalTileSize = 4;
530 /*******************************************************************************
532 ** gckVGHARDWARE_QueryChipIdentity
534 ** Query the identity of the hardware.
538 ** gckVGHARDWARE Hardware
539 ** Pointer to the gckVGHARDWARE object.
543 ** gceCHIPMODEL * ChipModel
544 ** If 'ChipModel' is not gcvNULL, the variable it points to will
545 ** receive the model of the chip.
547 ** gctUINT32 * ChipRevision
548 ** If 'ChipRevision' is not gcvNULL, the variable it points to will
549 ** receive the revision of the chip.
551 ** gctUINT32 * ChipFeatures
552 ** If 'ChipFeatures' is not gcvNULL, the variable it points to will
553 ** receive the feature set of the chip.
555 ** gctUINT32 * ChipMinorFeatures
556 ** If 'ChipMinorFeatures' is not gcvNULL, the variable it points to
557 ** will receive the minor feature set of the chip.
559 ** gctUINT32 * ChipMinorFeatures2
560 ** If 'ChipMinorFeatures2' is not gcvNULL, the variable it points to
561 ** will receive the minor feature set of the chip.
565 gckVGHARDWARE_QueryChipIdentity(
566 IN gckVGHARDWARE Hardware,
567 OUT gceCHIPMODEL * ChipModel,
568 OUT gctUINT32 * ChipRevision,
569 OUT gctUINT32* ChipFeatures,
570 OUT gctUINT32* ChipMinorFeatures,
571 OUT gctUINT32* ChipMinorFeatures2
574 gcmkHEADER_ARG("Hardware=0x%x ChipModel=0x%x ChipRevision=0x%x ChipFeatures = 0x%x ChipMinorFeatures = 0x%x ChipMinorFeatures2 = 0x%x",
575 Hardware, ChipModel, ChipRevision, ChipFeatures, ChipMinorFeatures, ChipMinorFeatures2);
577 /* Verify the arguments. */
578 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
580 /* Return chip model. */
581 if (ChipModel != gcvNULL)
583 *ChipModel = Hardware->chipModel;
586 /* Return revision number. */
587 if (ChipRevision != gcvNULL)
589 *ChipRevision = Hardware->chipRevision;
592 /* Return feature set. */
593 if (ChipFeatures != gcvNULL)
595 gctUINT32 features = Hardware->chipFeatures;
597 if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
599 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)));
602 /* Mark 2D pipe as available for GC500.0 since it did not have this *\
604 if ((Hardware->chipModel == gcv500)
605 && (Hardware->chipRevision == 0)
608 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)));
611 /* Mark 2D pipe as available for GC300 since it did not have this *\
613 if (Hardware->chipModel == gcv300)
615 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)));
618 *ChipFeatures = features;
621 /* Return minor feature set. */
622 if (ChipMinorFeatures != gcvNULL)
624 *ChipMinorFeatures = Hardware->chipMinorFeatures;
627 /* Return minor feature set #2. */
628 if (ChipMinorFeatures2 != gcvNULL)
630 *ChipMinorFeatures2 = Hardware->chipMinorFeatures2;
638 /*******************************************************************************
640 ** gckVGHARDWARE_ConvertFormat
642 ** Convert an API format to hardware parameters.
646 ** gckVGHARDWARE Hardware
647 ** Pointer to the gckVGHARDWARE object.
649 ** gceSURF_FORMAT Format
650 ** API format to convert.
654 ** gctUINT32 * BitsPerPixel
655 ** Pointer to a variable that will hold the number of bits per pixel.
657 ** gctUINT32 * BytesPerTile
658 ** Pointer to a variable that will hold the number of bytes per tile.
661 gckVGHARDWARE_ConvertFormat(
662 IN gckVGHARDWARE Hardware,
663 IN gceSURF_FORMAT Format,
664 OUT gctUINT32 * BitsPerPixel,
665 OUT gctUINT32 * BytesPerTile
668 gctUINT32 bitsPerPixel;
669 gctUINT32 bytesPerTile;
671 gcmkHEADER_ARG("Hardware=0x%x Format=0x%x BitsPerPixel=0x%x BytesPerTile = 0x%x",
672 Hardware, Format, BitsPerPixel, BytesPerTile);
674 /* Verify the arguments. */
675 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
677 /* Dispatch on format. */
684 bytesPerTile = (1 * 4 * 4) / 8;
690 bytesPerTile = (4 * 4 * 4) / 8;
698 bytesPerTile = (8 * 4 * 4) / 8;
702 /* 12-bpp planar YUV formats. */
704 bytesPerTile = (12 * 4 * 4) / 8;
708 /* 12-bpp planar YUV formats. */
710 bytesPerTile = (12 * 4 * 4) / 8;
713 /* 4444 variations. */
714 case gcvSURF_X4R4G4B4:
715 case gcvSURF_A4R4G4B4:
716 case gcvSURF_R4G4B4X4:
717 case gcvSURF_R4G4B4A4:
718 case gcvSURF_B4G4R4X4:
719 case gcvSURF_B4G4R4A4:
720 case gcvSURF_X4B4G4R4:
721 case gcvSURF_A4B4G4R4:
723 /* 1555 variations. */
724 case gcvSURF_X1R5G5B5:
725 case gcvSURF_A1R5G5B5:
726 case gcvSURF_R5G5B5X1:
727 case gcvSURF_R5G5B5A1:
728 case gcvSURF_X1B5G5R5:
729 case gcvSURF_A1B5G5R5:
730 case gcvSURF_B5G5R5X1:
731 case gcvSURF_B5G5R5A1:
733 /* 565 variations. */
743 bytesPerTile = (16 * 4 * 4) / 8;
746 case gcvSURF_X8R8G8B8:
747 case gcvSURF_A8R8G8B8:
748 case gcvSURF_X8B8G8R8:
749 case gcvSURF_A8B8G8R8:
750 case gcvSURF_R8G8B8X8:
751 case gcvSURF_R8G8B8A8:
752 case gcvSURF_B8G8R8X8:
753 case gcvSURF_B8G8R8A8:
757 bytesPerTile = (32 * 4 * 4) / 8;
763 bytesPerTile = (32 * 4 * 4) / 8;
769 bytesPerTile = (4 * 4 * 4) / 8;
777 bytesPerTile = (8 * 4 * 4) / 8;
781 /* Invalid format. */
783 return gcvSTATUS_INVALID_ARGUMENT;
786 /* Set the result. */
787 if (BitsPerPixel != gcvNULL)
789 * BitsPerPixel = bitsPerPixel;
792 if (BytesPerTile != gcvNULL)
794 * BytesPerTile = bytesPerTile;
802 /*******************************************************************************
804 ** gckVGHARDWARE_SplitMemory
806 ** Split a hardware specific memory address into a pool and offset.
810 ** gckVGHARDWARE Hardware
811 ** Pointer to the gckVGHARDWARE object.
814 ** Address in hardware specific format.
819 ** Pointer to a variable that will hold the pool type for the address.
821 ** gctUINT32 * Offset
822 ** Pointer to a variable that will hold the offset for the address.
825 gckVGHARDWARE_SplitMemory(
826 IN gckVGHARDWARE Hardware,
827 IN gctUINT32 Address,
829 OUT gctUINT32 * Offset
832 gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Pool=0x%x Offset = 0x%x",
833 Hardware, Address, Pool, Offset);
834 /* Verify the arguments. */
835 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
836 gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
837 gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
839 /* Dispatch on memory type. */
840 switch ((((((gctUINT32) (Address)) >> (0 ? 1:0)) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1)))))) ))
844 *Pool = gcvPOOL_SYSTEM;
848 /* Virtual memory. */
849 *Pool = gcvPOOL_VIRTUAL;
853 /* Invalid memory type. */
855 return gcvSTATUS_INVALID_ARGUMENT;
858 /* Return offset of address. */
859 *Offset = ((((gctUINT32) (Address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
866 /*******************************************************************************
868 ** gckVGHARDWARE_Execute
870 ** Kickstart the hardware's command processor with an initialized command
875 ** gckVGHARDWARE Hardware
876 ** Pointer to the gckVGHARDWARE object.
879 ** Address of the command buffer.
882 ** Number of command-sized data units to be executed.
889 gckVGHARDWARE_Execute(
890 IN gckVGHARDWARE Hardware,
891 IN gctUINT32 Address,
897 gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Count=0x%x",
898 Hardware, Address, Count);
900 /* Verify the arguments. */
901 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
905 /* Enable all events. */
906 gcmkERR_BREAK(gckOS_WriteRegisterEx(
915 /* Write address register. */
916 gcmkERR_BREAK(gckOS_WriteRegisterEx(
920 gcmkFIXADDRESS(Address)
923 /* Write control register. */
924 gcmkERR_BREAK(gckOS_WriteRegisterEx(
933 /* Write address register. */
934 gcmkERR_BREAK(gckOS_WriteRegisterEx(
938 gcmkFIXADDRESS(Address)
941 /* Write control register. */
942 gcmkERR_BREAK(gckOS_WriteRegisterEx(
946 ((((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))) |
947 ((((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)))
959 /* Return the status. */
963 /*******************************************************************************
965 ** gckVGHARDWARE_AlignToTile
967 ** Align the specified width and height to tile boundaries.
971 ** gckVGHARDWARE Hardware
972 ** Pointer to an gckVGHARDWARE object.
975 ** Type of alignment.
978 ** Pointer to the width to be aligned. If 'Width' is gcvNULL, no width
981 ** gctUINT32 * Height
982 ** Pointer to the height to be aligned. If 'Height' is gcvNULL, no height
988 ** Pointer to a variable that will receive the aligned width.
990 ** gctUINT32 * Height
991 ** Pointer to a variable that will receive the aligned height.
994 gckVGHARDWARE_AlignToTile(
995 IN gckVGHARDWARE Hardware,
996 IN gceSURF_TYPE Type,
997 IN OUT gctUINT32 * Width,
998 IN OUT gctUINT32 * Height
1001 gcmkHEADER_ARG("Hardware=0x%x Type=0x%x Width=0x%x Height=0x%x",
1002 Hardware, Type, Width, Height);
1003 /* Verify the arguments. */
1004 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1006 if (Width != gcvNULL)
1008 /* Align the width. */
1009 *Width = gcmALIGN(*Width, (Type == gcvSURF_TEXTURE) ? 4 : 16);
1012 if (Height != gcvNULL)
1014 /* Special case for VG images. */
1015 if ((*Height == 0) && (Type == gcvSURF_IMAGE))
1021 /* Align the height. */
1022 *Height = gcmALIGN(*Height, 4);
1028 return gcvSTATUS_OK;
1031 /*******************************************************************************
1033 ** gckVGHARDWARE_ConvertLogical
1035 ** Convert a logical system address into a hardware specific address.
1039 ** gckVGHARDWARE Hardware
1040 ** Pointer to an gckVGHARDWARE object.
1042 ** gctPOINTER Logical
1043 ** Logical address to convert.
1045 ** gctUINT32* Address
1046 ** Return hardware specific address.
1053 gckVGHARDWARE_ConvertLogical(
1054 IN gckVGHARDWARE Hardware,
1055 IN gctPOINTER Logical,
1056 OUT gctUINT32 * Address
1062 gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Address=0x%x",
1063 Hardware, Logical, Address);
1065 /* Verify the arguments. */
1066 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1067 gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
1068 gcmkVERIFY_ARGUMENT(Address != gcvNULL);
1072 /* Convert logical address into a physical address. */
1073 gcmkERR_BREAK(gckOS_GetPhysicalAddress(
1074 Hardware->os, Logical, &address
1077 /* Return hardware specific address. */
1078 *Address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
1082 return gcvSTATUS_OK;
1087 /* Return the status. */
1091 /*******************************************************************************
1093 ** gckVGHARDWARE_QuerySystemMemory
1095 ** Query the command buffer alignment and number of reserved bytes.
1099 ** gckVGHARDWARE Harwdare
1100 ** Pointer to an gckVGHARDWARE object.
1104 ** gctSIZE_T * SystemSize
1105 ** Pointer to a variable that receives the maximum size of the system
1108 ** gctUINT32 * SystemBaseAddress
1109 ** Poinetr to a variable that receives the base address for system
1112 gceSTATUS gckVGHARDWARE_QuerySystemMemory(
1113 IN gckVGHARDWARE Hardware,
1114 OUT gctSIZE_T * SystemSize,
1115 OUT gctUINT32 * SystemBaseAddress
1118 gcmkHEADER_ARG("Hardware=0x%x SystemSize=0x%x SystemBaseAddress=0x%x",
1119 Hardware, SystemSize, SystemBaseAddress);
1121 /* Verify the arguments. */
1122 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1124 if (SystemSize != gcvNULL)
1126 /* Maximum system memory can be 2GB. */
1127 *SystemSize = (gctSIZE_T)(1 << 31);
1130 if (SystemBaseAddress != gcvNULL)
1132 /* Set system memory base address. */
1133 *SystemBaseAddress = ((((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) (0x0 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
1138 return gcvSTATUS_OK;
1141 /*******************************************************************************
1143 ** gckVGHARDWARE_SetMMU
1145 ** Set the page table base address.
1149 ** gckVGHARDWARE Harwdare
1150 ** Pointer to an gckVGHARDWARE object.
1152 ** gctPOINTER Logical
1153 ** Logical address of the page table.
1159 gceSTATUS gckVGHARDWARE_SetMMU(
1160 IN gckVGHARDWARE Hardware,
1161 IN gctPOINTER Logical
1165 gctUINT32 address = 0;
1167 gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x",
1170 /* Verify the arguments. */
1171 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1172 gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
1176 /* Convert the logical address into an hardware address. */
1177 gcmkERR_BREAK(gckVGHARDWARE_ConvertLogical(Hardware, Logical, &address) );
1179 /* Write the AQMemoryFePageTable register. */
1180 gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
1182 gcmkFIXADDRESS(address)) );
1184 /* Write the AQMemoryTxPageTable register. */
1185 gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
1187 gcmkFIXADDRESS(address)) );
1189 /* Write the AQMemoryPePageTable register. */
1190 gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
1192 gcmkFIXADDRESS(address)) );
1194 /* Write the AQMemoryPezPageTable register. */
1195 gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
1197 gcmkFIXADDRESS(address)) );
1199 /* Write the AQMemoryRaPageTable register. */
1200 gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
1202 gcmkFIXADDRESS(address)) );
1207 /* Return the status. */
1211 /*******************************************************************************
1213 ** gckVGHARDWARE_FlushMMU
1215 ** Flush the page table.
1219 ** gckVGHARDWARE Harwdare
1220 ** Pointer to an gckVGHARDWARE object.
1226 gceSTATUS gckVGHARDWARE_FlushMMU(
1227 IN gckVGHARDWARE Hardware
1231 gckVGCOMMAND command;
1233 gcmkHEADER_ARG("Hardware=0x%x ", Hardware);
1234 /* Verify the arguments. */
1235 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1239 gcsCMDBUFFER_PTR commandBuffer;
1240 gctUINT32_PTR buffer;
1242 /* Create a shortcut to the command buffer object. */
1243 command = Hardware->kernel->command;
1245 /* Allocate command buffer space. */
1246 gcmkERR_BREAK(gckVGCOMMAND_Allocate(
1247 command, 8, &commandBuffer, (gctPOINTER *) &buffer
1251 = ((((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)))
1252 | ((((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)))
1253 | ((((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)));
1256 = ((((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)))
1257 | ((((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)))
1258 | ((((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)))
1259 | ((((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)))
1260 | ((((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)));
1265 /* Return the status. */
1269 /*******************************************************************************
1271 ** gckVGHARDWARE_BuildVirtualAddress
1273 ** Build a virtual address.
1277 ** gckVGHARDWARE Harwdare
1278 ** Pointer to an gckVGHARDWARE object.
1281 ** Index into page table.
1284 ** Offset into page.
1288 ** gctUINT32 * Address
1289 ** Pointer to a variable receiving te hardware address.
1291 gceSTATUS gckVGHARDWARE_BuildVirtualAddress(
1292 IN gckVGHARDWARE Hardware,
1294 IN gctUINT32 Offset,
1295 OUT gctUINT32 * Address
1300 gcmkHEADER_ARG("Hardware=0x%x Index=0x%x Offset=0x%x Address=0x%x",
1301 Hardware, Index, Offset, Address);
1303 /* Verify the arguments. */
1304 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1305 gcmkVERIFY_ARGUMENT(Address != gcvNULL);
1307 /* Build virtual address. */
1308 address = (Index << 12) | Offset;
1310 /* Set virtual type. */
1311 address = ((((gctUINT32) (address)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0)));
1313 /* Set the result. */
1318 return gcvSTATUS_OK;
1322 gckVGHARDWARE_GetIdle(
1323 IN gckVGHARDWARE Hardware,
1324 OUT gctUINT32 * Data
1328 gcmkHEADER_ARG("Hardware=0x%x Data=0x%x", Hardware, Data);
1329 /* Verify the arguments. */
1330 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1331 gcmkVERIFY_ARGUMENT(Data != gcvNULL);
1333 /* Read register and return. */
1334 status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, Data);
1340 gckVGHARDWARE_SetFastClear(
1341 IN gckVGHARDWARE Hardware,
1348 if (!(((((gctUINT32) (Hardware->chipFeatures)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
1350 return gcvSTATUS_OK;
1357 Enable = (Hardware->chipModel > gcv500) ||
1358 ((Hardware->chipModel == gcv500) && (Hardware->chipRevision >= 3));
1361 gcmkERR_BREAK(gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
1365 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)));
1367 #ifdef AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION
1368 debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1) == 32) ? ~0 : (~(~0 << ((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1))))))) << (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1) == 32) ? ~0 : (~(~0 << ((1 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) - (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION) + 1))))))) << (0 ? AQ_MEMORY_DEBUG_DISABLE_Z_COMPRESSION)));
1371 gcmkERR_BREAK(gckOS_WriteRegisterEx(Hardware->os, gcvCORE_VG,
1375 Hardware->allowFastClear = Enable;
1385 gckVGHARDWARE_ReadInterrupt(
1386 IN gckVGHARDWARE Hardware,
1387 OUT gctUINT32_PTR IDs
1391 gcmkHEADER_ARG("Hardware=0x%x IDs=0x%x", Hardware, IDs);
1393 /* Verify the arguments. */
1394 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1395 gcmkVERIFY_ARGUMENT(IDs != gcvNULL);
1397 /* Read AQIntrAcknowledge register. */
1398 status = gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG,
1405 static gceSTATUS _CommandStall(
1406 gckVGHARDWARE Hardware)
1409 gckVGCOMMAND command;
1411 gcmkHEADER_ARG("Hardware=0x%x", Hardware);
1412 /* Verify the arguments. */
1413 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1417 gctUINT32_PTR buffer;
1418 command = Hardware->kernel->command;
1420 /* Allocate command buffer space. */
1421 gcmkERR_BREAK(gckVGCOMMAND_Allocate(
1422 command, 8, &command->powerStallBuffer,
1423 (gctPOINTER *) &buffer
1426 gcmkERR_BREAK(gckVGCOMMAND_EventCommand(
1427 command, buffer, gcvBLOCK_PIXEL,
1428 command->powerStallInt, gcvNULL));
1430 gcmkERR_BREAK(gckVGCOMMAND_Execute(
1432 command->powerStallBuffer
1435 /* Wait the signal. */
1436 gcmkERR_BREAK(gckOS_WaitSignal(
1438 command->powerStallSignal,
1446 /* Return the status. */
1450 /*******************************************************************************
1452 ** gckHARDWARE_SetPowerManagementState
1454 ** Set GPU to a specified power state.
1458 ** gckHARDWARE Harwdare
1459 ** Pointer to an gckHARDWARE object.
1461 ** gceCHIPPOWERSTATE State
1466 gckVGHARDWARE_SetPowerManagementState(
1467 IN gckVGHARDWARE Hardware,
1468 IN gceCHIPPOWERSTATE State
1472 gckVGCOMMAND command = gcvNULL;
1474 gctUINT flag/*, clock*/;
1476 gctBOOL acquired = gcvFALSE;
1477 gctBOOL stall = gcvTRUE;
1478 gctBOOL commitMutex = gcvFALSE;
1479 gctBOOL mutexAcquired = gcvFALSE;
1481 #if gcdPOWEROFF_TIMEOUT
1482 gctBOOL timeout = gcvFALSE;
1483 gctBOOL isAfter = gcvFALSE;
1484 gctUINT32 currentTime;
1487 gctBOOL broadcast = gcvFALSE;
1488 gctUINT32 process, thread;
1489 gctBOOL global = gcvFALSE;
1491 #if gcdENABLE_PROFILING
1492 gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
1493 initTime, offTime, startTime, totalTime;
1496 /* State transition flags. */
1497 static const gctUINT flags[4][4] =
1501 /* OFF */ gcvPOWER_FLAG_ACQUIRE |
1502 gcvPOWER_FLAG_STALL |
1503 gcvPOWER_FLAG_STOP |
1504 gcvPOWER_FLAG_POWER_OFF |
1505 gcvPOWER_FLAG_CLOCK_OFF,
1506 /* IDLE */ gcvPOWER_FLAG_NOP,
1507 /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
1508 gcvPOWER_FLAG_STALL |
1509 gcvPOWER_FLAG_STOP |
1510 gcvPOWER_FLAG_CLOCK_OFF,
1514 { /* ON */ gcvPOWER_FLAG_INITIALIZE |
1515 gcvPOWER_FLAG_START |
1516 gcvPOWER_FLAG_RELEASE |
1517 gcvPOWER_FLAG_DELAY,
1519 /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
1520 gcvPOWER_FLAG_START |
1521 gcvPOWER_FLAG_RELEASE |
1522 gcvPOWER_FLAG_DELAY,
1523 /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
1524 gcvPOWER_FLAG_CLOCK_OFF,
1528 { /* ON */ gcvPOWER_FLAG_NOP,
1529 /* OFF */ gcvPOWER_FLAG_ACQUIRE |
1530 gcvPOWER_FLAG_STOP |
1531 gcvPOWER_FLAG_POWER_OFF |
1532 gcvPOWER_FLAG_CLOCK_OFF,
1534 /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
1535 gcvPOWER_FLAG_STOP |
1536 gcvPOWER_FLAG_CLOCK_OFF,
1539 /* gcvPOWER_SUSPEND */
1540 { /* ON */ gcvPOWER_FLAG_START |
1541 gcvPOWER_FLAG_RELEASE |
1542 gcvPOWER_FLAG_DELAY |
1543 gcvPOWER_FLAG_CLOCK_ON,
1544 /* OFF */ gcvPOWER_FLAG_SAVE |
1545 gcvPOWER_FLAG_POWER_OFF |
1546 gcvPOWER_FLAG_CLOCK_OFF,
1547 /* IDLE */ gcvPOWER_FLAG_START |
1548 gcvPOWER_FLAG_DELAY |
1549 gcvPOWER_FLAG_RELEASE |
1550 gcvPOWER_FLAG_CLOCK_ON,
1555 gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
1556 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
1557 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
1558 "Switching to power state %d",
1562 /* Verify the arguments. */
1563 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1565 /* Get the gckOS object pointer. */
1567 gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
1569 /* Get the gckCOMMAND object pointer. */
1570 gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
1571 command = Hardware->kernel->command;
1572 gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
1574 if (Hardware->powerManagement == gcvFALSE)
1577 return gcvSTATUS_OK;
1580 /* Start profiler. */
1581 gcmkPROFILE_INIT(freq, time);
1583 /* Convert the broadcast power state. */
1586 case gcvPOWER_SUSPEND_ATPOWERON:
1587 /* Convert to SUSPEND and don't wait for STALL. */
1588 State = gcvPOWER_SUSPEND;
1592 case gcvPOWER_OFF_ATPOWERON:
1593 /* Convert to OFF and don't wait for STALL. */
1594 State = gcvPOWER_OFF;
1598 case gcvPOWER_IDLE_BROADCAST:
1599 /* Convert to IDLE and note we are inside broadcast. */
1600 State = gcvPOWER_IDLE;
1601 broadcast = gcvTRUE;
1604 case gcvPOWER_SUSPEND_BROADCAST:
1605 /* Convert to SUSPEND and note we are inside broadcast. */
1606 State = gcvPOWER_SUSPEND;
1607 broadcast = gcvTRUE;
1610 case gcvPOWER_OFF_BROADCAST:
1611 /* Convert to OFF and note we are inside broadcast. */
1612 State = gcvPOWER_OFF;
1613 broadcast = gcvTRUE;
1616 case gcvPOWER_OFF_RECOVERY:
1617 /* Convert to OFF and note we are inside recovery. */
1618 State = gcvPOWER_OFF;
1620 broadcast = gcvTRUE;
1623 case gcvPOWER_ON_AUTO:
1624 /* Convert to ON and note we are inside recovery. */
1625 State = gcvPOWER_ON;
1630 case gcvPOWER_SUSPEND:
1632 /* Mark as global power management. */
1636 #if gcdPOWEROFF_TIMEOUT
1637 case gcvPOWER_OFF_TIMEOUT:
1638 /* Convert to OFF and note we are inside broadcast. */
1639 State = gcvPOWER_OFF;
1640 broadcast = gcvTRUE;
1641 /* Check time out */
1650 /* Get current process and thread IDs. */
1651 gcmkONERROR(gckOS_GetProcessID(&process));
1652 gcmkONERROR(gckOS_GetThreadID(&thread));
1654 /* Acquire the power mutex. */
1657 /* Try to acquire the power mutex. */
1658 status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
1660 if (status == gcvSTATUS_TIMEOUT)
1662 /* Check if we already own this mutex. */
1663 if ((Hardware->powerProcess == process)
1664 && (Hardware->powerThread == thread)
1667 /* Bail out on recursive power management. */
1669 return gcvSTATUS_OK;
1671 else if (State == gcvPOWER_IDLE)
1673 /* gcvPOWER_IDLE_BROADCAST is from IST,
1674 ** so waiting here will cause deadlock,
1675 ** if lock holder call gckCOMMAND_Stall() */
1676 gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
1680 /* Acquire the power mutex. */
1681 gcmkONERROR(gckOS_AcquireMutex(os,
1682 Hardware->powerMutex,
1689 /* Acquire the power mutex. */
1690 gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
1693 /* Get time until mtuex acquired. */
1694 gcmkPROFILE_QUERY(time, mutexTime);
1696 Hardware->powerProcess = process;
1697 Hardware->powerThread = thread;
1698 mutexAcquired = gcvTRUE;
1700 /* Grab control flags and clock. */
1701 flag = flags[Hardware->chipPowerState][State];
1702 /*clock = clocks[State];*/
1704 #if gcdPOWEROFF_TIMEOUT
1707 gcmkONERROR(gckOS_GetTicks(¤tTime));
1710 gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
1712 /* powerOffTime is pushed forward, give up.*/
1714 /* Expect a transition start from IDLE. */
1715 || (Hardware->chipPowerState == gcvPOWER_ON)
1716 || (Hardware->chipPowerState == gcvPOWER_OFF)
1719 /* Release the power mutex. */
1720 gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
1722 /* No need to do anything. */
1724 return gcvSTATUS_OK;
1731 /* Release the power mutex. */
1732 gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
1734 /* No need to do anything. */
1736 return gcvSTATUS_OK;
1739 /* internal power control */
1742 if (Hardware->chipPowerStateGlobal == gcvPOWER_OFF)
1744 /* Release the power mutex. */
1745 gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
1747 /* No need to do anything. */
1749 return gcvSTATUS_OK;
1754 if (flag & gcvPOWER_FLAG_ACQUIRE)
1756 /* Acquire the power management semaphore. */
1757 gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
1760 /* avoid acquiring again. */
1761 flag &= ~gcvPOWER_FLAG_ACQUIRE;
1765 if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
1767 /* Turn on the power. */
1768 gcmkONERROR(gckOS_SetGPUPower(os, gcvCORE_VG, gcvTRUE, gcvTRUE));
1770 /* Mark clock and power as enabled. */
1771 Hardware->clockState = gcvTRUE;
1772 Hardware->powerState = gcvTRUE;
1775 /* Get time until powered on. */
1776 gcmkPROFILE_QUERY(time, onTime);
1778 if ((flag & gcvPOWER_FLAG_STALL) && stall)
1780 /* Acquire the mutex. */
1781 gcmkONERROR(gckOS_AcquireMutex(
1783 command->commitMutex,
1787 commitMutex = gcvTRUE;
1789 gcmkONERROR(_CommandStall(Hardware));
1792 /* Get time until stalled. */
1793 gcmkPROFILE_QUERY(time, stallTime);
1795 if (flag & gcvPOWER_FLAG_ACQUIRE)
1797 /* Acquire the power management semaphore. */
1798 gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
1803 if (flag & gcvPOWER_FLAG_STOP)
1807 /* Get time until stopped. */
1808 gcmkPROFILE_QUERY(time, stopTime);
1810 /* Only process this when hardware is enabled. */
1811 if (Hardware->clockState && Hardware->powerState)
1815 if (flag & gcvPOWER_FLAG_DELAY)
1817 /* Wait for the specified amount of time to settle coming back from
1818 ** power-off or suspend state. */
1819 gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
1822 /* Get time until delayed. */
1823 gcmkPROFILE_QUERY(time, delayTime);
1825 if (flag & gcvPOWER_FLAG_INITIALIZE)
1827 gcmkONERROR(gckVGHARDWARE_SetMMU(Hardware, Hardware->kernel->mmu->pageTableLogical));
1829 /* Force the command queue to reload the next context. */
1830 command->currentContext = 0;
1833 /* Get time until initialized. */
1834 gcmkPROFILE_QUERY(time, initTime);
1836 if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
1838 /* Turn off the GPU power. */
1840 gckOS_SetGPUPower(os,
1842 (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
1844 (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
1847 /* Save current hardware power and clock states. */
1848 Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
1850 Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
1854 /* Get time until off. */
1855 gcmkPROFILE_QUERY(time, offTime);
1857 if (flag & gcvPOWER_FLAG_START)
1861 /* Get time until started. */
1862 gcmkPROFILE_QUERY(time, startTime);
1864 if (flag & gcvPOWER_FLAG_RELEASE)
1866 /* Release the power management semaphore. */
1867 gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
1868 acquired = gcvFALSE;
1871 /* Save the new power state. */
1872 Hardware->chipPowerState = State;
1876 /* Save the new power state. */
1877 Hardware->chipPowerStateGlobal = State;
1882 /* Acquire the mutex. */
1883 gcmkVERIFY_OK(gckOS_ReleaseMutex(
1885 command->commitMutex
1889 #if gcdPOWEROFF_TIMEOUT
1890 /* Reset power off time */
1891 gcmkONERROR(gckOS_GetTicks(¤tTime));
1893 Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
1895 if (State == gcvPOWER_IDLE)
1897 /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
1898 gcmkVERIFY_OK(gckOS_StartTimer(os,
1899 Hardware->powerOffTimer,
1900 Hardware->powerOffTimeout));
1904 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
1906 /* Cancel running timer when GPU enters ON or OFF. */
1907 gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
1911 /* Release the power mutex. */
1912 gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
1914 /* Get total time. */
1915 gcmkPROFILE_QUERY(time, totalTime);
1916 #if gcdENABLE_PROFILING
1917 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
1918 "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
1919 freq, mutexTime, onTime, stallTime, stopTime);
1920 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
1921 " delay:%llu init:%llu off:%llu start:%llu total:%llu",
1922 delayTime, initTime, offTime, startTime, totalTime);
1927 return gcvSTATUS_OK;
1933 /* Release semaphore. */
1934 gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
1935 command->powerSemaphore));
1940 gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
1945 /* Acquire the mutex. */
1946 gcmkVERIFY_OK(gckOS_ReleaseMutex(
1948 command->commitMutex
1952 /* Return the status. */
1957 /*******************************************************************************
1959 ** gckHARDWARE_QueryPowerManagementState
1961 ** Get GPU power state.
1965 ** gckHARDWARE Harwdare
1966 ** Pointer to an gckHARDWARE object.
1968 ** gceCHIPPOWERSTATE* State
1973 gckVGHARDWARE_QueryPowerManagementState(
1974 IN gckVGHARDWARE Hardware,
1975 OUT gceCHIPPOWERSTATE* State
1978 gcmkHEADER_ARG("Hardware=0x%x", Hardware);
1980 /* Verify the arguments. */
1981 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
1982 gcmkVERIFY_ARGUMENT(State != gcvNULL);
1984 /* Return the statue. */
1985 *State = Hardware->chipPowerState;
1988 gcmkFOOTER_ARG("*State=%d", *State);
1989 return gcvSTATUS_OK;
1992 /*******************************************************************************
1994 ** gckVGHARDWARE_SetPowerManagement
1996 ** Configure GPU power management function.
1997 ** Only used in driver initialization stage.
2001 ** gckVGHARDWARE Harwdare
2002 ** Pointer to an gckHARDWARE object.
2004 ** gctBOOL PowerManagement
2005 ** Power Mangement State.
2009 gckVGHARDWARE_SetPowerManagement(
2010 IN gckVGHARDWARE Hardware,
2011 IN gctBOOL PowerManagement
2014 gcmkHEADER_ARG("Hardware=0x%x", Hardware);
2016 /* Verify the arguments. */
2017 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2019 Hardware->powerManagement = PowerManagement;
2023 return gcvSTATUS_OK;
2027 gckVGHARDWARE_SetPowerOffTimeout(
2028 IN gckVGHARDWARE Hardware,
2029 IN gctUINT32 Timeout
2032 gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
2034 Hardware->powerOffTimeout = Timeout;
2037 return gcvSTATUS_OK;
2042 gckVGHARDWARE_QueryPowerOffTimeout(
2043 IN gckVGHARDWARE Hardware,
2044 OUT gctUINT32* Timeout
2047 gcmkHEADER_ARG("Hardware=0x%x", Hardware);
2049 *Timeout = Hardware->powerOffTimeout;
2051 gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
2052 return gcvSTATUS_OK;
2056 gckVGHARDWARE_QueryIdle(
2057 IN gckVGHARDWARE Hardware,
2058 OUT gctBOOL_PTR IsIdle
2064 gcmkHEADER_ARG("Hardware=0x%x", Hardware);
2066 /* Verify the arguments. */
2067 gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
2068 gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
2070 /* We are idle when the power is not ON. */
2071 if (Hardware->chipPowerState != gcvPOWER_ON)
2078 /* Read idle register. */
2080 gckOS_ReadRegisterEx(Hardware->os, gcvCORE_VG, 0x00004, &idle));
2082 /* Pipe must be idle. */
2083 if (((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) != 1)
2084 || ((((((gctUINT32) (idle)) >> (0 ? 8:8)) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) ) != 1)
2085 || ((((((gctUINT32) (idle)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) ) != 1)
2086 || ((((((gctUINT32) (idle)) >> (0 ? 10:10)) & ((gctUINT32) ((((1 ? 10:10) - (0 ? 10:10) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 10:10) - (0 ? 10:10) + 1)))))) ) != 1)
2087 || ((((((gctUINT32) (idle)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ) != 1)
2090 /* Something is busy. */
2102 return gcvSTATUS_OK;
2105 /* Return the status. */
2109 #endif /* gcdENABLE_VG */