aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mxc/gpu-viv/arch/XAQ2/hal
diff options
context:
space:
mode:
authorroot <root@artemis.panaceas.org>2015-12-25 04:40:36 +0000
committerroot <root@artemis.panaceas.org>2015-12-25 04:40:36 +0000
commit849369d6c66d3054688672f97d31fceb8e8230fb (patch)
tree6135abc790ca67dedbe07c39806591e70eda81ce /drivers/mxc/gpu-viv/arch/XAQ2/hal
downloadlinux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.tar.gz
linux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.tar.bz2
linux-3.0.35-kobo-849369d6c66d3054688672f97d31fceb8e8230fb.zip
initial_commit
Diffstat (limited to 'drivers/mxc/gpu-viv/arch/XAQ2/hal')
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c1727
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h146
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c6237
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h135
4 files changed, 8245 insertions, 0 deletions
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
new file mode 100644
index 00000000..a52c1c81
--- /dev/null
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
@@ -0,0 +1,1727 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2012 by Vivante Corp.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+#include "gc_hal_kernel_buffer.h"
+
+/******************************************************************************\
+******************************** Debugging Macro *******************************
+\******************************************************************************/
+
+/* Zone used for header/footer. */
+#define _GC_OBJ_ZONE gcvZONE_HARDWARE
+
+
+/******************************************************************************\
+************************** Context State Buffer Helpers ************************
+\******************************************************************************/
+
+#define _STATE(reg) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ reg ## _ResetValue, \
+ reg ## _Count, \
+ gcvFALSE, gcvFALSE \
+ )
+
+#define _STATE_COUNT(reg, count) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ reg ## _ResetValue, \
+ count, \
+ gcvFALSE, gcvFALSE \
+ )
+
+#define _STATE_COUNT_OFFSET(reg, offset, count) \
+ _State(\
+ Context, index, \
+ (reg ## _Address >> 2) + offset, \
+ reg ## _ResetValue, \
+ count, \
+ gcvFALSE, gcvFALSE \
+ )
+
+#define _STATE_MIRROR_COUNT(reg, mirror, count) \
+ _StateMirror(\
+ Context, \
+ reg ## _Address >> 2, \
+ count, \
+ mirror ## _Address >> 2 \
+ )
+
+#define _STATE_HINT(reg) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ reg ## _ResetValue, \
+ reg ## _Count, \
+ gcvFALSE, gcvTRUE \
+ )
+
+#define _STATE_HINT_BLOCK(reg, block, count) \
+ _State(\
+ Context, index, \
+ (reg ## _Address >> 2) + (block << reg ## _BLK), \
+ reg ## _ResetValue, \
+ count, \
+ gcvFALSE, gcvTRUE \
+ )
+
+#define _STATE_X(reg) \
+ _State(\
+ Context, index, \
+ reg ## _Address >> 2, \
+ reg ## _ResetValue, \
+ reg ## _Count, \
+ gcvTRUE, gcvFALSE \
+ )
+
+#define _CLOSE_RANGE() \
+ _TerminateStateBlock(Context, index)
+
+#define _ENABLE(reg, field) \
+ do \
+ { \
+ if (gcmVERIFYFIELDVALUE(data, reg, MASK_ ## field, ENABLED)) \
+ { \
+ enable |= gcmFIELDMASK(reg, field); \
+ } \
+ } \
+ while (gcvFALSE)
+
+#define _BLOCK_COUNT(reg) \
+ ((reg ## _Count) >> (reg ## _BLK))
+
+
+/******************************************************************************\
+*********************** Support Functions and Definitions **********************
+\******************************************************************************/
+
+#define gcdSTATE_MASK \
+ (((((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 | 0xC0FFEE & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))))
+
+#if !defined(VIVANTE_NO_3D)
+static gctSIZE_T
+_TerminateStateBlock(
+ IN gckCONTEXT Context,
+ IN gctSIZE_T Index
+ )
+{
+ gctUINT32_PTR buffer;
+ gctSIZE_T align;
+
+ /* Determine if we need alignment. */
+ align = (Index & 1) ? 1 : 0;
+
+ /* Address correct index. */
+ buffer = (Context->buffer == gcvNULL)
+ ? gcvNULL
+ : Context->buffer->logical;
+
+ /* Flush the current state block; make sure no pairing with the states
+ to follow happens. */
+ if (align && (buffer != gcvNULL))
+ {
+ buffer[Index] = 0xDEADDEAD;
+ }
+
+ /* Reset last address. */
+ Context->lastAddress = ~0U;
+
+ /* Return alignment requirement. */
+ return align;
+}
+#endif
+
+
+static gctSIZE_T
+_FlushPipe(
+ IN gckCONTEXT Context,
+ IN gctSIZE_T Index,
+ IN gcePIPE_SELECT Pipe
+ )
+{
+ if (Context->buffer != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Address correct index. */
+ buffer = Context->buffer->logical + Index;
+
+ /* Flush the current pipe. */
+ *buffer++
+ = ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ *buffer++
+ = (Pipe == gcvPIPE_2D)
+ ? ((((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)))
+ : ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ /* Semaphore from FE to PE. */
+ *buffer++
+ = ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ *buffer++
+ = ((((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)))
+ | ((((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)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((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)));
+
+ *buffer
+ = ((((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)))
+ | ((((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)));
+ }
+
+ /* Flushing 3D pipe takes 6 slots. */
+ return 6;
+}
+
+#if !defined(VIVANTE_NO_3D)
+static gctSIZE_T
+_SemaphoreStall(
+ IN gckCONTEXT Context,
+ IN gctSIZE_T Index
+ )
+{
+ if (Context->buffer != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Address correct index. */
+ buffer = Context->buffer->logical + Index;
+
+ /* Semaphore from FE to PE. */
+ *buffer++
+ = ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ *buffer++
+ = ((((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)))
+ | ((((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)));
+
+ /* Stall from FE to PE. */
+ *buffer++
+ = ((((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)));
+
+ *buffer
+ = ((((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)))
+ | ((((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)));
+ }
+
+ /* Semaphore/stall takes 4 slots. */
+ return 4;
+}
+#endif
+
+static gctSIZE_T
+_SwitchPipe(
+ IN gckCONTEXT Context,
+ IN gctSIZE_T Index,
+ IN gcePIPE_SELECT Pipe
+ )
+{
+ if (Context->buffer != gcvNULL)
+ {
+ gctUINT32_PTR buffer;
+
+ /* Address correct index. */
+ buffer = Context->buffer->logical + Index;
+
+ /* LoadState(AQPipeSelect, 1), pipe. */
+ *buffer++
+ = ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ *buffer
+ = (Pipe == gcvPIPE_2D)
+ ? 0x1
+ : 0x0;
+ }
+
+ return 2;
+}
+
+#if !defined(VIVANTE_NO_3D)
+static gctSIZE_T
+_State(
+ IN gckCONTEXT Context,
+ IN gctSIZE_T Index,
+ IN gctUINT32 Address,
+ IN gctUINT32 Value,
+ IN gctSIZE_T Size,
+ IN gctBOOL FixedPoint,
+ IN gctBOOL Hinted
+ )
+{
+ gctUINT32_PTR buffer;
+ gctSIZE_T align, i;
+
+ /* Determine if we need alignment. */
+ align = (Index & 1) ? 1 : 0;
+
+ /* Address correct index. */
+ buffer = (Context->buffer == gcvNULL)
+ ? gcvNULL
+ : Context->buffer->logical;
+
+ if ((buffer == gcvNULL) && (Address + Size > Context->stateCount))
+ {
+ /* Determine maximum state. */
+ Context->stateCount = Address + Size;
+ }
+
+ /* Do we need a new entry? */
+ if ((Address != Context->lastAddress) || (FixedPoint != Context->lastFixed))
+ {
+ if (buffer != gcvNULL)
+ {
+ if (align)
+ {
+ /* Add filler. */
+ buffer[Index++] = 0xDEADDEAD;
+ }
+
+ /* LoadState(Address, Count). */
+ gcmkASSERT((Index & 1) == 0);
+
+ if (FixedPoint)
+ {
+ buffer[Index]
+ = ((((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)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+ | ((((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) (Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((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) (Address) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ }
+ else
+ {
+ buffer[Index]
+ = ((((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)))
+ | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+ | ((((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) (Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+ | ((((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) (Address) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ }
+
+ /* Walk all the states. */
+ for (i = 0; i < Size; i += 1)
+ {
+ /* Set state to uninitialized value. */
+ buffer[Index + 1 + i] = Value;
+
+ /* Set index in state mapping table. */
+ Context->map[Address + i].index = Index + 1 + i;
+
+#if gcdSECURE_USER
+ /* Save hint. */
+ if (Context->hint != gcvNULL)
+ {
+ Context->hint[Address + i] = Hinted;
+ }
+#endif
+ }
+ }
+
+ /* Save information for this LoadState. */
+ Context->lastIndex = Index;
+ Context->lastAddress = Address + Size;
+ Context->lastSize = Size;
+ Context->lastFixed = FixedPoint;
+
+ /* Return size for load state. */
+ return align + 1 + Size;
+ }
+
+ /* Append this state to the previous one. */
+ if (buffer != gcvNULL)
+ {
+ /* Update last load state. */
+ buffer[Context->lastIndex] =
+ ((((gctUINT32) (buffer[Context->lastIndex])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (Context->lastSize + Size) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ /* Walk all the states. */
+ for (i = 0; i < Size; i += 1)
+ {
+ /* Set state to uninitialized value. */
+ buffer[Index + i] = Value;
+
+ /* Set index in state mapping table. */
+ Context->map[Address + i].index = Index + i;
+
+#if gcdSECURE_USER
+ /* Save hint. */
+ if (Context->hint != gcvNULL)
+ {
+ Context->hint[Address + i] = Hinted;
+ }
+#endif
+ }
+ }
+
+ /* Update last address and size. */
+ Context->lastAddress += Size;
+ Context->lastSize += Size;
+
+ /* Return number of slots required. */
+ return Size;
+}
+
+static gctSIZE_T
+_StateMirror(
+ IN gckCONTEXT Context,
+ IN gctUINT32 Address,
+ IN gctSIZE_T Size,
+ IN gctUINT32 AddressMirror
+ )
+{
+ gctSIZE_T i;
+
+ /* Process when buffer is set. */
+ if (Context->buffer != gcvNULL)
+ {
+ /* Walk all states. */
+ for (i = 0; i < Size; i++)
+ {
+ /* Copy the mapping address. */
+ Context->map[Address + i].index =
+ Context->map[AddressMirror + i].index;
+ }
+ }
+
+ /* Return the number of required maps. */
+ return Size;
+}
+#endif
+
+static gceSTATUS
+_InitializeContextBuffer(
+ IN gckCONTEXT Context
+ )
+{
+ gctUINT32_PTR buffer;
+ gctSIZE_T index;
+
+#if !defined(VIVANTE_NO_3D)
+ gctUINT i;
+ gctUINT vertexUniforms, fragmentUniforms;
+ gctUINT fe2vsCount;
+#endif
+
+ /* Reset the buffer index. */
+ index = 0;
+
+ /* Reset the last state address. */
+ Context->lastAddress = ~0U;
+
+ /* Get the buffer pointer. */
+ buffer = (Context->buffer == gcvNULL)
+ ? gcvNULL
+ : Context->buffer->logical;
+
+
+ /**************************************************************************/
+ /* Build 2D states. *******************************************************/
+
+
+#if !defined(VIVANTE_NO_3D)
+ /**************************************************************************/
+ /* Build 3D states. *******************************************************/
+
+ /* Query shader support. */
+ gcmkVERIFY_OK(gckHARDWARE_QueryShaderCaps(
+ Context->hardware, &vertexUniforms, &fragmentUniforms, gcvNULL));
+
+ /* Store the 3D entry index. */
+ Context->entryOffset3D = index * gcmSIZEOF(gctUINT32);
+
+ /* Flush 2D pipe. */
+ index += _FlushPipe(Context, index, gcvPIPE_2D);
+
+ /* Switch to 3D pipe. */
+ index += _SwitchPipe(Context, index, gcvPIPE_3D);
+
+ /* Current context pointer. */
+#if gcdDEBUG && 1
+ index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+#endif
+
+ index += _FlushPipe(Context, index, gcvPIPE_3D);
+
+ /* Global states. */
+ index += _State(Context, index, 0x03814 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03818 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0381C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03820 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03828 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0382C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03834 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x03838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0384C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ /* Front End states. */
+ fe2vsCount = 12;
+ if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) ))
+ {
+ fe2vsCount = 16;
+ }
+ index += _State(Context, index, 0x00600 >> 2, 0x00000000, fe2vsCount, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ index += _State(Context, index, 0x00644 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x00648 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0064C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x00650 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00680 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x006A0 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0067C >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x006C0 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00700 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00740 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00780 >> 2, 0x3F800000, 16, gcvFALSE, gcvFALSE);
+
+ /* Vertex Shader states. */
+ index += _State(Context, index, 0x00800 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00808 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0080C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00810 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00830 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00838 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ if (Context->hardware->identity.instructionCount <= 256)
+ {
+ index += _State(Context, index, 0x04000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
+ }
+
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x05000 >> 2, 0x00000000, vertexUniforms * 4, gcvFALSE, gcvFALSE);
+
+ /* Primitive Assembly states. */
+ index += _State(Context, index, 0x00A00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A0C >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A10 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A1C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A28 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A2C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A30 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A40 >> 2, 0x00000000, 10, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A34 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A38 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A3C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A80 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00A84 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00A8C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ /* Setup states. */
+ index += _State(Context, index, 0x00C00 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C04 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C08 >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C0C >> 2, 0x45000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C10 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00C14 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00C18 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00C1C >> 2, 0x42000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00C20 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+ index += _State(Context, index, 0x00C24 >> 2, 0x00000000, 1, gcvTRUE, gcvFALSE);
+
+ /* Raster states. */
+ index += _State(Context, index, 0x00E00 >> 2, 0x00000001, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E10 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E40 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00E08 >> 2, 0x00000031, 1, gcvFALSE, gcvFALSE);
+
+ /* Pixel Shader states. */
+ index += _State(Context, index, 0x01000 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01004 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0100C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01010 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01018 >> 2, 0x01000000, 1, gcvFALSE, gcvFALSE);
+ if (Context->hardware->identity.instructionCount <= 256)
+ {
+ index += _State(Context, index, 0x06000 >> 2, 0x00000000, 1024, gcvFALSE, gcvFALSE);
+ }
+
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x07000 >> 2, 0x00000000, fragmentUniforms * 4, gcvFALSE, gcvFALSE);
+
+ /* Texture states. */
+ index += _State(Context, index, 0x02000 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02040 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02080 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x020C0 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02100 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02140 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02180 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x021C0 >> 2, 0x00321000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02200 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02240 >> 2, 0x00000000, 12, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, (0x02400 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02440 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02480 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x024C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02500 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02540 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02580 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x025C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02600 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02640 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02680 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x026C0 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02700 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, (0x02740 >> 2) + (0 << 4), 0x00000000, 12, gcvFALSE, gcvTRUE);
+ index += _CLOSE_RANGE();
+
+ if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures2)) >> (0 ? 11:11)) & ((gctUINT32) ((((1 ? 11:11) - (0 ? 11:11) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:11) - (0 ? 11:11) + 1)))))) ))
+ {
+ gctUINT texBlockCount;
+
+ /* New texture block. */
+ index += _State(Context, index, 0x10000 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10080 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10100 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x02C00 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x10480 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+
+ if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures2)) >> (0 ? 15:15)) & ((gctUINT32) ((((1 ? 15:15) - (0 ? 15:15) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:15) - (0 ? 15:15) + 1)))))) ))
+ {
+ index += _State(Context, index, 0x12000 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x12400 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
+ }
+
+ if ((Context->hardware->identity.chipModel == gcv2000)
+ && (Context->hardware->identity.chipRevision == 0x5108))
+ {
+ texBlockCount = 12;
+ }
+ else
+ {
+ texBlockCount = ((512) >> (4));
+ }
+ for (i = 0; i < texBlockCount; i += 1)
+ {
+ index += _State(Context, index, (0x10800 >> 2) + (i << 4), 0x00000000, 14, gcvFALSE, gcvTRUE);
+ }
+ }
+
+ /* YUV. */
+ index += _State(Context, index, 0x01678 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0167C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01680 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01684 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01688 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0168C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01690 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01694 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01698 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0169C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ /* Thread walker states. */
+ index += _State(Context, index, 0x00900 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00904 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00908 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0090C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00910 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00914 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00918 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00924 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ if (Context->hardware->identity.instructionCount > 1024)
+ {
+ /* New Shader instruction memory. */
+ index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x00860 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ for (i = 0;
+ i < Context->hardware->identity.instructionCount << 2;
+ i += 256 << 2
+ )
+ {
+ index += _State(Context, index, (0x20000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+ }
+ else if (Context->hardware->identity.instructionCount > 256)
+ {
+ /* New Shader instruction memory. */
+ index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0101C >> 2, 0x00000100, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ /* VX instruction memory. */
+ for (i = 0;
+ i < Context->hardware->identity.instructionCount << 2;
+ i += 256 << 2
+ )
+ {
+ index += _State(Context, index, (0x0C000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+ }
+
+ _StateMirror(Context, 0x08000 >> 2, Context->hardware->identity.instructionCount << 2 , 0x0C000 >> 2);
+ }
+
+ /* Store the index of the "XD" entry. */
+ Context->entryOffsetXDFrom3D = index * gcmSIZEOF(gctUINT32);
+
+
+ /* Pixel Engine states. */
+ index += _State(Context, index, 0x01400 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01404 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01408 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0140C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01414 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01418 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0141C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01420 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01424 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01428 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0142C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01434 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01454 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01458 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0145C >> 2, 0x00000010, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014A8 >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014AC >> 2, 0xFFFFFFFF, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014B0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014A4 >> 2, 0x000E400C, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01580 >> 2, 0x00000000, 3, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x014B8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ /* Composition states. */
+ index += _State(Context, index, 0x03008 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+
+ if (Context->hardware->identity.pixelPipes == 1)
+ {
+ index += _State(Context, index, 0x01430 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01410 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ }
+ else
+ {
+ index += _State(Context, index, (0x01460 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+
+ index += _State(Context, index, (0x01480 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+
+ for (i = 0; i < 2; i++)
+ {
+ index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+ }
+ }
+
+ /* Resolve states. */
+ index += _State(Context, index, 0x01604 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01608 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0160C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01610 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01614 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01620 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01630 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01640 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x0163C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x016A0 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x016B4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ if (Context->hardware->identity.pixelPipes > 1)
+ {
+ index += _State(Context, index, (0x016C0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+
+ index += _State(Context, index, (0x016E0 >> 2) + (0 << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+
+ index += _State(Context, index, 0x01700 >> 2, 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvFALSE);
+ }
+
+ /* Tile status. */
+ index += _State(Context, index, 0x01654 >> 2, 0x00200000, 1, gcvFALSE, gcvFALSE);
+
+ index += _CLOSE_RANGE();
+ index += _State(Context, index, 0x01658 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0165C >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01660 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01664 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01668 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x0166C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01670 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01674 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x016A4 >> 2, 0x00000000, 1, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x016AC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x016A8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01720 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _State(Context, index, 0x01740 >> 2, 0x00000000, 8, gcvFALSE, gcvTRUE);
+ index += _State(Context, index, 0x01760 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
+ index += _CLOSE_RANGE();
+
+ /* Semaphore/stall. */
+ index += _SemaphoreStall(Context, index);
+#endif
+
+ /**************************************************************************/
+ /* Link to another address. ***********************************************/
+
+ Context->linkIndex3D = index;
+
+ if (buffer != gcvNULL)
+ {
+ buffer[index + 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) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((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) (0) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ buffer[index + 1]
+ = 0;
+ }
+
+ index += 2;
+
+ /* Store the end of the context buffer. */
+ Context->bufferSize = index * gcmSIZEOF(gctUINT32);
+
+
+ /**************************************************************************/
+ /* Pipe switch for the case where neither 2D nor 3D are used. *************/
+
+ /* Store the 3D entry index. */
+ Context->entryOffsetXDFrom2D = index * gcmSIZEOF(gctUINT32);
+
+ /* Flush 2D pipe. */
+ index += _FlushPipe(Context, index, gcvPIPE_2D);
+
+ /* Switch to 3D pipe. */
+ index += _SwitchPipe(Context, index, gcvPIPE_3D);
+
+ /* Store the location of the link. */
+ Context->linkIndexXD = index;
+
+ if (buffer != gcvNULL)
+ {
+ buffer[index + 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) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((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) (0) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+ buffer[index + 1]
+ = 0;
+ }
+
+ index += 2;
+
+
+ /**************************************************************************/
+ /* Save size for buffer. **************************************************/
+
+ Context->totalSize = index * gcmSIZEOF(gctUINT32);
+
+
+ /* Success. */
+ return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_DestroyContext(
+ IN gckCONTEXT Context
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+
+ if (Context != gcvNULL)
+ {
+ gcsCONTEXT_PTR bufferHead;
+
+ /* Free context buffers. */
+ for (bufferHead = Context->buffer; Context->buffer != gcvNULL;)
+ {
+ /* Get a shortcut to the current buffer. */
+ gcsCONTEXT_PTR buffer = Context->buffer;
+
+ /* Get the next buffer. */
+ gcsCONTEXT_PTR next = buffer->next;
+
+ /* Last item? */
+ if (next == bufferHead)
+ {
+ next = gcvNULL;
+ }
+
+ /* Destroy the signal. */
+ if (buffer->signal != gcvNULL)
+ {
+ gcmkONERROR(gckOS_DestroySignal(
+ Context->os, buffer->signal
+ ));
+
+ buffer->signal = gcvNULL;
+ }
+
+ /* Free state delta map. */
+ if (buffer->logical != gcvNULL)
+ {
+#if gcdVIRTUAL_COMMAND_BUFFER
+ gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
+ Context->hardware->kernel->eventObj,
+ Context->totalSize,
+ buffer->physical,
+ buffer->logical,
+ gcvKERNEL_PIXEL
+ ));
+
+#else
+ gcmkONERROR(gckEVENT_FreeContiguousMemory(
+ Context->hardware->kernel->eventObj,
+ Context->totalSize,
+ buffer->physical,
+ buffer->logical,
+ gcvKERNEL_PIXEL
+ ));
+#endif
+
+ buffer->logical = gcvNULL;
+ }
+
+ /* Free context buffer. */
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, buffer));
+
+ /* Remove from the list. */
+ Context->buffer = next;
+ }
+
+#if gcdSECURE_USER
+ /* Free the hint array. */
+ if (Context->hint != gcvNULL)
+ {
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->hint));
+ }
+#endif
+ /* Free record array copy. */
+ if (Context->recordArray != gcvNULL)
+ {
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->recordArray));
+ }
+
+ /* Free the state mapping. */
+ if (Context->map != gcvNULL)
+ {
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->map));
+ }
+
+ /* Mark the gckCONTEXT object as unknown. */
+ Context->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the gckCONTEXT object. */
+ gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context));
+ }
+
+OnError:
+ return status;
+}
+
+
+/******************************************************************************\
+**************************** Context Management API ****************************
+\******************************************************************************/
+
+/******************************************************************************\
+**
+** gckCONTEXT_Construct
+**
+** Construct a new gckCONTEXT object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to gckOS object.
+**
+** gctUINT32 ProcessID
+** Current process ID.
+**
+** gckHARDWARE Hardware
+** Pointer to gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gckCONTEXT * Context
+** Pointer to a variable thet will receive the gckCONTEXT object
+** pointer.
+*/
+gceSTATUS
+gckCONTEXT_Construct(
+ IN gckOS Os,
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 ProcessID,
+ OUT gckCONTEXT * Context
+ )
+{
+ gceSTATUS status;
+ gckCONTEXT context = gcvNULL;
+ gctSIZE_T allocationSize;
+ gctUINT i;
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Context != gcvNULL);
+
+
+ /**************************************************************************/
+ /* Allocate and initialize basic fields of gckCONTEXT. ********************/
+
+ /* The context object size. */
+ allocationSize = gcmSIZEOF(struct _gckCONTEXT);
+
+ /* Allocate the object. */
+ gcmkONERROR(gckOS_Allocate(
+ Os, allocationSize, &pointer
+ ));
+
+ context = pointer;
+
+ /* Reset the entire object. */
+ gcmkONERROR(gckOS_ZeroMemory(context, allocationSize));
+
+ /* Initialize the gckCONTEXT object. */
+ context->object.type = gcvOBJ_CONTEXT;
+ context->os = Os;
+ context->hardware = Hardware;
+
+
+#if defined(VIVANTE_NO_3D)
+ context->entryPipe = gcvPIPE_2D;
+ context->exitPipe = gcvPIPE_2D;
+#elif gcdCMD_NO_2D_CONTEXT
+ context->entryPipe = gcvPIPE_3D;
+ context->exitPipe = gcvPIPE_3D;
+#else
+ context->entryPipe
+ = (((((gctUINT32) (context->hardware->identity.chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) )
+ ? gcvPIPE_2D
+ : gcvPIPE_3D;
+ context->exitPipe = gcvPIPE_3D;
+#endif
+
+ /* Get the command buffer requirements. */
+ gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
+ Hardware,
+ &context->alignment,
+ &context->reservedHead,
+ &context->reservedTail
+ ));
+
+ /* Mark the context as dirty to force loading of the entire state table
+ the first time. */
+ context->dirty = gcvTRUE;
+
+
+ /**************************************************************************/
+ /* Get the size of the context buffer. ************************************/
+
+ gcmkONERROR(_InitializeContextBuffer(context));
+
+
+ /**************************************************************************/
+ /* Compute the size of the record array. **********************************/
+
+ context->recordArraySize
+ = gcmSIZEOF(gcsSTATE_DELTA_RECORD) * context->stateCount;
+
+
+ if (context->stateCount > 0)
+ {
+ /**************************************************************************/
+ /* Allocate and reset the state mapping table. ****************************/
+
+ /* Allocate the state mapping table. */
+ gcmkONERROR(gckOS_Allocate(
+ Os,
+ gcmSIZEOF(gcsSTATE_MAP) * context->stateCount,
+ &pointer
+ ));
+
+ context->map = pointer;
+
+ /* Zero the state mapping table. */
+ gcmkONERROR(gckOS_ZeroMemory(
+ context->map, gcmSIZEOF(gcsSTATE_MAP) * context->stateCount
+ ));
+
+
+ /**************************************************************************/
+ /* Allocate the hint array. ***********************************************/
+
+#if gcdSECURE_USER
+ /* Allocate hints. */
+ gcmkONERROR(gckOS_Allocate(
+ Os,
+ gcmSIZEOF(gctBOOL) * context->stateCount,
+ &pointer
+ ));
+
+ context->hint = pointer;
+#endif
+ }
+
+ /**************************************************************************/
+ /* Allocate the context and state delta buffers. **************************/
+
+ for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i += 1)
+ {
+ /* Allocate a context buffer. */
+ gcsCONTEXT_PTR buffer;
+
+ /* Allocate the context buffer structure. */
+ gcmkONERROR(gckOS_Allocate(
+ Os,
+ gcmSIZEOF(gcsCONTEXT),
+ &pointer
+ ));
+
+ buffer = pointer;
+
+ /* Reset the context buffer structure. */
+ gcmkVERIFY_OK(gckOS_ZeroMemory(
+ buffer, gcmSIZEOF(gcsCONTEXT)
+ ));
+
+ /* Append to the list. */
+ if (context->buffer == gcvNULL)
+ {
+ buffer->next = buffer;
+ context->buffer = buffer;
+ }
+ else
+ {
+ buffer->next = context->buffer->next;
+ context->buffer->next = buffer;
+ }
+
+ /* Set the number of delta in the order of creation. */
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ buffer->num = i;
+#endif
+
+ /* Create the busy signal. */
+ gcmkONERROR(gckOS_CreateSignal(
+ Os, gcvFALSE, &buffer->signal
+ ));
+
+ /* Set the signal, buffer is currently not busy. */
+ gcmkONERROR(gckOS_Signal(
+ Os, buffer->signal, gcvTRUE
+ ));
+
+ /* Create a new physical context buffer. */
+#if gcdVIRTUAL_COMMAND_BUFFER
+ gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
+ context->hardware->kernel,
+ gcvFALSE,
+ &context->totalSize,
+ &buffer->physical,
+ &pointer
+ ));
+
+#else
+ gcmkONERROR(gckOS_AllocateContiguous(
+ Os,
+ gcvFALSE,
+ &context->totalSize,
+ &buffer->physical,
+ &pointer
+ ));
+#endif
+
+ buffer->logical = pointer;
+
+ /* Set gckEVENT object pointer. */
+ buffer->eventObj = Hardware->kernel->eventObj;
+
+ /* Set the pointers to the LINK commands. */
+ if (context->linkIndex2D != 0)
+ {
+ buffer->link2D = &buffer->logical[context->linkIndex2D];
+ }
+
+ if (context->linkIndex3D != 0)
+ {
+ buffer->link3D = &buffer->logical[context->linkIndex3D];
+ }
+
+ if (context->linkIndexXD != 0)
+ {
+ gctPOINTER xdLink;
+ gctUINT8_PTR xdEntryLogical;
+ gctSIZE_T xdEntrySize;
+ gctSIZE_T linkBytes;
+
+ /* Determine LINK parameters. */
+ xdLink
+ = &buffer->logical[context->linkIndexXD];
+
+ xdEntryLogical
+ = (gctUINT8_PTR) buffer->logical
+ + context->entryOffsetXDFrom3D;
+
+ xdEntrySize
+ = context->bufferSize
+ - context->entryOffsetXDFrom3D;
+
+ /* Query LINK size. */
+ gcmkONERROR(gckHARDWARE_Link(
+ Hardware, gcvNULL, gcvNULL, 0, &linkBytes
+ ));
+
+ /* Generate a LINK. */
+ gcmkONERROR(gckHARDWARE_Link(
+ Hardware,
+ xdLink,
+ xdEntryLogical,
+ xdEntrySize,
+ &linkBytes
+ ));
+ }
+ }
+
+
+ /**************************************************************************/
+ /* Initialize the context buffers. ****************************************/
+
+ /* Initialize the current context buffer. */
+ gcmkONERROR(_InitializeContextBuffer(context));
+
+ /* Make all created contexts equal. */
+ {
+ gcsCONTEXT_PTR currContext, tempContext;
+
+ /* Set the current context buffer. */
+ currContext = context->buffer;
+
+ /* Get the next context buffer. */
+ tempContext = currContext->next;
+
+ /* Loop through all buffers. */
+ while (tempContext != currContext)
+ {
+ if (tempContext == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+
+ /* Copy the current context. */
+ gcmkONERROR(gckOS_MemCopy(
+ tempContext->logical,
+ currContext->logical,
+ context->totalSize
+ ));
+
+ /* Get the next context buffer. */
+ tempContext = tempContext->next;
+ }
+ }
+
+ /* Return pointer to the gckCONTEXT object. */
+ *Context = context;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Context=0x%08X", *Context);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back on error. */
+ gcmkVERIFY_OK(_DestroyContext(context));
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/******************************************************************************\
+**
+** gckCONTEXT_Destroy
+**
+** Destroy a gckCONTEXT object.
+**
+** INPUT:
+**
+** gckCONTEXT Context
+** Pointer to an gckCONTEXT object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCONTEXT_Destroy(
+ IN gckCONTEXT Context
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Context=0x%08X", Context);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
+
+ /* Destroy the context and all related objects. */
+ status = _DestroyContext(Context);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return status;
+}
+
+/******************************************************************************\
+**
+** gckCONTEXT_Update
+**
+** Merge all pending state delta buffers into the current context buffer.
+**
+** INPUT:
+**
+** gckCONTEXT Context
+** Pointer to an gckCONTEXT object.
+**
+** gctUINT32 ProcessID
+** Current process ID.
+**
+** gcsSTATE_DELTA_PTR StateDelta
+** Pointer to the state delta.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckCONTEXT_Update(
+ IN gckCONTEXT Context,
+ IN gctUINT32 ProcessID,
+ IN gcsSTATE_DELTA_PTR StateDelta
+ )
+{
+#ifndef VIVANTE_NO_3D
+ gceSTATUS status = gcvSTATUS_OK;
+ gcsSTATE_DELTA _stateDelta;
+ gckKERNEL kernel;
+ gcsCONTEXT_PTR buffer;
+ gcsSTATE_MAP_PTR map;
+ gctBOOL needCopy = gcvFALSE;
+ gcsSTATE_DELTA_PTR nDelta;
+ gcsSTATE_DELTA_PTR uDelta = gcvNULL;
+ gcsSTATE_DELTA_PTR kDelta = gcvNULL;
+ gcsSTATE_DELTA_RECORD_PTR record;
+ gcsSTATE_DELTA_RECORD_PTR recordArray = gcvNULL;
+ gctUINT elementCount;
+ gctUINT address;
+ gctUINT32 mask;
+ gctUINT32 data;
+ gctUINT index;
+ gctUINT i, j;
+
+#if gcdSECURE_USER
+ gcskSECURE_CACHE_PTR cache;
+#endif
+
+ gcmkHEADER_ARG(
+ "Context=0x%08X ProcessID=%d StateDelta=0x%08X",
+ Context, ProcessID, StateDelta
+ );
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
+
+ /* Get a shortcut to the kernel object. */
+ kernel = Context->hardware->kernel;
+
+ /* Check wehther we need to copy the structures or not. */
+ gcmkONERROR(gckOS_QueryNeedCopy(Context->os, ProcessID, &needCopy));
+
+ /* Allocate the copy buffer for the user record array. */
+ if (needCopy && (Context->recordArray == gcvNULL))
+ {
+ /* Allocate the buffer. */
+ gcmkONERROR(gckOS_Allocate(
+ Context->os,
+ Context->recordArraySize,
+ (gctPOINTER *) &Context->recordArray
+ ));
+ }
+
+ /* Get the current context buffer. */
+ buffer = Context->buffer;
+
+ /* Wait until the context buffer becomes available; this will
+ also reset the signal and mark the buffer as busy. */
+ gcmkONERROR(gckOS_WaitSignal(
+ Context->os, buffer->signal, gcvINFINITE
+ ));
+
+#if gcdSECURE_USER
+ /* Get the cache form the database. */
+ gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
+#endif
+
+#if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && !defined(VIVANTE_NO_3D)
+ /* Update current context token. */
+ buffer->logical[Context->map[0x0E14].index]
+ = gcmPTR2INT(Context);
+#endif
+
+ /* Are there any pending deltas? */
+ if (buffer->deltaCount != 0)
+ {
+ /* Get the state map. */
+ map = Context->map;
+
+ /* Get the first delta item. */
+ uDelta = buffer->delta;
+
+ /* Reset the vertex stream count. */
+ elementCount = 0;
+
+ /* Merge all pending deltas. */
+ for (i = 0; i < buffer->deltaCount; i += 1)
+ {
+ /* Get access to the state delta. */
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ kernel, needCopy,
+ &_stateDelta,
+ uDelta, gcmSIZEOF(gcsSTATE_DELTA),
+ (gctPOINTER *) &kDelta
+ ));
+
+ /* Get access to the state records. */
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ kernel, needCopy,
+ Context->recordArray,
+ kDelta->recordArray, Context->recordArraySize,
+ (gctPOINTER *) &recordArray
+ ));
+
+ /* Merge all pending states. */
+ for (j = 0; j < kDelta->recordCount; j += 1)
+ {
+ if (j >= Context->stateCount)
+ {
+ break;
+ }
+
+ /* Get the current state record. */
+ record = &recordArray[j];
+
+ /* Get the state address. */
+ address = record->address;
+
+ /* Make sure the state is a part of the mapping table. */
+ if (address >= Context->stateCount)
+ {
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): State 0x%04X is not mapped.\n",
+ __FUNCTION__, __LINE__,
+ address
+ );
+
+ continue;
+ }
+
+ /* Get the state index. */
+ index = map[address].index;
+
+ /* Skip the state if not mapped. */
+ if (index == 0)
+ {
+#if gcdDEBUG
+ if ((address != 0x0594)
+ && (address != 0x0E00)
+ && (address != 0x0E03)
+ )
+ {
+#endif
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): State 0x%04X is not mapped.\n",
+ __FUNCTION__, __LINE__,
+ address
+ );
+#if gcdDEBUG
+ }
+#endif
+ continue;
+ }
+
+ /* Get the data mask. */
+ mask = record->mask;
+
+ /* Masked states that are being completly reset or regular states. */
+ if ((mask == 0) || (mask == ~0U))
+ {
+ /* Get the new data value. */
+ data = record->data;
+
+ /* Process special states. */
+ if (address == 0x0595)
+ {
+ /* Force auto-disable to be disabled. */
+ data = ((((gctUINT32) (data)) & ~(((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)));
+ 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) (0x0 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1))))))) << (0 ? 13:13))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 13:13) - (0 ? 13:13) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 13:13) - (0 ? 13:13) + 1))))))) << (0 ? 13:13)));
+ }
+
+#if gcdSECURE_USER
+ /* Do we need to convert the logical address? */
+ if (Context->hint[address])
+ {
+ /* Map handle into physical address. */
+ gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
+ kernel, cache, (gctPOINTER) &data
+ ));
+ }
+#endif
+
+ /* Set new data. */
+ buffer->logical[index] = data;
+ }
+
+ /* Masked states that are being set partially. */
+ else
+ {
+ buffer->logical[index]
+ = (~mask & buffer->logical[index])
+ | (mask & record->data);
+ }
+ }
+
+ /* Get the element count. */
+ if (kDelta->elementCount != 0)
+ {
+ elementCount = kDelta->elementCount;
+ }
+
+ /* Dereference delta. */
+ kDelta->refCount -= 1;
+ gcmkASSERT(kDelta->refCount >= 0);
+
+ /* Get the next state delta. */
+ nDelta = kDelta->next;
+
+ /* Get access to the state records. */
+ gcmkONERROR(gckKERNEL_CloseUserData(
+ kernel, needCopy,
+ gcvFALSE,
+ kDelta->recordArray, Context->recordArraySize,
+ (gctPOINTER *) &recordArray
+ ));
+
+ /* Close access to the current state delta. */
+ gcmkONERROR(gckKERNEL_CloseUserData(
+ kernel, needCopy,
+ gcvTRUE,
+ uDelta, gcmSIZEOF(gcsSTATE_DELTA),
+ (gctPOINTER *) &kDelta
+ ));
+
+ /* Update the user delta pointer. */
+ uDelta = nDelta;
+ }
+
+ /* Hardware disables all input streams when the stream 0 is programmed,
+ it then reenables those streams that were explicitely programmed by
+ the software. Because of this we cannot program the entire array of
+ values, otherwise we'll get all streams reenabled, but rather program
+ only those that are actully needed by the software. */
+ if (elementCount != 0)
+ {
+ gctUINT base;
+ gctUINT nopCount;
+ gctUINT32_PTR nop;
+ gctUINT fe2vsCount = 12;
+
+ if ((((((gctUINT32) (Context->hardware->identity.chipMinorFeatures1)) >> (0 ? 23:23)) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) ))
+ {
+ fe2vsCount = 16;
+ }
+
+ /* Determine the base index of the vertex stream array. */
+ base = map[0x0180].index;
+
+ /* Set the proper state count. */
+ buffer->logical[base - 1]
+ = ((((gctUINT32) (buffer->logical[base - 1])) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (elementCount ) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+ /* Determine the number of NOP commands. */
+ nopCount
+ = (fe2vsCount / 2)
+ - (elementCount / 2);
+
+ /* Determine the location of the first NOP. */
+ nop = &buffer->logical[base + (elementCount | 1)];
+
+ /* Fill the unused space with NOPs. */
+ for (i = 0; i < nopCount; i += 1)
+ {
+ if (nop >= buffer->logical + Context->totalSize)
+ {
+ break;
+ }
+
+ /* Generate a NOP command. */
+ *nop = ((((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)));
+
+ /* Advance. */
+ nop += 2;
+ }
+ }
+
+ /* Reset pending deltas. */
+ buffer->deltaCount = 0;
+ buffer->delta = gcvNULL;
+ }
+
+ /* Set state delta user pointer. */
+ uDelta = StateDelta;
+
+ /* Get access to the state delta. */
+ gcmkONERROR(gckKERNEL_OpenUserData(
+ kernel, needCopy,
+ &_stateDelta,
+ uDelta, gcmSIZEOF(gcsSTATE_DELTA),
+ (gctPOINTER *) &kDelta
+ ));
+
+ /* State delta cannot be attached to anything yet. */
+ if (kDelta->refCount != 0)
+ {
+ gcmkTRACE(
+ gcvLEVEL_ERROR,
+ "%s(%d): kDelta->refCount = %d (has to be 0).\n",
+ __FUNCTION__, __LINE__,
+ kDelta->refCount
+ );
+ }
+
+ /* Attach to all contexts. */
+ buffer = Context->buffer;
+
+ do
+ {
+ /* Attach to the context if nothing is attached yet. If a delta
+ is allready attached, all we need to do is to increment
+ the number of deltas in the context. */
+ if (buffer->delta == gcvNULL)
+ {
+ buffer->delta = uDelta;
+ }
+
+ /* Update reference count. */
+ kDelta->refCount += 1;
+
+ /* Update counters. */
+ buffer->deltaCount += 1;
+
+ /* Get the next context buffer. */
+ buffer = buffer->next;
+
+ if (buffer == gcvNULL)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_FOUND);
+ }
+ }
+ while (Context->buffer != buffer);
+
+ /* Close access to the current state delta. */
+ gcmkONERROR(gckKERNEL_CloseUserData(
+ kernel, needCopy,
+ gcvTRUE,
+ uDelta, gcmSIZEOF(gcsSTATE_DELTA),
+ (gctPOINTER *) &kDelta
+ ));
+
+ /* Schedule an event to mark the context buffer as available. */
+ gcmkONERROR(gckEVENT_Signal(
+ buffer->eventObj, buffer->signal, gcvKERNEL_PIXEL
+ ));
+
+ /* Advance to the next context buffer. */
+ Context->buffer = buffer->next;
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Get access to the state records. */
+ if (kDelta != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ kernel, needCopy,
+ gcvFALSE,
+ kDelta->recordArray, Context->recordArraySize,
+ (gctPOINTER *) &recordArray
+ ));
+ }
+
+ /* Close access to the current state delta. */
+ gcmkVERIFY_OK(gckKERNEL_CloseUserData(
+ kernel, needCopy,
+ gcvTRUE,
+ uDelta, gcmSIZEOF(gcsSTATE_DELTA),
+ (gctPOINTER *) &kDelta
+ ));
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+#else
+ return gcvSTATUS_OK;
+#endif
+}
+
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h
new file mode 100644
index 00000000..a5030deb
--- /dev/null
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2012 by Vivante Corp.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+
+#ifndef __gc_hal_kernel_context_h_
+#define __gc_hal_kernel_context_h_
+
+#include "gc_hal_kernel_buffer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Maps state locations within the context buffer. */
+typedef struct _gcsSTATE_MAP * gcsSTATE_MAP_PTR;
+typedef struct _gcsSTATE_MAP
+{
+ /* Index of the state in the context buffer. */
+ gctUINT index;
+
+ /* State mask. */
+ gctUINT32 mask;
+}
+gcsSTATE_MAP;
+
+/* Context buffer. */
+typedef struct _gcsCONTEXT * gcsCONTEXT_PTR;
+typedef struct _gcsCONTEXT
+{
+ /* For debugging: the number of context buffer in the order of creation. */
+#if gcmIS_DEBUG(gcdDEBUG_CODE)
+ gctUINT num;
+#endif
+
+ /* Pointer to gckEVENT object. */
+ gckEVENT eventObj;
+
+ /* Context busy signal. */
+ gctSIGNAL signal;
+
+ /* Physical address of the context buffer. */
+ gctPHYS_ADDR physical;
+
+ /* Logical address of the context buffer. */
+ gctUINT32_PTR logical;
+
+ /* Pointer to the LINK commands. */
+ gctPOINTER link2D;
+ gctPOINTER link3D;
+
+ /* The number of pending state deltas. */
+ gctUINT deltaCount;
+
+ /* Pointer to the first delta to be applied. */
+ gcsSTATE_DELTA_PTR delta;
+
+ /* Next context buffer. */
+ gcsCONTEXT_PTR next;
+}
+gcsCONTEXT;
+
+/* gckCONTEXT structure that hold the current context. */
+struct _gckCONTEXT
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to gckOS object. */
+ gckOS os;
+
+ /* Pointer to gckHARDWARE object. */
+ gckHARDWARE hardware;
+
+ /* Command buffer alignment. */
+ gctSIZE_T alignment;
+ gctSIZE_T reservedHead;
+ gctSIZE_T reservedTail;
+
+ /* Context buffer metrics. */
+ gctSIZE_T stateCount;
+ gctSIZE_T totalSize;
+ gctSIZE_T bufferSize;
+ gctUINT32 linkIndex2D;
+ gctUINT32 linkIndex3D;
+ gctUINT32 linkIndexXD;
+ gctUINT32 entryOffset3D;
+ gctUINT32 entryOffsetXDFrom2D;
+ gctUINT32 entryOffsetXDFrom3D;
+
+ /* Dirty flags. */
+ gctBOOL dirty;
+ gctBOOL dirty2D;
+ gctBOOL dirty3D;
+ gcsCONTEXT_PTR dirtyBuffer;
+
+ /* State mapping. */
+ gcsSTATE_MAP_PTR map;
+
+ /* List of context buffers. */
+ gcsCONTEXT_PTR buffer;
+
+ /* A copy of the user record array. */
+ gctUINT recordArraySize;
+ gcsSTATE_DELTA_RECORD_PTR recordArray;
+
+ /* Requested pipe select for context. */
+ gcePIPE_SELECT entryPipe;
+ gcePIPE_SELECT exitPipe;
+
+ /* Variables used for building state buffer. */
+ gctUINT32 lastAddress;
+ gctSIZE_T lastSize;
+ gctUINT32 lastIndex;
+ gctBOOL lastFixed;
+
+ /* Hint array. */
+#if gcdSECURE_USER
+ gctBOOL_PTR hint;
+#endif
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_context_h_ */
+
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
new file mode 100644
index 00000000..f6b0557d
--- /dev/null
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
@@ -0,0 +1,6237 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2012 by Vivante Corp.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+
+#define _GC_OBJ_ZONE gcvZONE_HARDWARE
+
+typedef struct _gcsiDEBUG_REGISTERS * gcsiDEBUG_REGISTERS_PTR;
+typedef struct _gcsiDEBUG_REGISTERS
+{
+ gctSTRING module;
+ gctUINT index;
+ gctUINT shift;
+ gctUINT data;
+ gctUINT count;
+ gctUINT32 signature;
+}
+gcsiDEBUG_REGISTERS;
+
+extern int gpu3DMinClock;
+/******************************************************************************\
+********************************* Support Code *********************************
+\******************************************************************************/
+static gceSTATUS
+_ResetGPU(
+ IN gckHARDWARE Hardware,
+ IN gckOS Os,
+ IN gceCORE Core
+ );
+
+static gceSTATUS
+_IdentifyHardware(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
+ )
+{
+ gceSTATUS status;
+
+ gctUINT32 chipIdentity;
+
+ gctUINT32 streamCount = 0;
+ gctUINT32 registerMax = 0;
+ gctUINT32 threadCount = 0;
+ gctUINT32 shaderCoreCount = 0;
+ gctUINT32 vertexCacheSize = 0;
+ gctUINT32 vertexOutputBufferSize = 0;
+ gctUINT32 pixelPipes = 0;
+ gctUINT32 instructionCount = 0;
+ gctUINT32 numConstants = 0;
+ gctUINT32 bufferSize = 0;
+ gctUINT32 varyingsCount = 0;
+
+ gcmkHEADER_ARG("Os=0x%x", Os);
+
+ /***************************************************************************
+ ** Get chip ID and revision.
+ */
+
+ /* Read chip identity register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00018,
+ &chipIdentity));
+
+ /* Special case for older graphic cores. */
+ 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))))))))
+ {
+ Identity->chipModel = gcv500;
+ 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)))))) );
+ }
+
+ else
+ {
+ /* Read chip identity register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00020,
+ (gctUINT32_PTR) &Identity->chipModel));
+
+ /* !!!! HACK ALERT !!!! */
+ /* Because people change device IDs without letting software know
+ ** about it - here is the hack to make it all look the same. Only
+ ** for GC400 family. Next time - TELL ME!!! */
+ if (((Identity->chipModel & 0xFF00) == 0x0400)
+ && (Identity->chipModel != 0x0420))
+ {
+ Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400);
+ }
+
+ /* Read CHIP_REV register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00024,
+ &Identity->chipRevision));
+
+ if ((Identity->chipModel == gcv300)
+ && (Identity->chipRevision == 0x2201)
+ )
+ {
+ gctUINT32 chipDate;
+ gctUINT32 chipTime;
+
+ /* Read date and time registers. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00028,
+ &chipDate));
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x0002C,
+ &chipTime));
+
+ if ((chipDate == 0x20080814) && (chipTime == 0x12051100))
+ {
+ /* This IP has an ECO; put the correct revision in it. */
+ Identity->chipRevision = 0x1051;
+ }
+ }
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipModel=%X",
+ Identity->chipModel);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipRevision=%X",
+ Identity->chipRevision);
+
+
+ /***************************************************************************
+ ** Get chip features.
+ */
+
+ /* Read chip feature register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x0001C,
+ &Identity->chipFeatures));
+
+#ifndef VIVANTE_NO_3D
+ /* Disable fast clear on GC700. */
+ if (Identity->chipModel == gcv700)
+ {
+ Identity->chipFeatures
+ = ((((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)));
+ }
+#endif
+
+ if (((Identity->chipModel == gcv500) && (Identity->chipRevision < 2))
+ || ((Identity->chipModel == gcv300) && (Identity->chipRevision < 0x2000))
+ )
+ {
+ /* GC500 rev 1.x and GC300 rev < 2.0 doesn't have these registers. */
+ Identity->chipMinorFeatures = 0;
+ Identity->chipMinorFeatures1 = 0;
+ Identity->chipMinorFeatures2 = 0;
+ Identity->chipMinorFeatures3 = 0;
+ }
+ else
+ {
+ /* Read chip minor feature register #0. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00034,
+ &Identity->chipMinorFeatures));
+
+ 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)))))))
+ )
+ {
+ /* Read chip minor featuress register #1. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00074,
+ &Identity->chipMinorFeatures1));
+
+ /* Read chip minor featuress register #2. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00084,
+ &Identity->chipMinorFeatures2));
+
+ /*Identity->chipMinorFeatures2 &= ~(0x1 << 3);*/
+
+ /* Read chip minor featuress register #1. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00088,
+ &Identity->chipMinorFeatures3));
+ }
+ else
+ {
+ /* Chip doesn't has minor features register #1 or 2 or 3. */
+ Identity->chipMinorFeatures1 = 0;
+ Identity->chipMinorFeatures2 = 0;
+ Identity->chipMinorFeatures3 = 0;
+ }
+ }
+
+ /* Get the Supertile layout in the hardware. */
+ 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)))))))
+ || ((((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))))))))
+ {
+ Identity->superTileMode = 2;
+ }
+ 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))))))))
+ {
+ Identity->superTileMode = 1;
+ }
+ else
+ {
+ Identity->superTileMode = 0;
+ }
+
+ /* Exception for GC1000, revision 5035 & GC800, revision 4612 */
+ if (((Identity->chipModel == gcv1000) && (Identity->chipRevision == 0x5035))
+ || ((Identity->chipModel == gcv800) && (Identity->chipRevision == 0x4612)))
+ {
+ Identity->superTileMode = 1;
+ }
+
+
+
+ /* Disable HZ when EZ is present for older chips. */
+ 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))))))))
+ {
+ /* Disable HIERARCHICAL_Z. */
+ Identity->chipMinorFeatures
+ = ((((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)));
+ }
+
+ /* Disable rectangle primitive when chip is gc880_5_1_0_rc6*/
+ if ((Identity->chipModel == gcv880) && (Identity->chipRevision == 0x5106))
+ {
+ /* Disable rectangle primitive. */
+ Identity->chipMinorFeatures2
+ = ((((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)));
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipFeatures=0x%08X",
+ Identity->chipFeatures);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipMinorFeatures=0x%08X",
+ Identity->chipMinorFeatures);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipMinorFeatures1=0x%08X",
+ Identity->chipMinorFeatures1);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipMinorFeatures2=0x%08X",
+ Identity->chipMinorFeatures2);
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Identity: chipMinorFeatures3=0x%08X",
+ Identity->chipMinorFeatures3);
+
+ /***************************************************************************
+ ** Get chip specs.
+ */
+
+ 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))))))))
+ {
+ gctUINT32 specs, specs2, specs3;
+
+ /* Read gcChipSpecs register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00048,
+ &specs));
+
+ /* Extract the fields. */
+ streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) );
+ registerMax = (((((gctUINT32) (specs)) >> (0 ? 7:4)) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1)))))) );
+ threadCount = (((((gctUINT32) (specs)) >> (0 ? 11:8)) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1)))))) );
+ shaderCoreCount = (((((gctUINT32) (specs)) >> (0 ? 24:20)) & ((gctUINT32) ((((1 ? 24:20) - (0 ? 24:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:20) - (0 ? 24:20) + 1)))))) );
+ vertexCacheSize = (((((gctUINT32) (specs)) >> (0 ? 16:12)) & ((gctUINT32) ((((1 ? 16:12) - (0 ? 16:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:12) - (0 ? 16:12) + 1)))))) );
+ vertexOutputBufferSize = (((((gctUINT32) (specs)) >> (0 ? 31:28)) & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1)))))) );
+ pixelPipes = (((((gctUINT32) (specs)) >> (0 ? 27:25)) & ((gctUINT32) ((((1 ? 27:25) - (0 ? 27:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:25) - (0 ? 27:25) + 1)))))) );
+
+ /* Read gcChipSpecs2 register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x00080,
+ &specs2));
+
+ instructionCount = (((((gctUINT32) (specs2)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) );
+ numConstants = (((((gctUINT32) (specs2)) >> (0 ? 31:16)) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1)))))) );
+ bufferSize = (((((gctUINT32) (specs2)) >> (0 ? 7:0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1)))))) );
+
+ /* Read gcChipSpecs3 register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Os, Core,
+ 0x0008C,
+ &specs3));
+
+ varyingsCount = (((((gctUINT32) (specs3)) >> (0 ? 8:4)) & ((gctUINT32) ((((1 ? 8:4) - (0 ? 8:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:4) - (0 ? 8:4) + 1)))))) );
+ }
+
+ /* Get the number of pixel pipes. */
+ Identity->pixelPipes = gcmMAX(pixelPipes, 1);
+
+ /* Get the stream count. */
+ Identity->streamCount = (streamCount != 0)
+ ? streamCount
+ : (Identity->chipModel >= gcv1000) ? 4 : 1;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: streamCount=%u%s",
+ Identity->streamCount,
+ (streamCount == 0) ? " (default)" : "");
+
+ /* Get the vertex output buffer size. */
+ Identity->vertexOutputBufferSize = (vertexOutputBufferSize != 0)
+ ? 1 << vertexOutputBufferSize
+ : (Identity->chipModel == gcv400)
+ ? (Identity->chipRevision < 0x4000) ? 512
+ : (Identity->chipRevision < 0x4200) ? 256
+ : 128
+ : (Identity->chipModel == gcv530)
+ ? (Identity->chipRevision < 0x4200) ? 512
+ : 128
+ : 512;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: vertexOutputBufferSize=%u%s",
+ Identity->vertexOutputBufferSize,
+ (vertexOutputBufferSize == 0) ? " (default)" : "");
+
+ /* Get the maximum number of threads. */
+ Identity->threadCount = (threadCount != 0)
+ ? 1 << threadCount
+ : (Identity->chipModel == gcv400) ? 64
+ : (Identity->chipModel == gcv500) ? 128
+ : (Identity->chipModel == gcv530) ? 128
+ : 256;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: threadCount=%u%s",
+ Identity->threadCount,
+ (threadCount == 0) ? " (default)" : "");
+
+ /* Get the number of shader cores. */
+ Identity->shaderCoreCount = (shaderCoreCount != 0)
+ ? shaderCoreCount
+ : (Identity->chipModel >= gcv1000) ? 2
+ : 1;
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: shaderCoreCount=%u%s",
+ Identity->shaderCoreCount,
+ (shaderCoreCount == 0) ? " (default)" : "");
+
+ /* Get the vertex cache size. */
+ Identity->vertexCacheSize = (vertexCacheSize != 0)
+ ? vertexCacheSize
+ : 8;
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: vertexCacheSize=%u%s",
+ Identity->vertexCacheSize,
+ (vertexCacheSize == 0) ? " (default)" : "");
+
+ /* Get the maximum number of temporary registers. */
+ Identity->registerMax = (registerMax != 0)
+ /* Maximum of registerMax/4 registers are accessible to 1 shader */
+ ? 1 << registerMax
+ : (Identity->chipModel == gcv400) ? 32
+ : 64;
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: registerMax=%u%s",
+ Identity->registerMax,
+ (registerMax == 0) ? " (default)" : "");
+
+ /* Get the instruction count. */
+ Identity->instructionCount = (instructionCount == 0) ? 256
+ : (instructionCount == 1) ? 1024
+ : (instructionCount == 2) ? 2048
+ : (instructionCount == 0xFF) ? 512
+ : 256;
+
+ if (Identity->instructionCount == 256)
+ {
+ if ((Identity->chipModel == gcv2000 && Identity->chipRevision == 0x5108)
+ || Identity->chipModel == gcv880)
+ {
+ Identity->instructionCount = 512;
+ }
+ }
+
+ 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))))))))
+ {
+ Identity->instructionCount = 512;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: instructionCount=%u%s",
+ Identity->instructionCount,
+ (instructionCount == 0) ? " (default)" : "");
+
+ /* Get the number of constants. */
+ Identity->numConstants = (numConstants == 0) ? 168 : numConstants;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: numConstants=%u%s",
+ Identity->numConstants,
+ (numConstants == 0) ? " (default)" : "");
+
+ /* Get the buffer size. */
+ Identity->bufferSize = bufferSize;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Specs: bufferSize=%u%s",
+ Identity->bufferSize,
+ (bufferSize == 0) ? " (default)" : "");
+
+
+ if (varyingsCount != 0)
+ {
+ /* Bug 4480. */
+ /*Identity->varyingsCount = varyingsCount;*/
+ Identity->varyingsCount = 12;
+ }
+ 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))))))))
+ {
+ Identity->varyingsCount = 12;
+ }
+ else
+ {
+ Identity->varyingsCount = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdPOWEROFF_TIMEOUT
+void
+_PowerTimerFunction(
+ gctPOINTER Data
+ )
+{
+ gckHARDWARE hardware = (gckHARDWARE)Data;
+ gcmkVERIFY_OK(
+ gckHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
+}
+#endif
+
+static gceSTATUS
+_VerifyDMA(
+ IN gckOS Os,
+ IN gceCORE Core,
+ gctUINT32_PTR Address1,
+ gctUINT32_PTR Address2,
+ gctUINT32_PTR State1,
+ gctUINT32_PTR State2
+ )
+{
+ gceSTATUS status;
+ gctUINT32 i;
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State1));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address1));
+
+ for (i = 0; i < 500; i += 1)
+ {
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x660, State2));
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x664, Address2));
+
+ if (*Address1 != *Address2)
+ {
+ break;
+ }
+
+ if (*State1 != *State2)
+ {
+ break;
+ }
+ }
+
+OnError:
+ return status;
+}
+
+static gceSTATUS
+_DumpDebugRegisters(
+ IN gckOS Os,
+ IN gceCORE Core,
+ IN gcsiDEBUG_REGISTERS_PTR Descriptor
+ )
+{
+ gceSTATUS status;
+ gctUINT32 select;
+ gctUINT32 data;
+ gctUINT i;
+
+ gcmkHEADER_ARG("Os=0x%X Descriptor=0x%X", Os, Descriptor);
+
+ gcmkPRINT_N(4, " %s debug registers:\n", Descriptor->module);
+
+ for (i = 0; i < Descriptor->count; i += 1)
+ {
+ select = i << Descriptor->shift;
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
+#if gcdFPGA_BUILD
+ gcmkONERROR(gckOS_Delay(Os, 1000));
+#endif
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
+
+ gcmkPRINT_N(12, " [0x%02X] 0x%08X\n", i, data);
+ }
+
+ select = 0xF << Descriptor->shift;
+
+ for (i = 0; i < 500; i += 1)
+ {
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, select));
+#if gcdFPGA_BUILD
+ gcmkONERROR(gckOS_Delay(Os, 1000));
+#endif
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &data));
+
+ if (data == Descriptor->signature)
+ {
+ break;
+ }
+ }
+
+ if (i == 500)
+ {
+ gcmkPRINT_N(4, " failed to obtain the signature (read 0x%08X).\n", data);
+ }
+ else
+ {
+ gcmkPRINT_N(8, " signature = 0x%08X (%d read attempt(s))\n", data, i + 1);
+ }
+
+OnError:
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if gcdPOWER_MANAGEMENT
+static gceSTATUS
+_IsGPUPresent(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gcsHAL_QUERY_CHIP_IDENTITY identity;
+ gctUINT32 control;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &control));
+
+ 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)));
+ 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)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ control));
+
+ /* Identify the hardware. */
+ gcmkONERROR(_IdentifyHardware(Hardware->os,
+ Hardware->core,
+ &identity));
+
+ /* Check if these are the same values as saved before. */
+ if ((Hardware->identity.chipModel != identity.chipModel)
+ || (Hardware->identity.chipRevision != identity.chipRevision)
+ || (Hardware->identity.chipFeatures != identity.chipFeatures)
+ || (Hardware->identity.chipMinorFeatures != identity.chipMinorFeatures)
+ || (Hardware->identity.chipMinorFeatures1 != identity.chipMinorFeatures1)
+ || (Hardware->identity.chipMinorFeatures2 != identity.chipMinorFeatures2)
+ )
+ {
+ gcmkPRINT("[galcore]: GPU is not present.");
+ gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+/******************************************************************************\
+****************************** gckHARDWARE API code *****************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+** gckHARDWARE_Construct
+**
+** Construct a new gckHARDWARE object.
+**
+** INPUT:
+**
+** gckOS Os
+** Pointer to an initialized gckOS object.
+**
+** gceCORE Core
+** Specified core.
+**
+** OUTPUT:
+**
+** gckHARDWARE * Hardware
+** Pointer to a variable that will hold the pointer to the gckHARDWARE
+** object.
+*/
+gceSTATUS
+gckHARDWARE_Construct(
+ IN gckOS Os,
+ IN gceCORE Core,
+ OUT gckHARDWARE * Hardware
+ )
+{
+ gceSTATUS status;
+ gckHARDWARE hardware = gcvNULL;
+ gctUINT16 data = 0xff00;
+ gctUINT32 axi_ot;
+ gctPOINTER pointer = gcvNULL;
+
+ gcmkHEADER_ARG("Os=0x%x", Os);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+ gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
+
+ /* Enable the GPU. */
+ gcmkONERROR(gckOS_SetGPUPower(Os, Core, gcvTRUE, gcvTRUE));
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ 0x00000900));
+
+ /* Allocate the gckHARDWARE object. */
+ gcmkONERROR(gckOS_Allocate(Os,
+ gcmSIZEOF(struct _gckHARDWARE),
+ &pointer));
+
+ hardware = (gckHARDWARE) pointer;
+
+ /* Initialize the gckHARDWARE object. */
+ hardware->object.type = gcvOBJ_HARDWARE;
+ hardware->os = Os;
+ hardware->core = Core;
+
+ /* Identify the hardware. */
+ gcmkONERROR(_IdentifyHardware(Os, Core, &hardware->identity));
+
+ /* Determine the hardware type */
+ switch (hardware->identity.chipModel)
+ {
+ case gcv350:
+ case gcv355:
+ hardware->type = gcvHARDWARE_VG;
+ break;
+
+ case gcv300:
+ case gcv320:
+ hardware->type = gcvHARDWARE_2D;
+ /*set outstanding limit*/
+ gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x00414, &axi_ot));
+ axi_ot = (axi_ot & (~0xFF)) | 0x10;
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00414, axi_ot));
+ break;
+
+ default:
+ hardware->type = gcvHARDWARE_3D;
+
+ 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)))))) ))
+ {
+ hardware->type = (gceHARDWARE_TYPE) (hardware->type | gcvHARDWARE_2D);
+ }
+ }
+
+ hardware->powerBaseAddress
+ = ((hardware->identity.chipModel == gcv300)
+ && (hardware->identity.chipRevision < 0x2000))
+ ? 0x0100
+ : 0x0000;
+
+ /* _ResetGPU need powerBaseAddress. */
+ status = _ResetGPU(hardware, Os, Core);
+
+ if (status != gcvSTATUS_OK)
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "_ResetGPU failed: status=%d\n", status);
+ }
+
+ hardware->powerMutex = gcvNULL;
+
+ hardware->mmuVersion
+ = (((((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)))))) );
+
+ /* Determine whether bug fixes #1 are present. */
+ 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)))))));
+
+ /* Check if big endian */
+ hardware->bigEndian = (*(gctUINT8 *)&data == 0xff);
+
+ /* Initialize the fast clear. */
+ gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
+
+#if !gcdENABLE_128B_MERGE
+
+ 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))))))))
+ {
+ /* 128B merge is turned on by default. Disable it. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, 0));
+ }
+
+#endif
+
+ /* Set power state to ON. */
+ hardware->chipPowerState = gcvPOWER_ON;
+ hardware->clockState = gcvTRUE;
+ hardware->powerState = gcvTRUE;
+ hardware->lastWaitLink = ~0U;
+ hardware->globalSemaphore = gcvNULL;
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ hardware->powerOnFscaleVal = 64;
+#endif
+
+ gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
+ gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
+ hardware->startIsr = gcvNULL;
+ hardware->stopIsr = gcvNULL;
+
+#if gcdPOWEROFF_TIMEOUT
+ hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
+
+ gcmkVERIFY_OK(gckOS_CreateTimer(Os,
+ _PowerTimerFunction,
+ (gctPOINTER)hardware,
+ &hardware->powerOffTimer));
+#endif
+
+ gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pageTableDirty));
+
+#if gcdLINK_QUEUE_SIZE
+ hardware->linkQueue.front = 0;
+ hardware->linkQueue.rear = 0;
+ hardware->linkQueue.count = 0;
+#endif
+
+ /* Return pointer to the gckHARDWARE object. */
+ *Hardware = hardware;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Hardware=0x%x", *Hardware);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Roll back. */
+ if (hardware != gcvNULL)
+ {
+ /* Turn off the power. */
+ gcmkVERIFY_OK(gckOS_SetGPUPower(Os, Core, gcvFALSE, gcvFALSE));
+
+ if (hardware->globalSemaphore != gcvNULL)
+ {
+ /* Destroy the global semaphore. */
+ gcmkVERIFY_OK(gckOS_DestroySemaphore(Os,
+ hardware->globalSemaphore));
+ }
+
+ if (hardware->powerMutex != gcvNULL)
+ {
+ /* Destroy the power mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex));
+ }
+
+#if gcdPOWEROFF_TIMEOUT
+ if (hardware->powerOffTimer != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
+ gcmkVERIFY_OK(gckOS_DestoryTimer(Os, hardware->powerOffTimer));
+ }
+#endif
+
+ if (hardware->pageTableDirty != gcvNULL)
+ {
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pageTableDirty));
+ }
+
+ gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Destroy
+**
+** Destroy an gckHARDWARE object.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object that needs to be destroyed.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Destroy(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Destroy the power semaphore. */
+ gcmkVERIFY_OK(gckOS_DestroySemaphore(Hardware->os,
+ Hardware->globalSemaphore));
+
+ /* Destroy the power mutex. */
+ gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerMutex));
+
+#if gcdPOWEROFF_TIMEOUT
+ gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerOffTimer));
+ gcmkVERIFY_OK(gckOS_DestoryTimer(Hardware->os, Hardware->powerOffTimer));
+#endif
+
+ gcmkVERIFY_OK(gckOS_AtomDestroy(Hardware->os, Hardware->pageTableDirty));
+
+ /* Mark the object as unknown. */
+ Hardware->object.type = gcvOBJ_UNKNOWN;
+
+ /* Free the object. */
+ gcmkONERROR(gcmkOS_SAFE_FREE(Hardware->os, Hardware));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_GetType
+**
+** Get the hardware type.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gceHARDWARE_TYPE * Type
+** Pointer to a variable that receives the type of hardware object.
+*/
+gceSTATUS
+gckHARDWARE_GetType(
+ IN gckHARDWARE Hardware,
+ OUT gceHARDWARE_TYPE * Type
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+ gcmkVERIFY_ARGUMENT(Type != gcvNULL);
+
+ *Type = Hardware->type;
+
+ gcmkFOOTER_ARG("*Type=%d", *Type);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_InitializeHardware
+**
+** Initialize the hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_InitializeHardware(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gctUINT32 baseAddress;
+ gctUINT32 chipRev;
+ gctUINT32 control;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Read the chip revision register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00024,
+ &chipRev));
+
+ if (chipRev != Hardware->identity.chipRevision)
+ {
+ /* Chip is not there! */
+ gcmkONERROR(gcvSTATUS_CONTEXT_LOSSED);
+ }
+
+ /* Disable isolate GPU bit. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((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)))));
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &control));
+
+ /* Enable debug register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((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)))));
+
+ /* Reset memory counters. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0003C,
+ ~0U));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0003C,
+ 0));
+
+ /* Get the system's physical base address. */
+ gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
+
+ /* Program the base addesses. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0041C,
+ baseAddress));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00418,
+ baseAddress));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00428,
+ baseAddress));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00420,
+ baseAddress));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00424,
+ baseAddress));
+
+#if !VIVANTE_PROFILER
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress +
+ 0x00100,
+ &data));
+
+ /* Enable clock gating. */
+ 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)));
+
+ if ((Hardware->identity.chipRevision == 0x4301)
+ || (Hardware->identity.chipRevision == 0x4302)
+ )
+ {
+ /* Disable stall module level clock gating for 4.3.0.1 and 4.3.0.2
+ ** revisions. */
+ 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)));
+ }
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00100,
+ data));
+
+#ifndef VIVANTE_NO_3D
+ /* Disable PE clock gating on revs < 5.0 when HZ is present without a
+ ** bug fix. */
+ if ((Hardware->identity.chipRevision < 0x5000)
+ && ((((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)))))))
+ && ((((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)))))))
+ )
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &data));
+
+ /* Disable PE clock gating. */
+ 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)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ data));
+ }
+
+#endif
+ }
+#endif
+
+ /* Special workaround for this core
+ ** Make sure pulse eater kicks in only when SH is idle */
+ if (Hardware->identity.chipModel == gcv4000 &&
+ Hardware->identity.chipRevision == 0x5208)
+ {
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0010C,
+ ((((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)))));
+ }
+
+ /* Special workaround for this core
+ ** Make sure FE and TX are on different buses */
+ if ((Hardware->identity.chipModel == gcv2000)
+ && (Hardware->identity.chipRevision == 0x5108))
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00480,
+ &data));
+
+ /* Set FE bus to one, TX bus to zero */
+ 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)));
+ 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)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00480,
+ data));
+ }
+
+ /* Test if MMU is initialized. */
+ if ((Hardware->kernel != gcvNULL)
+ && (Hardware->kernel->mmu != gcvNULL)
+ )
+ {
+ /* Reset MMU. */
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkONERROR(
+ gckHARDWARE_SetMMU(Hardware,
+ Hardware->kernel->mmu->pageTableLogical));
+ }
+ }
+
+ if (Hardware->identity.chipModel >= gcv400
+ && Hardware->identity.chipModel != gcv420)
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &data));
+
+ /* Disable PA clock gating. */
+ 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)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ data));
+ }
+
+#if gcdHZ_L2_DISALBE
+ /* Disable HZ-L2. */
+ 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 ||
+ ((((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)
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ &data));
+
+ 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)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ data));
+ }
+#endif
+
+ /* Limit 2D outstanding request. */
+ if ((Hardware->identity.chipModel == gcv320)
+ && ((Hardware->identity.chipRevision == 0x5007)
+ || (Hardware->identity.chipRevision == 0x5220)))
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0002C,
+ &data));
+ if (data != 33956864)
+ {
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ &data));
+
+ 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)));
+
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ data));
+ }
+ }
+
+ /* Update GPU AXI cache atttribute. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00008,
+ 0x00002200));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryMemory
+**
+** Query the amount of memory available on the hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * InternalSize
+** Pointer to a variable that will hold the size of the internal video
+** memory in bytes. If 'InternalSize' is gcvNULL, no information of the
+** internal memory will be returned.
+**
+** gctUINT32 * InternalBaseAddress
+** Pointer to a variable that will hold the hardware's base address for
+** the internal video memory. This pointer cannot be gcvNULL if
+** 'InternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * InternalAlignment
+** Pointer to a variable that will hold the hardware's base address for
+** the internal video memory. This pointer cannot be gcvNULL if
+** 'InternalSize' is also non-gcvNULL.
+**
+** gctSIZE_T * ExternalSize
+** Pointer to a variable that will hold the size of the external video
+** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the
+** external memory will be returned.
+**
+** gctUINT32 * ExternalBaseAddress
+** Pointer to a variable that will hold the hardware's base address for
+** the external video memory. This pointer cannot be gcvNULL if
+** 'ExternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * ExternalAlignment
+** Pointer to a variable that will hold the hardware's base address for
+** the external video memory. This pointer cannot be gcvNULL if
+** 'ExternalSize' is also non-gcvNULL.
+**
+** gctUINT32 * HorizontalTileSize
+** Number of horizontal pixels per tile. If 'HorizontalTileSize' is
+** gcvNULL, no horizontal pixel per tile will be returned.
+**
+** gctUINT32 * VerticalTileSize
+** Number of vertical pixels per tile. If 'VerticalTileSize' is
+** gcvNULL, no vertical pixel per tile will be returned.
+*/
+gceSTATUS
+gckHARDWARE_QueryMemory(
+ IN gckHARDWARE Hardware,
+ OUT gctSIZE_T * InternalSize,
+ OUT gctUINT32 * InternalBaseAddress,
+ OUT gctUINT32 * InternalAlignment,
+ OUT gctSIZE_T * ExternalSize,
+ OUT gctUINT32 * ExternalBaseAddress,
+ OUT gctUINT32 * ExternalAlignment,
+ OUT gctUINT32 * HorizontalTileSize,
+ OUT gctUINT32 * VerticalTileSize
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (InternalSize != gcvNULL)
+ {
+ /* No internal memory. */
+ *InternalSize = 0;
+ }
+
+ if (ExternalSize != gcvNULL)
+ {
+ /* No external memory. */
+ *ExternalSize = 0;
+ }
+
+ if (HorizontalTileSize != gcvNULL)
+ {
+ /* 4x4 tiles. */
+ *HorizontalTileSize = 4;
+ }
+
+ if (VerticalTileSize != gcvNULL)
+ {
+ /* 4x4 tiles. */
+ *VerticalTileSize = 4;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*InternalSize=%lu *InternalBaseAddress=0x%08x "
+ "*InternalAlignment=0x%08x *ExternalSize=%lu "
+ "*ExternalBaseAddress=0x%08x *ExtenalAlignment=0x%08x "
+ "*HorizontalTileSize=%u *VerticalTileSize=%u",
+ gcmOPT_VALUE(InternalSize),
+ gcmOPT_VALUE(InternalBaseAddress),
+ gcmOPT_VALUE(InternalAlignment),
+ gcmOPT_VALUE(ExternalSize),
+ gcmOPT_VALUE(ExternalBaseAddress),
+ gcmOPT_VALUE(ExternalAlignment),
+ gcmOPT_VALUE(HorizontalTileSize),
+ gcmOPT_VALUE(VerticalTileSize));
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryChipIdentity
+**
+** Query the identity of the hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
+** Pointer to the identity structure.
+**
+*/
+gceSTATUS
+gckHARDWARE_QueryChipIdentity(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
+ )
+{
+ gctUINT32 features;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Identity != gcvNULL);
+
+ /* Return chip model and revision. */
+ Identity->chipModel = Hardware->identity.chipModel;
+ Identity->chipRevision = Hardware->identity.chipRevision;
+
+ /* Return feature set. */
+ features = Hardware->identity.chipFeatures;
+
+ if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
+ {
+ /* Override fast clear by command line. */
+ 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)));
+ }
+
+ if ((((((gctUINT32) (features)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ))
+ {
+ /* Override compression by command line. */
+ 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)));
+ }
+
+ /* Mark 2D pipe as available for GC500.0 through GC500.2 and GC300,
+ ** since they did not have this bit. */
+ if (((Hardware->identity.chipModel == gcv500) && (Hardware->identity.chipRevision <= 2))
+ || (Hardware->identity.chipModel == gcv300)
+ )
+ {
+ 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)));
+ }
+
+ Identity->chipFeatures = features;
+
+ /* Return minor features. */
+ Identity->chipMinorFeatures = Hardware->identity.chipMinorFeatures;
+ Identity->chipMinorFeatures1 = Hardware->identity.chipMinorFeatures1;
+ Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2;
+ Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3;
+
+ /* Return chip specs. */
+ Identity->streamCount = Hardware->identity.streamCount;
+ Identity->registerMax = Hardware->identity.registerMax;
+ Identity->threadCount = Hardware->identity.threadCount;
+ Identity->shaderCoreCount = Hardware->identity.shaderCoreCount;
+ Identity->vertexCacheSize = Hardware->identity.vertexCacheSize;
+ Identity->vertexOutputBufferSize = Hardware->identity.vertexOutputBufferSize;
+ Identity->pixelPipes = Hardware->identity.pixelPipes;
+ Identity->instructionCount = Hardware->identity.instructionCount;
+ Identity->numConstants = Hardware->identity.numConstants;
+ Identity->bufferSize = Hardware->identity.bufferSize;
+ Identity->varyingsCount = Hardware->identity.varyingsCount;
+ Identity->superTileMode = Hardware->identity.superTileMode;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_SplitMemory
+**
+** Split a hardware specific memory address into a pool and offset.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** gctUINT32 Address
+** Address in hardware specific format.
+**
+** OUTPUT:
+**
+** gcePOOL * Pool
+** Pointer to a variable that will hold the pool type for the address.
+**
+** gctUINT32 * Offset
+** Pointer to a variable that will hold the offset for the address.
+*/
+gceSTATUS
+gckHARDWARE_SplitMemory(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Address,
+ OUT gcePOOL * Pool,
+ OUT gctUINT32 * Offset
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x Addres=0x%08x", Hardware, Address);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Offset != gcvNULL);
+
+ if (Hardware->mmuVersion == 0)
+ {
+ /* Dispatch on memory type. */
+ switch ((((((gctUINT32) (Address)) >> (0 ? 31:31)) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) ))
+ {
+ case 0x0:
+ /* System memory. */
+ *Pool = gcvPOOL_SYSTEM;
+ break;
+
+ case 0x1:
+ /* Virtual memory. */
+ *Pool = gcvPOOL_VIRTUAL;
+ break;
+
+ default:
+ /* Invalid memory type. */
+ gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
+ return gcvSTATUS_INVALID_ARGUMENT;
+ }
+
+ /* Return offset of address. */
+ *Offset = (((((gctUINT32) (Address)) >> (0 ? 30:0)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1)))))) );
+ }
+ else
+ {
+ *Pool = gcvPOOL_SYSTEM;
+ *Offset = Address;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Pool=%d *Offset=0x%08x", *Pool, *Offset);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Execute
+**
+** Kickstart the hardware's command processor with an initialized command
+** buffer.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address of command buffer.
+**
+** gctSIZE_T Bytes
+** Number of bytes for the prefetch unit (until after the first LINK).
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Execute(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+#ifdef __QNXNTO__
+ IN gctPOINTER Physical,
+ IN gctBOOL PhysicalAddresses,
+#endif
+ IN gctSIZE_T Bytes
+ )
+{
+ gceSTATUS status;
+ gctUINT32 address = 0, control;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Bytes=%lu",
+ Hardware, Logical, Bytes);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+#ifdef __QNXNTO__
+ if (PhysicalAddresses && (Hardware->mmuVersion == 0))
+ {
+ /* Convert physical into hardware specific address. */
+ gcmkONERROR(
+ gckHARDWARE_ConvertPhysical(Hardware, Physical, &address));
+ }
+ else
+ {
+#endif
+ /* Convert logical into hardware specific address. */
+ gcmkONERROR(
+ gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
+#ifdef __QNXNTO__
+ }
+#endif
+
+ /* Enable all events. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U));
+
+ /* Write address register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, address));
+
+ /* Build control register. */
+ 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)))
+ | ((((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)));
+
+ /* Set big endian */
+ if (Hardware->bigEndian)
+ {
+ 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)));
+ }
+
+ /* Write control register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Started command buffer @ 0x%08x",
+ address);
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_WaitLink
+**
+** Append a WAIT/LINK command sequence at the specified location in the command
+** queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** WAIT/LINK command sequence at or gcvNULL just to query the size of the
+** WAIT/LINK command sequence.
+**
+** gctUINT32 Offset
+** Offset into command buffer required for alignment.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the WAIT/LINK command
+** sequence. If 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** by the WAIT/LINK command sequence. If 'Bytes' is gcvNULL, nothing will
+** be returned.
+**
+** gctUINT32 * WaitOffset
+** Pointer to a variable that will receive the offset of the WAIT command
+** from the specified logcial pointer.
+** If 'WaitOffset' is gcvNULL nothing will be returned.
+**
+** gctSIZE_T * WaitSize
+** Pointer to a variable that will receive the number of bytes used by
+** the WAIT command. If 'LinkSize' is gcvNULL nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_WaitLink(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Offset,
+ IN OUT gctSIZE_T * Bytes,
+ OUT gctUINT32 * WaitOffset,
+ OUT gctSIZE_T * WaitSize
+ )
+{
+ static const gctUINT waitCount = 200;
+
+ gceSTATUS status;
+ gctUINT32 address;
+ gctUINT32_PTR logical;
+ gctSIZE_T bytes;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu",
+ Hardware, Logical, Offset, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL));
+
+ /* Compute number of bytes required. */
+#if gcd6000_SUPPORT
+ bytes = gcmALIGN(Offset + 96, 8) - Offset;
+#else
+ bytes = gcmALIGN(Offset + 16, 8) - Offset;
+#endif
+
+ /* Cast the input pointer. */
+ logical = (gctUINT32_PTR) Logical;
+
+ if (logical != gcvNULL)
+ {
+ /* Not enough space? */
+ if (*Bytes < bytes)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Convert logical into hardware specific address. */
+ gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, &address));
+
+ /* Store the WAIT/LINK address. */
+ Hardware->lastWaitLink = address;
+
+ /* Append WAIT(count). */
+ 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)))
+ | ((((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)));
+
+#if gcd6000_SUPPORT
+ /* Send FE-PE sempahore token. */
+ 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)))
+ | ((((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)))
+ | ((((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)));
+
+ logical[3]
+ = ((((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)))
+ | ((((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)));
+
+ /* Send FE-PE stall token. */
+ 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)));
+
+ logical[5]
+ = ((((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)))
+ | ((((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)));
+
+ /*************************************************************/
+ /* Enable chip ID 0. */
+ logical[6] =
+ ((((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)))
+ | (1 << 0);
+
+ /* Send semaphore from FE to ChipID 1. */
+ logical[8] =
+ ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ logical[9] =
+ ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ /* Send semaphore from FE to ChipID 1. */
+ logical[10] =
+ ((((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)));
+
+ logical[11] =
+ ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ /*************************************************************/
+ /* Enable chip ID 1. */
+ logical[12] =
+ ((((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)))
+ | (1 << 1);
+
+ /* Send semaphore from FE to ChipID 1. */
+ logical[14] =
+ ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ logical[15] =
+ ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ /* Wait for semaphore from ChipID 0. */
+ logical[16] =
+ ((((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)));
+
+ logical[17] =
+ ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ /*************************************************************/
+ /* Enable all chips. */
+ logical[18] =
+ ((((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)))
+ | (0xFFFF);
+
+ /* LoadState(AQFlush, 1), flush. */
+ logical[20]
+ = ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ logical[21]
+ = ((((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)));
+
+ /* Append LINK(2, address). */
+ logical[22]
+ = ((((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)))
+ | ((((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)));
+
+ logical[23] = address;
+#else
+ /* Append LINK(2, address). */
+ 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) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+ | ((((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)));
+
+ logical[3] = address;
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: WAIT %u", address, waitCount
+ );
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: LINK 0x%08x, #%lu",
+ address + 8, address, bytes
+ );
+#endif
+
+ if (WaitOffset != gcvNULL)
+ {
+ /* Return the offset pointer to WAIT command. */
+ *WaitOffset = 0;
+ }
+
+ if (WaitSize != gcvNULL)
+ {
+ /* Return number of bytes used by the WAIT command. */
+ *WaitSize = 8;
+ }
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the WAIT/LINK command
+ ** sequence. */
+ *Bytes = bytes;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu *WaitOffset=0x%x *WaitSize=%lu",
+ gcmOPT_VALUE(Bytes), gcmOPT_VALUE(WaitOffset),
+ gcmOPT_VALUE(WaitSize));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_End
+**
+** Append an END command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** END command at or gcvNULL just to query the size of the END command.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the END command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the END command. If 'Bytes' is gcvNULL, nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_End(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Logical, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Append END. */
+ 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) (0x02 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", Logical);
+
+ /* Make sure the CPU writes out the data to memory. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, Logical));
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the END command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Nop
+**
+** Append a NOP command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** NOP command at or gcvNULL just to query the size of the NOP command.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the NOP command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_Nop(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Logical, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Append NOP. */
+ 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)));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical);
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the NOP command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Wait
+**
+** Append a WAIT command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** WAIT command at or gcvNULL just to query the size of the WAIT command.
+**
+** gctUINT32 Count
+** Number of cycles to wait.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the WAIT command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_Wait(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Count,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gceSTATUS status;
+ gctUINT32_PTR logical;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Count=%u *Bytes=%lu",
+ Hardware, Logical, Count, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ /* Cast the input pointer. */
+ logical = (gctUINT32_PTR) Logical;
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Append WAIT. */
+ 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)))
+ | ((((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)));
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ {
+ gctUINT32 address;
+
+ /* Convert logical into hardware specific address. */
+ gcmkONERROR(gckHARDWARE_ConvertLogical(
+ Hardware, logical, &address
+ ));
+
+ gcmkTRACE_ZONE(
+ gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: WAIT %u", address, Count
+ );
+ }
+#endif
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the WAIT command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Event
+**
+** Append an EVENT command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** the EVENT command at or gcvNULL just to query the size of the EVENT
+** command.
+**
+** gctUINT8 Event
+** Event ID to program.
+**
+** gceKERNEL_WHERE FromWhere
+** Location of the pipe to send the event.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the EVENT command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the EVENT command. If 'Bytes' is gcvNULL, nothing will be
+** returned.
+*/
+gceSTATUS
+gckHARDWARE_Event(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT8 Event,
+ IN gceKERNEL_WHERE FromWhere,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gctUINT size;
+ gctUINT32 destination = 0;
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Event=%u FromWhere=%d *Bytes=%lu",
+ Hardware, Logical, Event, FromWhere, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+ gcmkVERIFY_ARGUMENT(Event < 32);
+
+ /* Determine the size of the command. */
+
+ size = (Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL))
+ ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
+ : 8;
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < size)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ switch (FromWhere)
+ {
+ case gcvKERNEL_COMMAND:
+ /* From command processor. */
+ 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)));
+ break;
+
+ case gcvKERNEL_PIXEL:
+ /* From pixel engine. */
+ 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)));
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Append EVENT(Event, destiantion). */
+ 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)))
+ | ((((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)))
+ | ((((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)));
+
+ 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)));
+
+ /* Make sure the event ID gets written out before GPU can access it. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, logical + 1));
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ {
+ gctUINT32 phys;
+ gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%08x: EVENT %d", phys, Event);
+ }
+#endif
+
+ /* Append the extra states. These are needed for the chips that do not
+ ** support back-to-back events due to the async interface. The extra
+ ** states add the necessary delay to ensure that event IDs do not
+ ** collide. */
+ if (size > 8)
+ {
+ 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)))
+ | ((((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)))
+ | ((((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)));
+ logical[3] = 0;
+ logical[4] = 0;
+ logical[5] = 0;
+ logical[6] = 0;
+ logical[7] = 0;
+ }
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the EVENT command. */
+ *Bytes = size;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_PipeSelect
+**
+** Append a PIPESELECT command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** the PIPESELECT command at or gcvNULL just to query the size of the
+** PIPESELECT command.
+**
+** gcePIPE_SELECT Pipe
+** Pipe value to select.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the PIPESELECT command.
+** If 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the PIPESELECT command. If 'Bytes' is gcvNULL, nothing will be
+** returned.
+*/
+gceSTATUS
+gckHARDWARE_PipeSelect(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gcePIPE_SELECT Pipe,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Pipe=%d *Bytes=%lu",
+ Hardware, Logical, Pipe, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ /* Append a PipeSelect. */
+ if (Logical != gcvNULL)
+ {
+ gctUINT32 flush, stall;
+
+ if (*Bytes < 32)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ flush = (Pipe == gcvPIPE_2D)
+ ? ((((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)))
+ | ((((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)))
+ : ((((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)));
+
+ 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)))
+ | ((((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)));
+
+ /* LoadState(AQFlush, 1), flush. */
+ 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)))
+ | ((((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)))
+ | ((((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)));
+
+ logical[1]
+ = flush;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH 0x%x", logical, flush);
+
+ /* LoadState(AQSempahore, 1), stall. */
+ 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)))
+ | ((((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)))
+ | ((((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)));
+
+ logical[3]
+ = stall;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: SEMAPHORE 0x%x", logical + 2, stall);
+
+ /* Stall, stall. */
+ 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)));
+ logical[5] = stall;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: STALL 0x%x", logical + 4, stall);
+
+ /* LoadState(AQPipeSelect, 1), pipe. */
+ logical[6]
+ = ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ logical[7] = (Pipe == gcvPIPE_2D)
+ ? 0x1
+ : 0x0;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: PIPE %d", logical + 6, Pipe);
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the PIPESELECT command. */
+ *Bytes = 32;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Link
+**
+** Append a LINK command at the specified location in the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Pointer to the current location inside the command queue to append
+** the LINK command at or gcvNULL just to query the size of the LINK
+** command.
+**
+** gctPOINTER FetchAddress
+** Logical address of destination of LINK.
+**
+** gctSIZE_T FetchSize
+** Number of bytes in destination of LINK.
+**
+** gctSIZE_T * Bytes
+** Pointer to the number of bytes available for the LINK command. If
+** 'Logical' is gcvNULL, this argument will be ignored.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Bytes
+** Pointer to a variable that will receive the number of bytes required
+** for the LINK command. If 'Bytes' is gcvNULL, nothing will be returned.
+*/
+gceSTATUS
+gckHARDWARE_Link(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctPOINTER FetchAddress,
+ IN gctSIZE_T FetchSize,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gceSTATUS status;
+ gctSIZE_T bytes;
+ gctUINT32 address;
+ gctUINT32 link;
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x FetchAddress=0x%x FetchSize=%lu "
+ "*Bytes=%lu",
+ Hardware, Logical, FetchAddress, FetchSize,
+ gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Convert logical address to hardware address. */
+ gcmkONERROR(
+ gckHARDWARE_ConvertLogical(Hardware, FetchAddress, &address));
+
+ gcmkONERROR(
+ gckOS_WriteMemory(Hardware->os, logical + 1, address));
+
+ /* Make sure the address got written before the LINK command. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, logical + 1));
+
+ /* Compute number of 64-byte aligned bytes to fetch. */
+ bytes = gcmALIGN(address + FetchSize, 64) - address;
+
+ /* Append LINK(bytes / 8), FetchAddress. */
+ 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)))
+ | ((((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)));
+
+ gcmkONERROR(
+ gckOS_WriteMemory(Hardware->os, logical, link));
+
+ /* Memory barrier. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, logical));
+
+#if gcdLINK_QUEUE_SIZE && gcdVIRTUAL_COMMAND_BUFFER
+ if (address >= 0x80000000)
+ {
+ gckLINKQUEUE_Enqueue(&Hardware->linkQueue, address, address + bytes);
+ }
+#endif
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* Return number of bytes required by the LINK command. */
+ *Bytes = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_UpdateQueueTail
+**
+** Update the tail of the command queue.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address of the start of the command queue.
+**
+** gctUINT32 Offset
+** Offset into the command queue of the tail (last command).
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_UpdateQueueTail(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ IN gctUINT32 Offset
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x",
+ Hardware, Logical, Offset);
+
+ /* Verify the hardware. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Force a barrier. */
+ gcmkONERROR(
+ gckOS_MemoryBarrier(Hardware->os, Logical));
+
+ /* Notify gckKERNEL object of change. */
+ gcmkONERROR(
+ gckKERNEL_Notify(Hardware->kernel,
+ gcvNOTIFY_COMMAND_QUEUE,
+ gcvFALSE));
+
+ if (status == gcvSTATUS_CHIP_NOT_READY)
+ {
+ gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_ConvertLogical
+**
+** Convert a logical system address into a hardware specific address.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address to convert.
+**
+** gctUINT32* Address
+** Return hardware specific address.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_ConvertLogical(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical,
+ OUT gctUINT32 * Address
+ )
+{
+ gctUINT32 address;
+ gceSTATUS status;
+ gctUINT32 baseAddress;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+#if gcdVIRTUAL_COMMAND_BUFFER
+ status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address);
+
+ if (status == gcvSTATUS_INVALID_ADDRESS)
+#endif
+ {
+ /* Convert logical address into a physical address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
+
+ /* For old MMU, get GPU address according to baseAddress. */
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
+
+ /* Subtract base address to get a GPU address. */
+ gcmkASSERT(address >= baseAddress);
+ address -= baseAddress;
+ }
+
+ /* Return hardware specific address. */
+ *Address = (Hardware->mmuVersion == 0)
+ ? ((((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)))
+ | ((((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)))
+ : address;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Address=0x%08x", *Address);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_ConvertPhysical
+**
+** Convert a physical address into a hardware specific address.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctPHYS_ADDR Physical
+** Physical address to convert.
+**
+** gctUINT32* Address
+** Return hardware specific address.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_ConvertPhysical(
+ IN gckHARDWARE Hardware,
+ IN gctPHYS_ADDR Physical,
+ OUT gctUINT32 * Address
+ )
+{
+ gctUINT32 address;
+ gctUINT32 baseAddress;
+
+ gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x", Hardware, Physical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ address = gcmPTR2INT(Physical);
+
+ /* For old MMU, get GPU address according to baseAddress. */
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkVERIFY_OK(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
+
+ /* Subtract base address to get a GPU address. */
+ gcmkASSERT(address >= baseAddress);
+ address -= baseAddress;
+ }
+
+ /* Return hardware specific address. */
+ *Address = (Hardware->mmuVersion == 0)
+ ? ((((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)))
+ | ((((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)))
+ : address;
+
+ /* Return the status. */
+ gcmkFOOTER_ARG("*Address=0x%08x", *Address);
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Interrupt
+**
+** Process an interrupt.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gctBOOL InterruptValid
+** If gcvTRUE, this function will read the interrupt acknowledge
+** register, stores the data, and return whether or not the interrupt
+** is ours or not. If gcvFALSE, this functions will read the interrupt
+** acknowledge register and combine it with any stored value to handle
+** the event notifications.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Interrupt(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL InterruptValid
+ )
+{
+ gckEVENT eventObj;
+ gctUINT32 data;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x InterruptValid=%d", Hardware, InterruptValid);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Extract gckEVENT object. */
+ eventObj = Hardware->kernel->eventObj;
+ gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
+
+ if (InterruptValid)
+ {
+ /* Read AQIntrAcknowledge register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00010,
+ &data));
+
+ if (data == 0)
+ {
+ /* Not our interrupt. */
+ status = gcvSTATUS_NOT_OUR_INTERRUPT;
+ }
+ else
+ {
+ /* Inform gckEVENT of the interrupt. */
+ status = gckEVENT_Interrupt(eventObj, data);
+ }
+ }
+ else
+ {
+ /* Handle events. */
+ status = gckEVENT_Notify(eventObj, 0);
+ }
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryCommandBuffer
+**
+** Query the command buffer alignment and number of reserved bytes.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * Alignment
+** Pointer to a variable receiving the alignment for each command.
+**
+** gctSIZE_T * ReservedHead
+** Pointer to a variable receiving the number of reserved bytes at the
+** head of each command buffer.
+**
+** gctSIZE_T * ReservedTail
+** Pointer to a variable receiving the number of bytes reserved at the
+** tail of each command buffer.
+*/
+gceSTATUS
+gckHARDWARE_QueryCommandBuffer(
+ IN gckHARDWARE Hardware,
+ OUT gctSIZE_T * Alignment,
+ OUT gctSIZE_T * ReservedHead,
+ OUT gctSIZE_T * ReservedTail
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (Alignment != gcvNULL)
+ {
+ /* Align every 8 bytes. */
+ *Alignment = 8;
+ }
+
+ if (ReservedHead != gcvNULL)
+ {
+ /* Reserve space for SelectPipe(). */
+ *ReservedHead = 32;
+ }
+
+ if (ReservedTail != gcvNULL)
+ {
+ /* Reserve space for Link(). */
+ *ReservedTail = 8;
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu",
+ gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead),
+ gcmOPT_VALUE(ReservedTail));
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QuerySystemMemory
+**
+** Query the command buffer alignment and number of reserved bytes.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** gctSIZE_T * SystemSize
+** Pointer to a variable that receives the maximum size of the system
+** memory.
+**
+** gctUINT32 * SystemBaseAddress
+** Poinetr to a variable that receives the base address for system
+** memory.
+*/
+gceSTATUS
+gckHARDWARE_QuerySystemMemory(
+ IN gckHARDWARE Hardware,
+ OUT gctSIZE_T * SystemSize,
+ OUT gctUINT32 * SystemBaseAddress
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (SystemSize != gcvNULL)
+ {
+ /* Maximum system memory can be 2GB. */
+ *SystemSize = 1U << 31;
+ }
+
+ if (SystemBaseAddress != gcvNULL)
+ {
+ /* Set system memory base address. */
+ *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)));
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*SystemSize=%lu *SystemBaseAddress=%lu",
+ gcmOPT_VALUE(SystemSize), gcmOPT_VALUE(SystemBaseAddress));
+ return gcvSTATUS_OK;
+}
+
+#ifndef VIVANTE_NO_3D
+/*******************************************************************************
+**
+** gckHARDWARE_QueryShaderCaps
+**
+** Query the shader capabilities.
+**
+** INPUT:
+**
+** Nothing.
+**
+** OUTPUT:
+**
+** gctUINT * VertexUniforms
+** Pointer to a variable receiving the number of uniforms in the vertex
+** shader.
+**
+** gctUINT * FragmentUniforms
+** Pointer to a variable receiving the number of uniforms in the
+** fragment shader.
+**
+** gctUINT * Varyings
+** Pointer to a variable receiving the maimum number of varyings.
+*/
+gceSTATUS
+gckHARDWARE_QueryShaderCaps(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT * VertexUniforms,
+ OUT gctUINT * FragmentUniforms,
+ OUT gctUINT * Varyings
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x "
+ "FragmentUniforms=0x%x Varyings=0x%x",
+ Hardware, VertexUniforms,
+ FragmentUniforms, Varyings);
+
+ if (VertexUniforms != gcvNULL)
+ {
+ /* Return the vs shader const count. */
+ if (Hardware->identity.chipModel < gcv4000)
+ {
+ *VertexUniforms = 168;
+ }
+ else
+ {
+ *VertexUniforms = 256;
+ }
+ }
+
+ if (FragmentUniforms != gcvNULL)
+ {
+ /* Return the ps shader const count. */
+ if (Hardware->identity.chipModel < gcv4000)
+ {
+ *FragmentUniforms = 64;
+ }
+ else
+ {
+ *FragmentUniforms = 256;
+ }
+ }
+
+ if (Varyings != gcvNULL)
+ {
+ /* Return the shader varyings count. */
+ *Varyings = Hardware->identity.varyingsCount;
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+#endif
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetMMU
+**
+** Set the page table base address.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctPOINTER Logical
+** Logical address of the page table.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_SetMMU(
+ IN gckHARDWARE Hardware,
+ IN gctPOINTER Logical
+ )
+{
+ gceSTATUS status;
+ gctUINT32 address = 0;
+ gctUINT32 baseAddress;
+
+ gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ /* Convert the logical address into an hardware address. */
+ gcmkONERROR(
+ gckHARDWARE_ConvertLogical(Hardware, Logical, &address));
+
+ /* Also get the base address - we need a real physical address. */
+ gcmkONERROR(
+ gckOS_GetBaseAddress(Hardware->os, &baseAddress));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Setting page table to 0x%08X",
+ address + baseAddress);
+
+ /* Write the AQMemoryFePageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00400,
+ address + baseAddress));
+
+ /* Write the AQMemoryRaPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00410,
+ address + baseAddress));
+
+ /* Write the AQMemoryTxPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00404,
+ address + baseAddress));
+
+
+ /* Write the AQMemoryPePageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00408,
+ address + baseAddress));
+
+ /* Write the AQMemoryPezPageTable register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0040C,
+ address + baseAddress));
+
+ /* Return the status. */
+ gcmkFOOTER_NO();
+ return status;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_FlushMMU
+**
+** Flush the page table.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_FlushMMU(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gckCOMMAND command;
+ gctUINT32_PTR buffer;
+ gctSIZE_T bufferSize;
+ gctBOOL commitEntered = gcvFALSE;
+ gctPOINTER pointer = gcvNULL;
+ gctUINT32 flushSize;
+ gctUINT32 count;
+ gctUINT32 physical;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Verify the gckCOMMAND object pointer. */
+ command = Hardware->kernel->command;
+
+ /* Acquire the command queue. */
+ gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE));
+ commitEntered = gcvTRUE;
+
+ /* Flush the memory controller. */
+ if (Hardware->mmuVersion == 0)
+ {
+ gcmkONERROR(gckCOMMAND_Reserve(
+ command, 8, &pointer, &bufferSize
+ ));
+
+ buffer = (gctUINT32_PTR) pointer;
+
+ buffer[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)))
+ | ((((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)))
+ | ((((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)));
+
+ buffer[1]
+ = ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ gcmkONERROR(gckCOMMAND_Execute(command, 8));
+ }
+ else
+ {
+ flushSize = 16 * 4;
+
+ gcmkONERROR(gckCOMMAND_Reserve(
+ command, flushSize, &pointer, &bufferSize
+ ));
+
+ buffer = (gctUINT32_PTR) pointer;
+
+ count = (bufferSize - flushSize + 7) >> 3;
+
+ gcmkONERROR(gckOS_GetPhysicalAddress(command->os, buffer, &physical));
+
+ /* Flush cache. */
+ buffer[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)))
+ | ((((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)))
+ | ((((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)));
+
+ buffer[1]
+ = ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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 ? 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)))
+ | ((((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)));
+
+ /* Arm the PE-FE Semaphore. */
+ buffer[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)))
+ | ((((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)))
+ | ((((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)));
+
+ buffer[3]
+ = ((((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)))
+ | ((((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)));
+
+ /* STALL FE until PE is done flushing. */
+ buffer[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)));
+
+ buffer[5]
+ = ((((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)))
+ | ((((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)));
+
+ /* LINK to next slot to flush FE FIFO. */
+ buffer[6]
+ = ((((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)))
+ | ((((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)));
+
+ buffer[7]
+ = physical + 8 * gcmSIZEOF(gctUINT32);
+
+ /* Flush MMU cache. */
+ buffer[8]
+ = ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ buffer[9]
+ = (((((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))) );
+
+ /* Arm the PE-FE Semaphore. */
+ buffer[10]
+ = ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ buffer[11]
+ = ((((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)))
+ | ((((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)));
+
+ /* STALL FE until PE is done flushing. */
+ buffer[12]
+ = ((((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)));
+
+ buffer[13]
+ = ((((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)))
+ | ((((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)));
+
+ /* LINK to next slot to flush FE FIFO. */
+ buffer[14]
+ = ((((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)))
+ | ((((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)));
+
+ buffer[15]
+ = physical + flushSize;
+
+ gcmkONERROR(gckCOMMAND_Execute(command, flushSize));
+ }
+
+ /* Release the command queue. */
+ gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE));
+ commitEntered = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (commitEntered)
+ {
+ /* Release the command queue mutex. */
+ gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
+ gcvFALSE));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetMMUv2
+**
+** Set the page table base address.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_SetMMUv2(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Enable,
+ IN gctPOINTER MtlbAddress,
+ IN gceMMU_MODE Mode,
+ IN gctPOINTER SafeAddress,
+ IN gctBOOL FromPower
+ )
+{
+ gceSTATUS status;
+ gctUINT32 config, address;
+ gckCOMMAND command;
+ gctUINT32_PTR buffer;
+ gctSIZE_T bufferSize;
+ gctBOOL commitEntered = gcvFALSE;
+ gctPOINTER pointer = gcvNULL;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Convert logical address into physical address. */
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &config));
+
+ gcmkONERROR(
+ gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &address));
+
+ if (address & 0x3F)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ switch (Mode)
+ {
+ case gcvMMU_MODE_1K:
+ if (config & 0x3FF)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ 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)));
+
+ break;
+
+ case gcvMMU_MODE_4K:
+ if (config & 0xFFF)
+ {
+ gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+ }
+
+ 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)));
+
+ break;
+
+ default:
+ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+ }
+
+ /* Verify the gckCOMMAND object pointer. */
+ command = Hardware->kernel->command;
+
+ /* Acquire the command queue. */
+ gcmkONERROR(gckCOMMAND_EnterCommit(command, FromPower));
+ commitEntered = gcvTRUE;
+
+ gcmkONERROR(gckCOMMAND_Reserve(
+ command, 16, &pointer, &bufferSize
+ ));
+
+ buffer = pointer;
+
+ buffer[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)))
+ | ((((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)))
+ | ((((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)));
+
+ buffer[1] = config;
+
+ buffer[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)))
+ | ((((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)))
+ | ((((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)));
+
+ buffer[3] = address;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address);
+
+ gcmkONERROR(gckCOMMAND_Execute(command, 16));
+
+ if (FromPower == gcvFALSE)
+ {
+ /* Acquire global semaphore to suspend power management until MMU
+ ** is enabled. And acquired it before gckCOMMAND_ExitCommit to
+ ** make sure GPU keeps ON. */
+ gcmkONERROR(
+ gckOS_AcquireSemaphore(Hardware->os, Hardware->globalSemaphore));
+
+ acquired = gcvTRUE;
+ }
+
+ /* Release the command queue. */
+ gcmkONERROR(gckCOMMAND_ExitCommit(command, FromPower));
+ commitEntered = gcvFALSE;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "call gckCOMMAND_Stall to make sure the config is done.\n ");
+
+ gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Enable MMU through GCREG_MMU_CONTROL.");
+
+ /* Enable MMU. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0018C,
+ ((((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)))));
+
+ if (FromPower == gcvFALSE)
+ {
+ /* Relase global semaphore. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
+
+ acquired = gcvFALSE;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "call gckCOMMAND_Stall to check MMU available.\n");
+
+ gcmkONERROR(gckCOMMAND_Stall(command, FromPower));
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "The MMU is available.\n");
+
+ /* Return the status. */
+ gcmkFOOTER_NO();
+ return status;
+
+OnError:
+ if (commitEntered)
+ {
+ /* Release the command queue mutex. */
+ gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command,
+ FromPower));
+ }
+
+ if (acquired)
+ {
+ gcmkVERIFY_OK(
+ gckOS_ReleaseSemaphore(Hardware->os, Hardware->globalSemaphore));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_BuildVirtualAddress
+**
+** Build a virtual address.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gctUINT32 Index
+** Index into page table.
+**
+** gctUINT32 Offset
+** Offset into page.
+**
+** OUTPUT:
+**
+** gctUINT32 * Address
+** Pointer to a variable receiving te hardware address.
+*/
+gceSTATUS
+gckHARDWARE_BuildVirtualAddress(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Index,
+ IN gctUINT32 Offset,
+ OUT gctUINT32 * Address
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x Index=%u Offset=%u", Hardware, Index, Offset);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+ /* Build virtual address. */
+ *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)))
+ | ((((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)));
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Address=0x%08x", *Address);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_GetIdle(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Wait,
+ OUT gctUINT32 * Data
+ )
+{
+ gceSTATUS status;
+ gctUINT32 idle = 0;
+ gctINT retry, poll, pollCount;
+
+ gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(Data != gcvNULL);
+
+
+ /* If we have to wait, try 100 polls per millisecond. */
+ pollCount = Wait ? 100 : 1;
+
+ /* At most, try for 1 second. */
+ for (retry = 0; retry < 1000; ++retry)
+ {
+ /* If we have to wait, try 100 polls per millisecond. */
+ for (poll = pollCount; poll > 0; --poll)
+ {
+ /* Read register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
+
+ /* See if we have to wait for FE idle. */
+ if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ))
+ {
+ /* FE is idle. */
+ break;
+ }
+ }
+
+ /* Check if we need to wait for FE and FE is busy. */
+ 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)))))) ))
+ {
+ /* Wait a little. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "%s: Waiting for idle: 0x%08X",
+ __FUNCTION__, idle);
+
+ gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ /* Return idle to caller. */
+ *Data = idle;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Data=0x%08x", *Data);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/* Flush the caches. */
+gceSTATUS
+gckHARDWARE_Flush(
+ IN gckHARDWARE Hardware,
+ IN gceKERNEL_FLUSH Flush,
+ IN gctPOINTER Logical,
+ IN OUT gctSIZE_T * Bytes
+ )
+{
+ gctUINT32 pipe;
+ gctUINT32 flush = 0;
+ gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
+ Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Get current pipe. */
+ pipe = Hardware->kernel->command->pipeSelect;
+
+ /* Flush 3D color cache. */
+ if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0))
+ {
+ 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)));
+ }
+
+ /* Flush 3D depth cache. */
+ if ((Flush & gcvFLUSH_DEPTH) && (pipe == 0x0))
+ {
+ 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)));
+ }
+
+ /* Flush 3D texture cache. */
+ if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0))
+ {
+ 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)));
+ }
+
+ /* Flush 2D cache. */
+ if ((Flush & gcvFLUSH_2D) && (pipe == 0x1))
+ {
+ 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)));
+ }
+
+ /* See if there is a valid flush. */
+ if (flush == 0)
+ {
+ if (Bytes != gcvNULL)
+ {
+ /* No bytes required. */
+ *Bytes = 0;
+ }
+ }
+
+ else
+ {
+ /* Copy to command queue. */
+ if (Logical != gcvNULL)
+ {
+ if (*Bytes < 8)
+ {
+ /* Command queue too small. */
+ gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+ }
+
+ /* Append LOAD_STATE to AQFlush. */
+ 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)))
+ | ((((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)))
+ | ((((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)));
+
+ logical[1] = flush;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "0x%x: FLUSH 0x%x", logical, flush);
+ }
+
+ if (Bytes != gcvNULL)
+ {
+ /* 8 bytes required. */
+ *Bytes = 8;
+ }
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_SetFastClear(
+ IN gckHARDWARE Hardware,
+ IN gctINT Enable,
+ IN gctINT Compression
+ )
+{
+#ifndef VIVANTE_NO_3D
+ gctUINT32 debug;
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x Enable=%d Compression=%d",
+ Hardware, Enable, Compression);
+
+ /* Only process if fast clear is available. */
+ 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)))))) ))
+ {
+ if (Enable == -1)
+ {
+ /* Determine automatic value for fast clear. */
+ Enable = ((Hardware->identity.chipModel != gcv500)
+ || (Hardware->identity.chipRevision >= 3)
+ ) ? 1 : 0;
+ }
+
+ if (Compression == -1)
+ {
+ /* Determine automatic value for compression. */
+ Compression = Enable
+ & (((((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)))))) );
+ }
+
+ /* Read AQMemoryDebug register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &debug));
+
+ /* Set fast clear bypass. */
+ 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)));
+
+ if (
+ ((((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))))))) ||
+ (Hardware->identity.chipModel >= gcv4000))
+ {
+ /* Set compression bypass. */
+ 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)));
+ }
+
+ /* Write back AQMemoryDebug register. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00414,
+ debug));
+
+ /* Store fast clear and comprersison flags. */
+ Hardware->allowFastClear = Enable;
+ Hardware->allowCompression = Compression;
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "FastClear=%d Compression=%d", Enable, Compression);
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+#else
+ return gcvSTATUS_OK;
+#endif
+}
+
+typedef enum
+{
+ gcvPOWER_FLAG_INITIALIZE = 1 << 0,
+ gcvPOWER_FLAG_STALL = 1 << 1,
+ gcvPOWER_FLAG_STOP = 1 << 2,
+ gcvPOWER_FLAG_START = 1 << 3,
+ gcvPOWER_FLAG_RELEASE = 1 << 4,
+ gcvPOWER_FLAG_DELAY = 1 << 5,
+ gcvPOWER_FLAG_SAVE = 1 << 6,
+ gcvPOWER_FLAG_ACQUIRE = 1 << 7,
+ gcvPOWER_FLAG_POWER_OFF = 1 << 8,
+ gcvPOWER_FLAG_CLOCK_OFF = 1 << 9,
+ gcvPOWER_FLAG_CLOCK_ON = 1 << 10,
+}
+gcePOWER_FLAGS;
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE) && gcdPOWER_MANAGEMENT
+static gctCONST_STRING
+_PowerEnum(gceCHIPPOWERSTATE State)
+{
+ const gctCONST_STRING states[] =
+ {
+ gcmSTRING(gcvPOWER_ON),
+ gcmSTRING(gcvPOWER_OFF),
+ gcmSTRING(gcvPOWER_IDLE),
+ gcmSTRING(gcvPOWER_SUSPEND),
+ gcmSTRING(gcvPOWER_SUSPEND_ATPOWERON),
+ gcmSTRING(gcvPOWER_OFF_ATPOWERON),
+ gcmSTRING(gcvPOWER_IDLE_BROADCAST),
+ gcmSTRING(gcvPOWER_SUSPEND_BROADCAST),
+ gcmSTRING(gcvPOWER_OFF_BROADCAST),
+ gcmSTRING(gcvPOWER_OFF_RECOVERY),
+ gcmSTRING(gcvPOWER_ON_AUTO)
+ };
+
+ if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO))
+ {
+ return states[State - gcvPOWER_ON];
+ }
+
+ return "unknown";
+}
+#endif
+
+/*******************************************************************************
+**
+** gckHARDWARE_SetPowerManagementState
+**
+** Set GPU to a specified power state.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gceCHIPPOWERSTATE State
+** Power State.
+**
+*/
+gceSTATUS
+gckHARDWARE_SetPowerManagementState(
+ IN gckHARDWARE Hardware,
+ IN gceCHIPPOWERSTATE State
+ )
+{
+#if gcdPOWER_MANAGEMENT
+ gceSTATUS status;
+ gckCOMMAND command = gcvNULL;
+ gckOS os;
+ gctUINT flag, clock;
+ gctPOINTER buffer;
+ gctSIZE_T bytes, requested;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL mutexAcquired = gcvFALSE;
+ gctBOOL stall = gcvTRUE;
+ gctBOOL broadcast = gcvFALSE;
+#if gcdPOWEROFF_TIMEOUT
+ gctBOOL timeout = gcvFALSE;
+ gctBOOL isAfter = gcvFALSE;
+ gctUINT32 currentTime;
+#endif
+ gctUINT32 process, thread;
+ gctBOOL commitEntered = gcvFALSE;
+ gctBOOL commandStarted = gcvFALSE;
+ gctBOOL isrStarted = gcvFALSE;
+
+#if gcdENABLE_PROFILING
+ gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
+ initTime, offTime, startTime, totalTime;
+#endif
+ gctBOOL global = gcvFALSE;
+ gctBOOL globalAcquired = gcvFALSE;
+ gctBOOL configMmu = gcvFALSE;
+
+ /* State transition flags. */
+ static const gctUINT flags[4][4] =
+ {
+ /* gcvPOWER_ON */
+ { /* ON */ 0,
+ /* OFF */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STALL |
+ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STALL,
+ /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE |
+ gcvPOWER_FLAG_STALL |
+ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_OFF */
+ { /* ON */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_RELEASE |
+ gcvPOWER_FLAG_DELAY,
+ /* OFF */ 0,
+ /* IDLE */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_DELAY,
+ /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_IDLE */
+ { /* ON */ gcvPOWER_FLAG_RELEASE,
+ /* OFF */ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ 0,
+ /* SUSPEND */ gcvPOWER_FLAG_STOP |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ },
+
+ /* gcvPOWER_SUSPEND */
+ { /* ON */ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_RELEASE |
+ gcvPOWER_FLAG_DELAY |
+ gcvPOWER_FLAG_CLOCK_ON,
+ /* OFF */ gcvPOWER_FLAG_SAVE |
+ gcvPOWER_FLAG_POWER_OFF |
+ gcvPOWER_FLAG_CLOCK_OFF,
+ /* IDLE */ gcvPOWER_FLAG_START |
+ gcvPOWER_FLAG_DELAY |
+ gcvPOWER_FLAG_CLOCK_ON,
+ /* SUSPEND */ 0,
+ },
+ };
+
+ /* Clocks. */
+ static const gctUINT clocks[4] =
+ {
+ /* gcvPOWER_ON */
+ ((((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))) |
+ ((((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))) |
+ ((((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))) |
+ ((((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))),
+
+ /* gcvPOWER_OFF */
+ ((((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))) |
+ ((((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))) |
+ ((((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))) |
+ ((((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))),
+
+ /* gcvPOWER_IDLE */
+ ((((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))) |
+ ((((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))) |
+ ((((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))) |
+ ((((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))),
+
+ /* gcvPOWER_SUSPEND */
+ ((((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))) |
+ ((((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))) |
+ ((((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))) |
+ ((((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))),
+ };
+
+ gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State);
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Switching to power state %d(%s)",
+ State, _PowerEnum(State));
+#endif
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Get the gckOS object pointer. */
+ os = Hardware->os;
+ gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+ /* Get the gckCOMMAND object pointer. */
+ gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
+ command = Hardware->kernel->command;
+ gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
+
+ /* Start profiler. */
+ gcmkPROFILE_INIT(freq, time);
+
+ /* Convert the broadcast power state. */
+ switch (State)
+ {
+ case gcvPOWER_SUSPEND_ATPOWERON:
+ /* Convert to SUSPEND and don't wait for STALL. */
+ State = gcvPOWER_SUSPEND;
+ stall = gcvFALSE;
+ break;
+
+ case gcvPOWER_OFF_ATPOWERON:
+ /* Convert to OFF and don't wait for STALL. */
+ State = gcvPOWER_OFF;
+ stall = gcvFALSE;
+ break;
+
+ case gcvPOWER_IDLE_BROADCAST:
+ /* Convert to IDLE and note we are inside broadcast. */
+ State = gcvPOWER_IDLE;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_SUSPEND_BROADCAST:
+ /* Convert to SUSPEND and note we are inside broadcast. */
+ State = gcvPOWER_SUSPEND;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_OFF_BROADCAST:
+ /* Convert to OFF and note we are inside broadcast. */
+ State = gcvPOWER_OFF;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_OFF_RECOVERY:
+ /* Convert to OFF and note we are inside recovery. */
+ State = gcvPOWER_OFF;
+ stall = gcvFALSE;
+ broadcast = gcvTRUE;
+ break;
+
+ case gcvPOWER_ON_AUTO:
+ /* Convert to ON and note we are inside recovery. */
+ State = gcvPOWER_ON;
+ break;
+
+ case gcvPOWER_ON:
+ case gcvPOWER_IDLE:
+ case gcvPOWER_SUSPEND:
+ case gcvPOWER_OFF:
+ /* Mark as global power management. */
+ global = gcvTRUE;
+ break;
+
+#if gcdPOWEROFF_TIMEOUT
+ case gcvPOWER_OFF_TIMEOUT:
+ /* Convert to OFF and note we are inside broadcast. */
+ State = gcvPOWER_OFF;
+ broadcast = gcvTRUE;
+ /* Check time out */
+ timeout = gcvTRUE;
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ /* Get current process and thread IDs. */
+ gcmkONERROR(gckOS_GetProcessID(&process));
+ gcmkONERROR(gckOS_GetThreadID(&thread));
+
+ if (broadcast)
+ {
+ /* Try to acquire the power mutex. */
+ status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
+
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ /* Check if we already own this mutex. */
+ if ((Hardware->powerProcess == process)
+ && (Hardware->powerThread == thread)
+ )
+ {
+ /* Bail out on recursive power management. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ else if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
+ {
+ /* Called from IST,
+ ** so waiting here will cause deadlock,
+ ** if lock holder call gckCOMMAND_Stall() */
+ gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
+ }
+ else
+ {
+ /* Acquire the power mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os,
+ Hardware->powerMutex,
+ gcvINFINITE));
+ }
+ }
+ }
+ else
+ {
+ /* Acquire the power mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
+ }
+
+ /* Get time until mtuex acquired. */
+ gcmkPROFILE_QUERY(time, mutexTime);
+
+ Hardware->powerProcess = process;
+ Hardware->powerThread = thread;
+ mutexAcquired = gcvTRUE;
+
+ /* Grab control flags and clock. */
+ flag = flags[Hardware->chipPowerState][State];
+ clock = clocks[State];
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ if (State == gcvPOWER_ON)
+ {
+ 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)));
+ }
+#endif
+
+ if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
+ {
+#if gcdPOWER_SUSNPEND_WHEN_IDLE
+ /* Do nothing */
+
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+#else
+ /* Clock should be on when switch power from off to suspend */
+ 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))) |
+ ((((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))) |
+ ((((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))) |
+ ((((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))) ;
+#endif
+ }
+
+#if gcdPOWEROFF_TIMEOUT
+ if (timeout)
+ {
+ gcmkONERROR(gckOS_GetTicks(&currentTime));
+
+ gcmkONERROR(
+ gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
+
+ /* powerOffTime is pushed forward, give up.*/
+ if (isAfter
+ /* Expect a transition start from IDLE or SUSPEND. */
+ || (Hardware->chipPowerState == gcvPOWER_ON)
+ || (Hardware->chipPowerState == gcvPOWER_OFF)
+ )
+ {
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* No need to do anything. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Power Off GPU[%d] at %u [supposed to be at %u]",
+ Hardware->core, currentTime, Hardware->powerOffTime);
+ }
+#endif
+
+ if (flag == 0)
+ {
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* No need to do anything. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+
+ /* If this is an internal power management, we have to check if we can grab
+ ** the global power semaphore. If we cannot, we have to wait until the
+ ** external world changes power management. */
+ if (!global)
+ {
+ /* Try to acquire the global semaphore. */
+ status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
+ {
+ /* Called from thread routine which should NEVER sleep.*/
+ gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
+ }
+
+ /* Release the power mutex. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Releasing the power mutex.");
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+ mutexAcquired = gcvFALSE;
+
+ /* Wait for the semaphore. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Waiting for global semaphore.");
+ gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvTRUE;
+
+ /* Acquire the power mutex. */
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "Reacquiring the power mutex.");
+ gcmkONERROR(gckOS_AcquireMutex(os,
+ Hardware->powerMutex,
+ gcvINFINITE));
+ mutexAcquired = gcvTRUE;
+
+ /* chipPowerState may be changed by external world during the time
+ ** we give up powerMutex, so updating flag now is necessary. */
+ flag = flags[Hardware->chipPowerState][State];
+
+ if (flag == 0)
+ {
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvFALSE;
+
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+ mutexAcquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ }
+ else
+ {
+ /* Error. */
+ gcmkONERROR(status);
+ }
+
+ /* Release the global semaphore again. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvFALSE;
+ }
+ else
+ {
+ if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
+ {
+ /* Acquire the global semaphore if it has not been acquired. */
+ status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+ if (status == gcvSTATUS_OK)
+ {
+ globalAcquired = gcvTRUE;
+ }
+ else if (status != gcvSTATUS_TIMEOUT)
+ {
+ /* Other errors. */
+ gcmkONERROR(status);
+ }
+ /* Ignore gcvSTATUS_TIMEOUT and leave globalAcquired as gcvFALSE.
+ ** gcvSTATUS_TIMEOUT means global semaphore has already
+ ** been acquired before this operation, so even if we fail,
+ ** we should not release it in our error handling. It should be
+ ** released by the next successful global gcvPOWER_ON. */
+ }
+
+ /* Global power management can't be aborted, so sync with
+ ** proceeding last commit. */
+ if (flag & gcvPOWER_FLAG_ACQUIRE)
+ {
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+ acquired = gcvTRUE;
+
+ /* avoid acquiring again. */
+ flag &= ~gcvPOWER_FLAG_ACQUIRE;
+ }
+ }
+
+ if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
+ {
+ /* Turn on the power. */
+ gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
+
+ /* Mark clock and power as enabled. */
+ Hardware->clockState = gcvTRUE;
+ Hardware->powerState = gcvTRUE;
+
+ for (;;)
+ {
+ /* Check if GPU is present and awake. */
+ status = _IsGPUPresent(Hardware);
+
+ /* Check if the GPU is not responding. */
+ if (status == gcvSTATUS_GPU_NOT_RESPONDING)
+ {
+ /* Turn off the power and clock. */
+ gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvFALSE, gcvFALSE));
+
+ Hardware->clockState = gcvFALSE;
+ Hardware->powerState = gcvFALSE;
+
+ /* Wait a little. */
+ gckOS_Delay(os, 1);
+
+ /* Turn on the power and clock. */
+ gcmkONERROR(gckOS_SetGPUPower(os, Hardware->core, gcvTRUE, gcvTRUE));
+
+ Hardware->clockState = gcvTRUE;
+ Hardware->powerState = gcvTRUE;
+
+ /* We need to initialize the hardware and start the command
+ * processor. */
+ flag |= gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_START;
+ }
+ else
+ {
+ /* Test for error. */
+ gcmkONERROR(status);
+
+ /* Break out of loop. */
+ break;
+ }
+ }
+ }
+
+ /* Get time until powered on. */
+ gcmkPROFILE_QUERY(time, onTime);
+
+ if ((flag & gcvPOWER_FLAG_STALL) && stall)
+ {
+ gctBOOL idle;
+ gctINT32 atomValue;
+
+ /* For global operation, all pending commits have already been
+ ** blocked by globalSemaphore or powerSemaphore.*/
+ if (!global)
+ {
+ /* Check commit atom. */
+ gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
+
+ if (atomValue > 0)
+ {
+ /* Commits are pending - abort power management. */
+ status = broadcast ? gcvSTATUS_CHIP_NOT_READY
+ : gcvSTATUS_MORE_DATA;
+ goto OnError;
+ }
+ }
+
+ if (broadcast)
+ {
+ /* Check for idle. */
+ gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
+
+ if (!idle)
+ {
+ status = gcvSTATUS_CHIP_NOT_READY;
+ goto OnError;
+ }
+ }
+
+ else
+ {
+ /* Acquire the command queue. */
+ gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvTRUE));
+ commitEntered = gcvTRUE;
+
+ /* Get the size of the flush command. */
+ gcmkONERROR(gckHARDWARE_Flush(Hardware,
+ gcvFLUSH_ALL,
+ gcvNULL,
+ &requested));
+
+ /* Reserve space in the command queue. */
+ gcmkONERROR(gckCOMMAND_Reserve(command,
+ requested,
+ &buffer,
+ &bytes));
+
+ /* Append a flush. */
+ gcmkONERROR(gckHARDWARE_Flush(
+ Hardware, gcvFLUSH_ALL, buffer, &bytes
+ ));
+
+ /* Execute the command queue. */
+ gcmkONERROR(gckCOMMAND_Execute(command, requested));
+
+ /* Release the command queue. */
+ gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvTRUE));
+ commitEntered = gcvFALSE;
+
+ /* Wait to finish all commands. */
+ gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
+ }
+ }
+
+ /* Get time until stalled. */
+ gcmkPROFILE_QUERY(time, stallTime);
+
+ if (flag & gcvPOWER_FLAG_ACQUIRE)
+ {
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+ acquired = gcvTRUE;
+ }
+
+ if (flag & gcvPOWER_FLAG_STOP)
+ {
+ /* Stop the command parser. */
+ gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
+
+ /* Stop the Isr. */
+ if (Hardware->stopIsr)
+ {
+ gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
+ }
+ }
+
+ /* Get time until stopped. */
+ gcmkPROFILE_QUERY(time, stopTime);
+
+ /* Only process this when hardware is enabled. */
+ if (Hardware->clockState && Hardware->powerState
+ /* Don't touch clock control if dynamic frequency scaling is available. */
+ && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE
+ )
+ {
+ if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
+ {
+ if (Hardware->identity.chipModel == gcv4000
+ && Hardware->identity.chipRevision == 0x5208)
+ {
+ clock &= ~2U;
+ }
+ }
+
+ /* Write the clock control register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(os,
+ Hardware->core,
+ 0x00000,
+ clock));
+
+ /* Done loading the frequency scaler. */
+ gcmkONERROR(gckOS_WriteRegisterEx(os,
+ Hardware->core,
+ 0x00000,
+ ((((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)))));
+ }
+
+ if (flag & gcvPOWER_FLAG_DELAY)
+ {
+ /* Wait for the specified amount of time to settle coming back from
+ ** power-off or suspend state. */
+ gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
+ }
+
+ /* Get time until delayed. */
+ gcmkPROFILE_QUERY(time, delayTime);
+
+ if (flag & gcvPOWER_FLAG_INITIALIZE)
+ {
+ /* Initialize hardware. */
+ gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
+
+ gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
+ Hardware->allowFastClear,
+ Hardware->allowCompression));
+
+ /* Force the command queue to reload the next context. */
+ command->currContext = gcvNULL;
+
+ /* Need to config mmu after command start. */
+ configMmu = gcvTRUE;
+ }
+
+ /* Get time until initialized. */
+ gcmkPROFILE_QUERY(time, initTime);
+
+ if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
+ {
+ /* Turn off the GPU power. */
+ gcmkONERROR(
+ gckOS_SetGPUPower(os,
+ Hardware->core,
+ (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
+ : gcvTRUE,
+ (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
+ : gcvTRUE));
+
+ /* Save current hardware power and clock states. */
+ Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE
+ : gcvTRUE;
+ Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE
+ : gcvTRUE;
+ }
+
+ /* Get time until off. */
+ gcmkPROFILE_QUERY(time, offTime);
+
+ if (flag & gcvPOWER_FLAG_START)
+ {
+ /* Start the command processor. */
+ gcmkONERROR(gckCOMMAND_Start(command));
+ commandStarted = gcvTRUE;
+
+ if (Hardware->startIsr)
+ {
+ /* Start the Isr. */
+ gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
+ isrStarted = gcvTRUE;
+ }
+
+ /* Set NEW MMU. */
+ if (Hardware->mmuVersion != 0 && configMmu)
+ {
+ gcmkONERROR(
+ gckHARDWARE_SetMMUv2(
+ Hardware,
+ gcvTRUE,
+ Hardware->kernel->mmu->mtlbLogical,
+ gcvMMU_MODE_4K,
+ (gctUINT8_PTR)Hardware->kernel->mmu->mtlbLogical + gcdMMU_MTLB_SIZE,
+ gcvTRUE
+ ));
+ }
+ }
+
+ /* Get time until started. */
+ gcmkPROFILE_QUERY(time, startTime);
+
+ if (flag & gcvPOWER_FLAG_RELEASE)
+ {
+ /* Release the power management semaphore. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore));
+ acquired = gcvFALSE;
+
+ if (global)
+ {
+ /* Verify global semaphore has been acquired already before
+ ** we release it.
+ ** If it was acquired, gckOS_TryAcquireSemaphore will return
+ ** gcvSTATUS_TIMEOUT and we release it. Otherwise, global
+ ** semaphore will be acquried now, but it still is released
+ ** immediately. */
+ status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+ if (status != gcvSTATUS_TIMEOUT)
+ {
+ gcmkONERROR(status);
+ }
+
+ /* Release the global semaphore. */
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvFALSE;
+ }
+ }
+
+ /* Save the new power state. */
+ Hardware->chipPowerState = State;
+
+#if gcdPOWEROFF_TIMEOUT
+ /* Reset power off time */
+ gcmkONERROR(gckOS_GetTicks(&currentTime));
+
+ Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
+
+ if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
+ {
+ /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
+ gcmkVERIFY_OK(gckOS_StartTimer(os,
+ Hardware->powerOffTimer,
+ Hardware->powerOffTimeout));
+ }
+ else
+ {
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
+
+ /* Cancel running timer when GPU enters ON or OFF. */
+ gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
+ }
+#endif
+
+ /* Release the power mutex. */
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+
+ /* Get total time. */
+ gcmkPROFILE_QUERY(time, totalTime);
+#if gcdENABLE_PROFILING
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu",
+ freq, mutexTime, onTime, stallTime, stopTime);
+ gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+ " delay:%llu init:%llu off:%llu start:%llu total:%llu",
+ delayTime, initTime, offTime, startTime, totalTime);
+#endif
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (commandStarted)
+ {
+ gcmkVERIFY_OK(gckCOMMAND_Stop(command, gcvFALSE));
+ }
+
+ if (isrStarted)
+ {
+ gcmkVERIFY_OK(Hardware->stopIsr(Hardware->isrContext));
+ }
+
+ if (commitEntered)
+ {
+ /* Release the command queue mutex. */
+ gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvTRUE));
+ }
+
+ if (acquired)
+ {
+ /* Release semaphore. */
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
+ command->powerSemaphore));
+ }
+
+ if (globalAcquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os,
+ Hardware->globalSemaphore));
+ }
+
+ if (mutexAcquired)
+ {
+ gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ }
+
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+#else /* gcdPOWER_MANAGEMENT */
+ /* Do nothing */
+ return gcvSTATUS_OK;
+#endif
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_QueryPowerManagementState
+**
+** Get GPU power state.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** gceCHIPPOWERSTATE* State
+** Power State.
+**
+*/
+gceSTATUS
+gckHARDWARE_QueryPowerManagementState(
+ IN gckHARDWARE Hardware,
+ OUT gceCHIPPOWERSTATE* State
+ )
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(State != gcvNULL);
+
+ /* Return the statue. */
+ *State = Hardware->chipPowerState;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*State=%d", *State);
+ return gcvSTATUS_OK;
+}
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+gceSTATUS
+gckHARDWARE_SetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 FscaleValue
+ )
+{
+ gceSTATUS status;
+ gctUINT32 clock;
+ gctBOOL acquired = gcvFALSE;
+
+ gcmkHEADER_ARG("Hardware=0x%x FscaleValue=%d", Hardware, FscaleValue);
+
+ gcmkVERIFY_ARGUMENT(FscaleValue > 0 && FscaleValue <= 64);
+
+ gcmkONERROR(
+ gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
+ Hardware->powerOnFscaleVal = FscaleValue;
+
+ if (Hardware->chipPowerState == gcvPOWER_ON)
+ {
+ gctUINT32 data;
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ &data));
+
+ /* Disable all clock gating. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))));
+
+ 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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ clock));
+
+ /* Done loading the frequency scaler. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((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)))));
+
+ /* Restore all clock gating. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ Hardware->powerBaseAddress
+ + 0x00104,
+ data));
+ }
+
+ gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ gcmkVERIFY(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ }
+
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_GetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT * FscaleValue,
+ IN gctUINT * MinFscaleValue,
+ IN gctUINT * MaxFscaleValue
+ )
+{
+ *FscaleValue = Hardware->powerOnFscaleVal;
+ if ((gpu3DMinClock > 0) && (gpu3DMinClock <= 64) && (Hardware->core == gcvCORE_MAJOR))
+ *MinFscaleValue = gpu3DMinClock;
+ else
+ *MinFscaleValue = 1;
+ *MaxFscaleValue = 64;
+
+ return gcvSTATUS_OK;
+}
+
+#endif
+
+#if gcdPOWEROFF_TIMEOUT
+gceSTATUS
+gckHARDWARE_SetPowerOffTimeout(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 Timeout
+)
+{
+ gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout);
+
+ Hardware->powerOffTimeout = Timeout;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+}
+
+
+gceSTATUS
+gckHARDWARE_QueryPowerOffTimeout(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32* Timeout
+)
+{
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ *Timeout = Hardware->powerOffTimeout;
+
+ gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
+ return gcvSTATUS_OK;
+}
+#endif
+
+gceSTATUS
+gckHARDWARE_QueryIdle(
+ IN gckHARDWARE Hardware,
+ OUT gctBOOL_PTR IsIdle
+ )
+{
+ gceSTATUS status;
+ gctUINT32 idle, address;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL);
+
+ /* We are idle when the power is not ON. */
+ if (Hardware->chipPowerState != gcvPOWER_ON)
+ {
+ *IsIdle = gcvTRUE;
+ }
+
+ else
+ {
+ /* Read idle register. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle));
+
+ /* Pipe must be idle. */
+ 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)
+ || ((((((gctUINT32) (idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) != 1)
+ || ((((((gctUINT32) (idle)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) != 1)
+ )
+ {
+ /* Something is busy. */
+ *IsIdle = gcvFALSE;
+ }
+
+ else
+ {
+ /* Read the current FE address. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00664,
+ &address));
+
+ /* Test if address is inside the last WAIT/LINK sequence. */
+ if ((address >= Hardware->lastWaitLink)
+ && (address <= Hardware->lastWaitLink + 16)
+ )
+ {
+ /* FE is in last WAIT/LINK and the pipe is idle. */
+ *IsIdle = gcvTRUE;
+ }
+ else
+ {
+ /* FE is not in WAIT/LINK yet. */
+ *IsIdle = gcvFALSE;
+ }
+ }
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+/*******************************************************************************
+** Handy macros that will help in reading those debug registers.
+*/
+
+#define gcmkREAD_DEBUG_REGISTER(control, block, index, data) \
+ gcmkONERROR(\
+ gckOS_WriteRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_CONTROL##control##_Address, \
+ gcmSETFIELD(0, \
+ GC_DEBUG_CONTROL##control, \
+ block, \
+ index))); \
+ gcmkONERROR(\
+ gckOS_ReadRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_SIGNALS_##block##_Address, \
+ &profiler->data))
+
+#define gcmkRESET_DEBUG_REGISTER(control, block) \
+ gcmkONERROR(\
+ gckOS_WriteRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_CONTROL##control##_Address, \
+ gcmSETFIELD(0, \
+ GC_DEBUG_CONTROL##control, \
+ block, \
+ 15))); \
+ gcmkONERROR(\
+ gckOS_WriteRegisterEx(Hardware->os, \
+ Hardware->core, \
+ GC_DEBUG_CONTROL##control##_Address, \
+ gcmSETFIELD(0, \
+ GC_DEBUG_CONTROL##control, \
+ block, \
+ 0)))
+
+/*******************************************************************************
+**
+** gckHARDWARE_ProfileEngine2D
+**
+** Read the profile registers available in the 2D engine and sets them in the
+** profile. The function will also reset the pixelsRendered counter every time.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** OPTIONAL gcs2D_PROFILE_PTR Profile
+** Pointer to a gcs2D_Profile structure.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_ProfileEngine2D(
+ IN gckHARDWARE Hardware,
+ OPTIONAL gcs2D_PROFILE_PTR Profile
+ )
+{
+ gceSTATUS status;
+ gcs2D_PROFILE_PTR profiler = Profile;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (Profile != gcvNULL)
+ {
+ /* Read the cycle count. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00438,
+ &Profile->cycleCount));
+
+ /* Read pixels rendered by 2D engine. */
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pixelsRendered));
+
+ /* Reset counter. */
+ 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))) ));
+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)))
+));
+ }
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+#if VIVANTE_PROFILER
+gceSTATUS
+gckHARDWARE_QueryProfileRegisters(
+ IN gckHARDWARE Hardware,
+ IN gctBOOL Reset,
+ OUT gcsPROFILER_COUNTERS * Counters
+ )
+{
+ gceSTATUS status;
+ gcsPROFILER_COUNTERS * profiler = Counters;
+
+ gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Read the counters. */
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00040,
+ &profiler->gpuTotalRead64BytesPerFrame));
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00044,
+ &profiler->gpuTotalWrite64BytesPerFrame));
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00438,
+ &profiler->gpuCyclesCounter));
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00078,
+ &profiler->gpuTotalCyclesCounter));
+
+ gcmkONERROR(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0007C,
+ &profiler->gpuIdleCyclesCounter));
+
+ if(Reset){
+
+ /* Reset counters. */
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0));
+ gcmkONERROR(
+ gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00078, 0));
+ }
+ /* PE */
+ 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, &profiler->pe_pixel_count_killed_by_color_pipe));
+ 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, &profiler->pe_pixel_count_killed_by_depth_pipe));
+ 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, &profiler->pe_pixel_count_drawn_by_color_pipe));
+ 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, &profiler->pe_pixel_count_drawn_by_depth_pipe));
+ if(Reset){ 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))) ));
+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)))
+)); }
+
+ /* SH */
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter));
+ 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))) ));
+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)))
+));}
+
+ /* PA */
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter));
+ 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))) ));
+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)))
+));}
+
+ /* SE */
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count));
+ 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))) ));
+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)))
+));}
+
+ /* RA */
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter));
+ 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))) ));
+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)))
+));}
+
+ /* TX */
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count));
+ 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))) ));
+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)))
+));}
+
+ /* MC */
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline));
+ 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))) ));
+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)))
+));}
+
+ /* HI */
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled));
+ 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))) ));
+gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled));
+ 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))) ));
+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)))
+));}
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
+static gceSTATUS
+_ResetGPU(
+ IN gckHARDWARE Hardware,
+ IN gckOS Os,
+ IN gceCORE Core
+ )
+{
+ gctUINT32 control, idle;
+ gceSTATUS status;
+
+ for (;;)
+ {
+ /* Disable clock gating. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ Hardware->powerBaseAddress +
+ 0x00104,
+ 0x00000000));
+
+ 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)));
+
+ /* Disable pulse-eater. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0010C,
+ control));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0010C,
+ ((((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)))));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x0010C,
+ control));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ ((((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)))));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ 0x00000900));
+
+ /* Wait for clock being stable. */
+ gcmkONERROR(gckOS_Delay(Os, 1));
+
+ /* Isolate the GPU. */
+ 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)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ control));
+
+ /* Set soft reset. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ ((((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)))));
+
+ /* Wait for reset. */
+ gcmkONERROR(gckOS_Delay(Os, 1));
+
+ /* Reset soft reset bit. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ ((((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)))));
+
+ /* Reset GPU isolation. */
+ 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)));
+
+ gcmkONERROR(gckOS_WriteRegisterEx(Os,
+ Core,
+ 0x00000,
+ control));
+
+ /* Read idle register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os,
+ Core,
+ 0x00004,
+ &idle));
+
+ 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)
+ {
+ continue;
+ }
+
+ /* Read reset register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Os,
+ Core,
+ 0x00000,
+ &control));
+
+ 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)
+ || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
+ )
+ {
+ continue;
+ }
+
+ /* GPU is idle. */
+ break;
+ }
+
+ /* Success. */
+ return gcvSTATUS_OK;
+
+OnError:
+
+ /* Return the error. */
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_Reset(
+ IN gckHARDWARE Hardware
+ )
+{
+ gceSTATUS status;
+ gckCOMMAND command;
+ gctBOOL acquired = gcvFALSE;
+ gctBOOL mutexAcquired = gcvFALSE;
+ gctUINT32 process, thread;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
+ command = Hardware->kernel->command;
+ gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
+
+ if (Hardware->identity.chipRevision < 0x4600)
+ {
+ /* Not supported - we need the isolation bit. */
+ gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+ }
+
+ status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0);
+ if (status == gcvSTATUS_TIMEOUT)
+ {
+ gcmkONERROR(gckOS_GetProcessID(&process));
+ gcmkONERROR(gckOS_GetThreadID(&thread));
+
+ if ((Hardware->powerProcess == process)
+ && (Hardware->powerThread == thread))
+ {
+ /* No way to recovery from a error in power management. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
+ }
+ else
+ {
+ mutexAcquired = gcvTRUE;
+ }
+
+ if (Hardware->chipPowerState == gcvPOWER_ON)
+ {
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(
+ gckOS_AcquireSemaphore(Hardware->os, command->powerSemaphore));
+ acquired = gcvTRUE;
+ }
+
+ if ((Hardware->chipPowerState == gcvPOWER_ON)
+ || (Hardware->chipPowerState == gcvPOWER_IDLE)
+ )
+ {
+ /* Stop the command processor. */
+ gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE));
+ }
+
+ /* Stop isr, we will start it again when power on GPU. */
+ if (Hardware->stopIsr)
+ {
+ gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
+ }
+
+ /* Hardware reset. */
+ status = gckOS_ResetGPU(Hardware->os, Hardware->core);
+
+ if (gcmIS_ERROR(status))
+ {
+ /* Soft reset. */
+ gcmkONERROR(_ResetGPU(Hardware, Hardware->os, Hardware->core));
+ }
+
+ /* Force an OFF to ON power switch. */
+ Hardware->chipPowerState = gcvPOWER_OFF;
+
+ gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+ mutexAcquired = gcvFALSE;
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ if (acquired)
+ {
+ /* Release the power management semaphore. */
+ gcmkVERIFY_OK(
+ gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore));
+ }
+
+ if (mutexAcquired)
+ {
+ gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
+ }
+
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_GetBaseAddress(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32_PTR BaseAddress
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
+
+ /* Test if we have a new Memory Controller. */
+ 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))))))))
+ {
+ /* No base address required. */
+ *BaseAddress = 0;
+ }
+ else
+ {
+ /* Get the base address from the OS. */
+ gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, BaseAddress));
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_NeedBaseAddress(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 State,
+ OUT gctBOOL_PTR NeedBase
+ )
+{
+ gctBOOL need = gcvFALSE;
+
+ gcmkHEADER_ARG("Hardware=0x%x State=0x%08x", Hardware, State);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(NeedBase != gcvNULL);
+
+ /* Make sure this is a load state. */
+ 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))))))))
+ {
+#ifndef VIVANTE_NO_3D
+ /* Get the state address. */
+ switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) ))
+ {
+ case 0x0596:
+ case 0x0597:
+ case 0x0599:
+ case 0x059A:
+ case 0x05A9:
+ /* These states need a TRUE physical address. */
+ need = gcvTRUE;
+ break;
+ }
+#else
+ /* 2D addresses don't need a base address. */
+#endif
+ }
+
+ /* Return the flag. */
+ *NeedBase = need;
+
+ /* Success. */
+ gcmkFOOTER_ARG("*NeedBase=%d", *NeedBase);
+ return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckHARDWARE_SetIsrManager(
+ IN gckHARDWARE Hardware,
+ IN gctISRMANAGERFUNC StartIsr,
+ IN gctISRMANAGERFUNC StopIsr,
+ IN gctPOINTER Context
+ )
+{
+ gceSTATUS status = gcvSTATUS_OK;
+
+ gcmkHEADER_ARG("Hardware=0x%x, StartIsr=0x%x, StopIsr=0x%x, Context=0x%x",
+ Hardware, StartIsr, StopIsr, Context);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ if (StartIsr == gcvNULL ||
+ StopIsr == gcvNULL ||
+ Context == gcvNULL)
+ {
+ status = gcvSTATUS_INVALID_ARGUMENT;
+
+ gcmkFOOTER();
+ return status;
+ }
+
+ Hardware->startIsr = StartIsr;
+ Hardware->stopIsr = StopIsr;
+ Hardware->isrContext = Context;
+
+ /* Success. */
+ gcmkFOOTER();
+
+ return status;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_Compose
+**
+** Start a composition.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to the gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Compose(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 ProcessID,
+ IN gctPHYS_ADDR Physical,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Offset,
+ IN gctSIZE_T Size,
+ IN gctUINT8 EventID
+ )
+{
+#ifndef VIVANTE_NO_3D
+ gceSTATUS status;
+ gctUINT32_PTR triggerState;
+
+ gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x Logical=0x%x"
+ " Offset=%d Size=%d EventID=%d",
+ Hardware, Physical, Logical, Offset, Size, EventID);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+ gcmkVERIFY_ARGUMENT(((Size + 8) & 63) == 0);
+ gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+
+ /* Program the trigger state. */
+ triggerState = (gctUINT32_PTR) ((gctUINT8_PTR) Logical + Offset + Size);
+ triggerState[0] = 0x0C03;
+ triggerState[1]
+ = ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ | ((((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)))
+ ;
+
+#if gcdNONPAGED_MEMORY_CACHEABLE
+ /* Flush the cache for the wait/link. */
+ gcmkONERROR(gckOS_CacheClean(
+ Hardware->os, ProcessID, gcvNULL,
+ Physical, Logical, Offset + Size
+ ));
+#endif
+
+ /* Start composition. */
+ gcmkONERROR(gckOS_WriteRegisterEx(
+ Hardware->os, Hardware->core, 0x00554,
+ ((((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)))
+ ));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+#else
+ /* Return the status. */
+ return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_IsFeatureAvailable
+**
+** Verifies whether the specified feature is available in hardware.
+**
+** INPUT:
+**
+** gckHARDWARE Hardware
+** Pointer to an gckHARDWARE object.
+**
+** gceFEATURE Feature
+** Feature to be verified.
+*/
+gceSTATUS
+gckHARDWARE_IsFeatureAvailable(
+ IN gckHARDWARE Hardware,
+ IN gceFEATURE Feature
+ )
+{
+ gctBOOL available;
+
+ gcmkHEADER_ARG("Hardware=0x%x Feature=%d", Hardware, Feature);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ /* Only features needed by common kernel logic added here. */
+ switch (Feature)
+ {
+ case gcvFEATURE_END_EVENT:
+ /*available = gcmVERIFYFIELDVALUE(Hardware->identity.chipMinorFeatures2,
+ GC_MINOR_FEATURES2, END_EVENT, AVAILABLE
+ );*/
+ available = gcvFALSE;
+ break;
+ case gcvFEATURE_MC20:
+ 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)))))));
+ break;
+ case gcvFEATURE_DYNAMIC_FREQUENCY_SCALING:
+ 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)))))));
+ break;
+
+ default:
+ gcmkFATAL("Invalid feature has been requested.");
+ available = gcvFALSE;
+ }
+
+ /* Return result. */
+ gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_OK);
+ return available ? gcvSTATUS_TRUE : gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_DumpMMUException
+**
+** Dump the MMU debug info on an MMU exception.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_DumpMMUException(
+ IN gckHARDWARE Hardware
+ )
+{
+#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT
+ gctUINT32 mmu, mmuStatus, address, i;
+#if gcdDEBUG
+ gctUINT32 mtlb, stlb, offset;
+#endif
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+ gcmkPRINT("GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
+ Hardware->core,
+ Hardware->identity.chipModel,
+ Hardware->identity.chipRevision);
+
+ gcmkPRINT("**************************\n");
+ gcmkPRINT("*** MMU ERROR DUMP ***\n");
+ gcmkPRINT("**************************\n");
+
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00188,
+ &mmuStatus));
+
+ gcmkPRINT(" MMU status = 0x%08X\n", mmuStatus);
+
+ for (i = 0; i < 4; i += 1)
+ {
+ mmu = mmuStatus & 0xF;
+ mmuStatus >>= 4;
+
+ if (mmu == 0)
+ {
+ continue;
+ }
+
+ switch (mmu)
+ {
+ case 1:
+ gcmkPRINT(" MMU%d: slave not present\n", i);
+ break;
+
+ case 2:
+ gcmkPRINT(" MMU%d: page not present\n", i);
+ break;
+
+ case 3:
+ gcmkPRINT(" MMU%d: write violation\n", i);
+ break;
+
+ default:
+ gcmkPRINT(" MMU%d: unknown state\n", i);
+ }
+
+ gcmkVERIFY_OK(
+ gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00190 + i * 4,
+ &address));
+
+ mtlb = (address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+ stlb = (address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+ offset = address & gcdMMU_OFFSET_4K_MASK;
+
+ gcmkPRINT(" MMU%d: exception address = 0x%08X\n", i, address);
+
+ gcmkPRINT(" MTLB entry = %d\n", mtlb);
+
+ gcmkPRINT(" STLB entry = %d\n", stlb);
+
+ gcmkPRINT(" Offset = 0x%08X (%d)\n", offset, offset);
+
+ gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
+
+ }
+
+ gcmkFOOTER_NO();
+#else
+ /* If clock could be off automatically, we can't read mmu debug
+ ** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0
+ ** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */
+ gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__);
+#endif
+
+ return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+** gckHARDWARE_DumpGPUState
+**
+** Dump the GPU debug registers.
+**
+** INPUT:
+**
+** gckHARDWARE Harwdare
+** Pointer to an gckHARDWARE object.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckHARDWARE_DumpGPUState(
+ IN gckHARDWARE Hardware
+ )
+{
+ static gctCONST_STRING _cmdState[] =
+ {
+ "PAR_IDLE_ST", "PAR_DEC_ST", "PAR_ADR0_ST", "PAR_LOAD0_ST",
+ "PAR_ADR1_ST", "PAR_LOAD1_ST", "PAR_3DADR_ST", "PAR_3DCMD_ST",
+ "PAR_3DCNTL_ST", "PAR_3DIDXCNTL_ST", "PAR_INITREQDMA_ST",
+ "PAR_DRAWIDX_ST", "PAR_DRAW_ST", "PAR_2DRECT0_ST", "PAR_2DRECT1_ST",
+ "PAR_2DDATA0_ST", "PAR_2DDATA1_ST", "PAR_WAITFIFO_ST", "PAR_WAIT_ST",
+ "PAR_LINK_ST", "PAR_END_ST", "PAR_STALL_ST"
+ };
+
+ static gctCONST_STRING _cmdDmaState[] =
+ {
+ "CMD_IDLE_ST", "CMD_START_ST", "CMD_REQ_ST", "CMD_END_ST"
+ };
+
+ static gctCONST_STRING _cmdFetState[] =
+ {
+ "FET_IDLE_ST", "FET_RAMVALID_ST", "FET_VALID_ST"
+ };
+
+ static gctCONST_STRING _reqDmaState[] =
+ {
+ "REQ_IDLE_ST", "REQ_WAITIDX_ST", "REQ_CAL_ST"
+ };
+
+ static gctCONST_STRING _calState[] =
+ {
+ "CAL_IDLE_ST", "CAL_LDADR_ST", "CAL_IDXCALC_ST"
+ };
+
+ static gctCONST_STRING _veReqState[] =
+ {
+ "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST"
+ };
+
+ static gcsiDEBUG_REGISTERS _dbgRegs[] =
+ {
+ { "RA", 0x474, 16, 0x448, 16, 0x12344321 },
+ { "TX", 0x474, 24, 0x44C, 16, 0x12211221 },
+ { "FE", 0x470, 0, 0x450, 16, 0xBABEF00D },
+ { "PE", 0x470, 16, 0x454, 16, 0xBABEF00D },
+ { "DE", 0x470, 8, 0x458, 16, 0xBABEF00D },
+ { "SH", 0x470, 24, 0x45C, 16, 0xDEADBEEF },
+ { "PA", 0x474, 0, 0x460, 16, 0x0000AAAA },
+ { "SE", 0x474, 8, 0x464, 16, 0x5E5E5E5E },
+ { "MC", 0x478, 0, 0x468, 16, 0x12345678 },
+ { "HI", 0x478, 8, 0x46C, 16, 0xAAAAAAAA }
+ };
+
+ static gctUINT32 _otherRegs[] =
+ {
+ 0x040, 0x044, 0x04C, 0x050, 0x054, 0x058, 0x05C, 0x060,
+ 0x43c, 0x440, 0x444, 0x414,
+ };
+
+ gceSTATUS status;
+ gckKERNEL kernel;
+ gctUINT32 idle, axi;
+ gctUINT32 dmaAddress1, dmaAddress2;
+ gctUINT32 dmaState1, dmaState2;
+ gctUINT32 dmaLow, dmaHigh;
+ gctUINT32 cmdState, cmdDmaState, cmdFetState;
+ gctUINT32 dmaReqState, calState, veReqState;
+ gctUINT i;
+ gctUINT pipe, pixelPipes;
+ gctUINT32 control, oldControl;
+ gckOS os = Hardware->os;
+ gceCORE core = Hardware->core;
+
+ gcmkHEADER_ARG("Hardware=0x%X", Hardware);
+
+ kernel = Hardware->kernel;
+
+ gcmkPRINT_N(12, "GPU[%d](ChipModel=0x%x ChipRevision=0x%x):\n",
+ core,
+ Hardware->identity.chipModel,
+ Hardware->identity.chipRevision);
+
+ pixelPipes = Hardware->identity.pixelPipes
+ ? Hardware->identity.pixelPipes
+ : 1;
+
+ /* Reset register values. */
+ idle = axi =
+ dmaState1 = dmaState2 =
+ dmaAddress1 = dmaAddress2 =
+ dmaLow = dmaHigh = 0;
+
+ /* Verify whether DMA is running. */
+ gcmkONERROR(_VerifyDMA(
+ os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
+ ));
+
+ cmdState = dmaState2 & 0x1F;
+ cmdDmaState = (dmaState2 >> 8) & 0x03;
+ cmdFetState = (dmaState2 >> 10) & 0x03;
+ dmaReqState = (dmaState2 >> 12) & 0x03;
+ calState = (dmaState2 >> 14) & 0x03;
+ veReqState = (dmaState2 >> 16) & 0x03;
+
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x004, &idle));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x00C, &axi));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x668, &dmaLow));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x66C, &dmaHigh));
+
+ gcmkPRINT_N(0, "**************************\n");
+ gcmkPRINT_N(0, "*** GPU STATE DUMP ***\n");
+ gcmkPRINT_N(0, "**************************\n");
+
+ gcmkPRINT_N(4, " axi = 0x%08X\n", axi);
+
+ gcmkPRINT_N(4, " idle = 0x%08X\n", idle);
+ if ((idle & 0x00000001) == 0) gcmkPRINT_N(0, " FE not idle\n");
+ if ((idle & 0x00000002) == 0) gcmkPRINT_N(0, " DE not idle\n");
+ if ((idle & 0x00000004) == 0) gcmkPRINT_N(0, " PE not idle\n");
+ if ((idle & 0x00000008) == 0) gcmkPRINT_N(0, " SH not idle\n");
+ if ((idle & 0x00000010) == 0) gcmkPRINT_N(0, " PA not idle\n");
+ if ((idle & 0x00000020) == 0) gcmkPRINT_N(0, " SE not idle\n");
+ if ((idle & 0x00000040) == 0) gcmkPRINT_N(0, " RA not idle\n");
+ if ((idle & 0x00000080) == 0) gcmkPRINT_N(0, " TX not idle\n");
+ if ((idle & 0x00000100) == 0) gcmkPRINT_N(0, " VG not idle\n");
+ if ((idle & 0x00000200) == 0) gcmkPRINT_N(0, " IM not idle\n");
+ if ((idle & 0x00000400) == 0) gcmkPRINT_N(0, " FP not idle\n");
+ if ((idle & 0x00000800) == 0) gcmkPRINT_N(0, " TS not idle\n");
+ if ((idle & 0x80000000) != 0) gcmkPRINT_N(0, " AXI low power mode\n");
+
+ if (
+ (dmaAddress1 == dmaAddress2)
+ && (dmaState1 == dmaState2)
+ )
+ {
+ gcmkPRINT_N(0, " DMA appears to be stuck at this address:\n");
+ gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
+ }
+ else
+ {
+ if (dmaAddress1 == dmaAddress2)
+ {
+ gcmkPRINT_N(0, " DMA address is constant, but state is changing:\n");
+ gcmkPRINT_N(4, " 0x%08X\n", dmaState1);
+ gcmkPRINT_N(4, " 0x%08X\n", dmaState2);
+ }
+ else
+ {
+ gcmkPRINT_N(0, " DMA is running; known addresses are:\n");
+ gcmkPRINT_N(4, " 0x%08X\n", dmaAddress1);
+ gcmkPRINT_N(4, " 0x%08X\n", dmaAddress2);
+ }
+ }
+ gcmkPRINT_N(4, " dmaLow = 0x%08X\n", dmaLow);
+ gcmkPRINT_N(4, " dmaHigh = 0x%08X\n", dmaHigh);
+ gcmkPRINT_N(4, " dmaState = 0x%08X\n", dmaState2);
+ gcmkPRINT_N(8, " command state = %d (%s)\n", cmdState, _cmdState [cmdState]);
+ gcmkPRINT_N(8, " command DMA state = %d (%s)\n", cmdDmaState, _cmdDmaState[cmdDmaState]);
+ gcmkPRINT_N(8, " command fetch state = %d (%s)\n", cmdFetState, _cmdFetState[cmdFetState]);
+ gcmkPRINT_N(8, " DMA request state = %d (%s)\n", dmaReqState, _reqDmaState[dmaReqState]);
+ gcmkPRINT_N(8, " cal state = %d (%s)\n", calState, _calState [calState]);
+ gcmkPRINT_N(8, " VE request state = %d (%s)\n", veReqState, _veReqState [veReqState]);
+
+ /* Record control. */
+ gckOS_ReadRegisterEx(os, core, 0x0, &oldControl);
+
+ for (pipe = 0; pipe < pixelPipes; pipe++)
+ {
+ gcmkPRINT_N(4, " Debug registers of pipe[%d]:\n", pipe);
+
+ /* Switch pipe. */
+ gckOS_ReadRegisterEx(os, core, 0x0, &control);
+ control &= ~(0xF << 20);
+ control |= (pipe << 20);
+ gckOS_WriteRegisterEx(os, core, 0x0, control);
+
+ for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
+ {
+ gcmkONERROR(_DumpDebugRegisters(os, core, &_dbgRegs[i]));
+ }
+
+ gcmkPRINT_N(0, " Other Registers:\n");
+ for (i = 0; i < gcmCOUNTOF(_otherRegs); i += 1)
+ {
+ gctUINT32 read;
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, _otherRegs[i], &read));
+ gcmkPRINT_N(12, " [0x%04X] 0x%08X\n", _otherRegs[i], read);
+ }
+ }
+
+ if (kernel->hardware->identity.chipFeatures & (1 << 4))
+ {
+ gctUINT32 read0, read1, write;
+
+ read0 = read1 = write = 0;
+
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x43C, &read0));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x440, &read1));
+ gcmkONERROR(gckOS_ReadRegisterEx(os, core, 0x444, &write));
+
+ gcmkPRINT_N(4, " read0 = 0x%08X\n", read0);
+ gcmkPRINT_N(4, " read1 = 0x%08X\n", read1);
+ gcmkPRINT_N(4, " write = 0x%08X\n", write);
+ }
+
+ /* Restore control. */
+ gckOS_WriteRegisterEx(os, core, 0x0, oldControl);
+
+ /* dump stack. */
+ gckOS_DumpCallStack(os);
+
+OnError:
+
+ /* Return the error. */
+ gcmkFOOTER();
+ return status;
+}
+
+
+#if gcdFRAME_DB
+static gceSTATUS
+gckHARDWARE_ReadPerformanceRegister(
+ IN gckHARDWARE Hardware,
+ IN gctUINT PerformanceAddress,
+ IN gctUINT IndexAddress,
+ IN gctUINT IndexShift,
+ IN gctUINT Index,
+ OUT gctUINT32_PTR Value
+ )
+{
+ gceSTATUS status;
+
+ gcmkHEADER_ARG("Hardware=0x%x PerformanceAddress=0x%x IndexAddress=0x%x "
+ "IndexShift=%u Index=%u",
+ Hardware, PerformanceAddress, IndexAddress, IndexShift,
+ Index);
+
+ /* Write the index. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ IndexAddress,
+ Index << IndexShift));
+
+ /* Read the register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ PerformanceAddress,
+ Value));
+
+ /* Test for reset. */
+ if (Index == 15)
+ {
+ /* Index another register to get out of reset. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, IndexAddress, 0));
+ }
+
+ /* Success. */
+ gcmkFOOTER_ARG("*Value=0x%x", *Value);
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+
+gceSTATUS
+gckHARDWARE_GetFrameInfo(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_FRAME_INFO * FrameInfo
+ )
+{
+ gceSTATUS status;
+ gctUINT i, clock;
+ gcsHAL_FRAME_INFO info;
+#if gcdFRAME_DB_RESET
+ gctUINT reset;
+#endif
+
+ gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+ /* Get profile tick. */
+ gcmkONERROR(gckOS_GetProfileTick(&info.ticks));
+
+ /* Read SH counters and reset them. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 4,
+ &info.shaderCycles));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 9,
+ &info.vsInstructionCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 12,
+ &info.vsTextureCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 7,
+ &info.psInstructionCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 14,
+ &info.psTextureCount));
+#if gcdFRAME_DB_RESET
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0045C,
+ 0x00470,
+ 24,
+ 15,
+ &reset));
+#endif
+
+ /* Read PA counters and reset them. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 3,
+ &info.vertexCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 4,
+ &info.primitiveCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 7,
+ &info.rejectedPrimitives));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 8,
+ &info.culledPrimitives));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 6,
+ &info.clippedPrimitives));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 5,
+ &info.outPrimitives));
+#if gcdFRAME_DB_RESET
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00460,
+ 0x00474,
+ 0,
+ 15,
+ &reset));
+#endif
+
+ /* Read RA counters and reset them. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 3,
+ &info.inPrimitives));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 11,
+ &info.culledQuadCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 1,
+ &info.totalQuadCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 2,
+ &info.quadCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 0,
+ &info.totalPixelCount));
+#if gcdFRAME_DB_RESET
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00448,
+ 0x00474,
+ 16,
+ 15,
+ &reset));
+#endif
+
+ /* Read TX counters and reset them. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 0,
+ &info.bilinearRequests));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 1,
+ &info.trilinearRequests));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 8,
+ &info.txHitCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 9,
+ &info.txMissCount));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 6,
+ &info.txBytes8));
+#if gcdFRAME_DB_RESET
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x0044C,
+ 0x00474,
+ 24,
+ 15,
+ &reset));
+#endif
+
+ /* Read clock control register. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ &clock));
+
+ /* Walk through all avaiable pixel pipes. */
+ for (i = 0; i < Hardware->identity.pixelPipes; ++i)
+ {
+ /* Select proper pipe. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ ((((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)))));
+
+ /* Read cycle registers. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00078,
+ &info.cycles[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0007C,
+ &info.idleCycles[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00438,
+ &info.mcCycles[i]));
+
+ /* Read bandwidth registers. */
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0005C,
+ &info.readRequests[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00040,
+ &info.readBytes8[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00050,
+ &info.writeRequests[i]));
+ gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00044,
+ &info.writeBytes8[i]));
+
+ /* Read PE counters. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 0,
+ &info.colorKilled[i]));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 2,
+ &info.colorDrawn[i]));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 1,
+ &info.depthKilled[i]));
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 3,
+ &info.depthDrawn[i]));
+ }
+
+ /* Zero out remaning reserved counters. */
+ for (; i < 8; ++i)
+ {
+ info.readBytes8[i] = 0;
+ info.writeBytes8[i] = 0;
+ info.cycles[i] = 0;
+ info.idleCycles[i] = 0;
+ info.mcCycles[i] = 0;
+ info.readRequests[i] = 0;
+ info.writeRequests[i] = 0;
+ info.colorKilled[i] = 0;
+ info.colorDrawn[i] = 0;
+ info.depthKilled[i] = 0;
+ info.depthDrawn[i] = 0;
+ }
+
+ /* Reset clock control register. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00000,
+ clock));
+
+ /* Reset cycle and bandwidth counters. */
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0003C,
+ 1));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x0003C,
+ 0));
+ gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
+ Hardware->core,
+ 0x00078,
+ 0));
+
+#if gcdFRAME_DB_RESET
+ /* Reset PE counters. */
+ gcmkONERROR(gckHARDWARE_ReadPerformanceRegister(
+ Hardware,
+ 0x00454,
+ 0x00470,
+ 16,
+ 15,
+ &reset));
+#endif
+
+ /* Copy to user. */
+ gcmkONERROR(gckOS_CopyToUserData(Hardware->os,
+ &info,
+ FrameInfo,
+ gcmSIZEOF(info)));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+#endif
+
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h
new file mode 100644
index 00000000..9ecfca76
--- /dev/null
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+*
+* Copyright (C) 2005 - 2012 by Vivante Corp.
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the license, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not write to the Free Software
+* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+
+#ifndef __gc_hal_kernel_hardware_h_
+#define __gc_hal_kernel_hardware_h_
+
+#if gcdENABLE_VG
+#include "gc_hal_kernel_hardware_vg.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* gckHARDWARE object. */
+struct _gckHARDWARE
+{
+ /* Object. */
+ gcsOBJECT object;
+
+ /* Pointer to gctKERNEL object. */
+ gckKERNEL kernel;
+
+ /* Pointer to gctOS object. */
+ gckOS os;
+
+ /* Core */
+ gceCORE core;
+
+ /* Chip characteristics. */
+ gcsHAL_QUERY_CHIP_IDENTITY identity;
+ gctBOOL allowFastClear;
+ gctBOOL allowCompression;
+ gctUINT32 powerBaseAddress;
+ gctBOOL extraEventStates;
+
+ /* Big endian */
+ gctBOOL bigEndian;
+
+ /* Chip status */
+ gctPOINTER powerMutex;
+ gctUINT32 powerProcess;
+ gctUINT32 powerThread;
+ gceCHIPPOWERSTATE chipPowerState;
+ gctUINT32 lastWaitLink;
+ gctBOOL clockState;
+ gctBOOL powerState;
+ gctPOINTER globalSemaphore;
+
+ gctISRMANAGERFUNC startIsr;
+ gctISRMANAGERFUNC stopIsr;
+ gctPOINTER isrContext;
+
+ gctUINT32 mmuVersion;
+
+ /* Type */
+ gceHARDWARE_TYPE type;
+
+#if gcdPOWEROFF_TIMEOUT
+ gctUINT32 powerOffTime;
+ gctUINT32 powerOffTimeout;
+ gctPOINTER powerOffTimer;
+#endif
+
+ gctPOINTER pageTableDirty;
+
+#if gcdENABLE_FSCALE_VAL_ADJUST
+ /* FSCALE_VAL when gcvPOWER_ON. */
+ gctUINT32 powerOnFscaleVal;
+#endif
+
+#if gcdLINK_QUEUE_SIZE
+ struct _gckLINKQUEUE linkQueue;
+#endif
+};
+
+gceSTATUS
+gckHARDWARE_GetBaseAddress(
+ IN gckHARDWARE Hardware,
+ OUT gctUINT32_PTR BaseAddress
+ );
+
+gceSTATUS
+gckHARDWARE_NeedBaseAddress(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 State,
+ OUT gctBOOL_PTR NeedBase
+ );
+
+gceSTATUS
+gckHARDWARE_GetFrameInfo(
+ IN gckHARDWARE Hardware,
+ OUT gcsHAL_FRAME_INFO * FrameInfo
+ );
+
+gceSTATUS
+gckHARDWARE_SetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT32 FscaleValue
+ );
+
+gceSTATUS
+gckHARDWARE_GetFscaleValue(
+ IN gckHARDWARE Hardware,
+ IN gctUINT * FscaleValue,
+ IN gctUINT * MinFscaleValue,
+ IN gctUINT * MaxFscaleValue
+ );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_kernel_hardware_h_ */
+