MGS-4683: integrate GPU 6.4.0 beta early version
authorXianzhong <xianzhong.li@nxp.com>
Tue, 16 Apr 2019 14:44:44 +0000 (22:44 +0800)
committerLeonard Crestez <leonard.crestez@nxp.com>
Thu, 18 Apr 2019 00:00:38 +0000 (03:00 +0300)
support new features for i.MX8 AI/ML:
1. Android NN with VXC acceleration
2. VXC NN adapter for Tensorflow Lite
3. Unified OpenVX for QM/QXP/mScale
4. OpenVX 1.2 with NN extension
5. Bridged GPU compute on 8QM

Signed-off-by: Xianzhong <xianzhong.li@nxp.com>
98 files changed:
drivers/mxc/gpu-viv/Kbuild
drivers/mxc/gpu-viv/config
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.c
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_context.h
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.c
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware.h
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_async_fe.c [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_fe.h [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_mc_fe.c [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_waitlink_fe.c [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_recorder.c
drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.c
drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_command_vg.h
drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.c
drivers/mxc/gpu-viv/hal/kernel/archvg/gc_hal_kernel_hardware_vg.h
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_async_command.c [deleted file]
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command_vg.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_db.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_debug.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_heap.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_interrupt_vg.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_mmu_vg.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_power.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_precomp.h
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_security_v1.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_vg.h
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
drivers/mxc/gpu-viv/hal/kernel/inc/gc_feature_database.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_debug_zones.h [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver_vg.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_drm.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_dump.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine_vg.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_kernel_buffer.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_mem.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_metadata.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_profiler.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_raster.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h [deleted file]
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_resource.h [deleted file]
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_security_interface.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_vg.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_array.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dma.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_dmabuf.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_gfp.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_reserved_mem.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/default/gc_hal_kernel_allocator_user_memory.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_array.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/allocator/freescale/gc_hal_kernel_allocator_cma.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_allocator.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_drm.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_iommu.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_linux.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_math.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_mutex.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_platform.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_security_channel_emulator.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_sync.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.config [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx.c
drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.c
drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta.h
drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.c
drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_hardware.h
drivers/mxc/gpu-viv/hal/security_v1/gc_hal_ta_mmu.c
drivers/mxc/gpu-viv/hal/security_v1/os/emulator/gc_hal_ta_emulator.c

index 5f45b13..2290459 100644 (file)
@@ -2,7 +2,7 @@
 #
 #    The MIT License (MIT)
 #
-#    Copyright (c) 2014 - 2018 Vivante Corporation
+#    Copyright (c) 2014 - 2019 Vivante Corporation
 #
 #    Permission is hereby granted, free of charge, to any person obtaining a
 #    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 #
 #    The GPL License (GPL)
 #
-#    Copyright (C) 2014 - 2018 Vivante Corporation
+#    Copyright (C) 2014 - 2019 Vivante Corporation
 #
 #    This program is free software; you can redistribute it and/or
 #    modify it under the terms of the GNU General Public License
@@ -108,7 +108,6 @@ endif
 
 OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \
         $(HAL_KERNEL_DIR)/gc_hal_kernel_command.o \
-        $(HAL_KERNEL_DIR)/gc_hal_kernel_async_command.o \
         $(HAL_KERNEL_DIR)/gc_hal_kernel_db.o \
         $(HAL_KERNEL_DIR)/gc_hal_kernel_debug.o \
         $(HAL_KERNEL_DIR)/gc_hal_kernel_event.o \
@@ -119,7 +118,10 @@ OBJS += $(HAL_KERNEL_DIR)/gc_hal_kernel.o \
         $(HAL_KERNEL_DIR)/gc_hal_kernel_security_v1.o
 
 OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_context.o \
-        $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware.o
+        $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware.o \
+        $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware_async_fe.o \
+        $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware_mc_fe.o \
+        $(ARCH_KERNEL_DIR)/gc_hal_kernel_hardware_waitlink_fe.o
 
 ifeq ($(VIVANTE_ENABLE_3D), 1)
 OBJS += $(ARCH_KERNEL_DIR)/gc_hal_kernel_recorder.o
@@ -235,12 +237,6 @@ else
 EXTRA_CFLAGS += -DUSE_LINUX_PCIE=0
 endif
 
-ifeq ($(FORCE_ALL_VIDEO_MEMORY_CACHED), 1)
-EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=1
-else
-EXTRA_CFLAGS += -DgcdPAGED_MEMORY_CACHEABLE=0
-endif
-
 ifeq ($(CACHE_FUNCTION_UNIMPLEMENTED), 1)
 EXTRA_CFLAGS += -DgcdCACHE_FUNCTION_UNIMPLEMENTED=1
 else
index 1fb80a7..267487c 100644 (file)
@@ -2,7 +2,7 @@
 #
 #    The MIT License (MIT)
 #
-#    Copyright (c) 2014 - 2018 Vivante Corporation
+#    Copyright (c) 2014 - 2019 Vivante Corporation
 #
 #    Permission is hereby granted, free of charge, to any person obtaining a
 #    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 #
 #    The GPL License (GPL)
 #
-#    Copyright (C) 2014 - 2018 Vivante Corporation
+#    Copyright (C) 2014 - 2019 Vivante Corporation
 #
 #    This program is free software; you can redistribute it and/or
 #    modify it under the terms of the GNU General Public License
@@ -62,7 +62,6 @@ VIVANTE_ENABLE_DRM                ?= 1
 NO_DMA_COHERENT                   ?= 0
 USE_PLATFORM_DRIVER               ?= 1
 ENABLE_GPU_CLOCK_BY_DRIVER        ?= 0
-FORCE_ALL_VIDEO_MEMORY_CACHED     ?= 0
 CACHE_FUNCTION_UNIMPLEMENTED      ?= 0
 USE_BANK_ALIGNMENT                ?= 1
 BANK_BIT_START                    ?= 13
index 9516342..97ef15f 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
         gcvFALSE, gcvFALSE                                                     \
         )
 
+#define _STATE_INIT_VALUE_BLOCK(reg, value, block, count)                      \
+    _State(\
+        Context, index, \
+        (reg ## _Address >> 2) + (block << reg ## _BLK), \
+        value, \
+        count, \
+        gcvFALSE, gcvFALSE                                                     \
+        )
+
+
 #define _CLOSE_RANGE()                                                         \
     _TerminateStateBlock(Context, index)
 
@@ -225,6 +235,7 @@ _FlushPipe(
     gctBOOL hwTFB;
     gctBOOL blt;
     gctBOOL peTSFlush;
+    gctBOOL multiCluster;
 
     txCacheFix
         = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_TEX_CACHE_FLUSH_FIX);
@@ -242,12 +253,13 @@ _FlushPipe(
         = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_SNAPPAGE_CMD_FIX) &&
           gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_SNAPPAGE_CMD);
 
-
     hwTFB
         = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_HW_TFB);
 
     blt
         = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_BLT_ENGINE);
+    multiCluster
+        = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_MULTI_CLUSTER);
 
     peTSFlush
         = gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX);
@@ -637,7 +649,8 @@ _FlushPipe(
  1:1) - (0 ?
  1:1) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
-                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                  | (multiCluster ?
+ 0 : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  2:2) - (0 ?
  2:2) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -646,7 +659,7 @@ _FlushPipe(
  2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
  2:2) - (0 ?
  2:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))))
                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  5:5) - (0 ?
  5:5) + 1) == 32) ?
@@ -713,7 +726,7 @@ _FlushPipe(
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
              *buffer++
-                 = 0x12345678;
+                 = 0x1;
         }
 
         /* Flush VST in separate cmd. */
@@ -2543,14 +2556,6 @@ _State(
 
                 /* Set index in state mapping table. */
                 Context->map[Address + i].index = (gctUINT)Index + 1 + i;
-
-#if gcdSECURE_USER
-                /* Save hint. */
-                if (Context->hint != gcvNULL)
-                {
-                    Context->hint[Address + i] = Hinted;
-                }
-#endif
             }
         }
 
@@ -2588,14 +2593,6 @@ _State(
 
             /* Set index in state mapping table. */
             Context->map[Address + i].index = (gctUINT)Index + i;
-
-#if gcdSECURE_USER
-            /* Save hint. */
-            if (Context->hint != gcvNULL)
-            {
-                Context->hint[Address + i] = Hinted;
-            }
-#endif
         }
     }
 
@@ -2626,17 +2623,226 @@ _StateMirror(
             /* Copy the mapping address. */
             Context->map[Address + i].index =
                 Context->map[AddressMirror + i].index;
-
-#if gcdSECURE_USER
-            Context->hint[Address + i] =
-                Context->hint[AddressMirror + i];
-#endif
         }
     }
 
     /* Return the number of required maps. */
     return Size;
 }
+
+static void
+_UpdateUnifiedReg(
+    IN gckCONTEXT Context,
+    IN gctUINT32 Address,
+    IN gctUINT32 Size,
+    IN gctUINT32 Count
+    )
+{
+    gctUINT base;
+    gctUINT nopCount;
+    gctUINT32_PTR nop;
+    gcsCONTEXT_PTR buffer;
+    gcsSTATE_MAP_PTR map;
+    gctUINT i;
+
+    /* Get the current context buffer. */
+    buffer = Context->buffer;
+
+    /* Get the state map. */
+    map = Context->map;
+
+    base = map[Address].index;
+
+    if (Count > 1024)
+    {
+        buffer->logical[base - 1]
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1))))))) << (0 ?
+ 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1024) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+        buffer->logical[base + 1024 + 1]
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1))))))) << (0 ?
+ 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (Count - 1024) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Address + 1024) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+        /* Determine the number of NOP commands. */
+        nopCount = (Size / 2) - (Count / 2);
+        /* Determine the location of the first NOP. */
+        nop = &buffer->logical[base + (Count | 1) + 2];
+
+        /* 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) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+            /* Advance. */
+            nop += 2;
+        }
+    }
+    else
+    {
+        buffer->logical[base - 1]
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1))))))) << (0 ?
+ 26:26))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 26:26) - (0 ?
+ 26:26) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 26:26) - (0 ? 26:26) + 1))))))) << (0 ? 26:26)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Address) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+        /* Determine the number of NOP commands. */
+        nopCount = (Size / 2) - (Count / 2) + Size / 1024;
+
+        /* Determine the location of the first NOP. */
+        nop = &buffer->logical[base + (Count | 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) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+            /* Advance. */
+            nop += 2;
+        }
+    }
+}
 #endif
 
 #if (gcdENABLE_3D || gcdENABLE_2D)
@@ -2662,7 +2868,12 @@ _InitializeContextBuffer(
     gctBOOL hasTXdesc;
     gctBOOL hasSecurity;
     gctBOOL hasRobustness;
+    gctBOOL multiCluster;
+    gctBOOL smallBatch;
     gctBOOL multiCoreBlockSetCfg2;
+    gctUINT clusterAliveMask;
+    gctBOOL hasPSCSThrottle;
+    gctBOOL hasMsaaFragOperation;
 #endif
 
     gckHARDWARE hardware;
@@ -2707,12 +2918,23 @@ _InitializeContextBuffer(
     hasSecurity = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_SECURITY);
     hasRobustness = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_ROBUSTNESS);
     hasICachePrefetch = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_SH_INSTRUCTION_PREFETCH);
+    multiCluster = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MULTI_CLUSTER);
+    smallBatch = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_SMALL_BATCH) && hardware->options.smallBatch;
     multiCoreBlockSetCfg2 = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MULTI_CORE_BLOCK_SET_CONFIG2);
+    clusterAliveMask = hardware->identity.clusterAvailMask & hardware->options.userClusterMask;
+    hasPSCSThrottle = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_PSCS_THROTTLE);
+    hasMsaaFragOperation = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MSAA_FRAGMENT_OPERATION);
 
     /* Multi render target. */
-    if (halti2 ||
-        (Context->hardware->identity.chipModel == gcv900 && Context->hardware->identity.chipRevision == 0x5250)
-       )
+    if (Context->hardware->identity.chipModel == gcv880 &&
+        Context->hardware->identity.chipRevision == 0x5124 &&
+        Context->hardware->identity.customerID == 0x103)
+    {
+        numRT = 16;
+    }
+    else if (halti2 ||
+            ((Context->hardware->identity.chipModel == gcv900) &&
+            (Context->hardware->identity.chipRevision == 0x5250)))
     {
         numRT = 8;
     }
@@ -2732,7 +2954,9 @@ _InitializeContextBuffer(
 
     /* Query how many uniforms can support. */
     {if (Context->hardware->identity.numConstants > 256){    unifiedUniform = gcvTRUE;
-if (halti5){    vsConstBase  = 0xD000;
+if (smallBatch){    vsConstBase  = 0xD000;
+    psConstBase  = 0xD000;
+}else if (halti5){    vsConstBase  = 0xD000;
     psConstBase  = 0xD800;
 }else{    vsConstBase  = 0xC000;
     psConstBase  = 0xC000;
@@ -2780,6 +3004,32 @@ if (halti5){    vsConstBase  = 0xD000;
     /* Switch to 3D pipe. */
     index += _SwitchPipe(Context, index, gcvPIPE_3D);
 
+    if (multiCluster)
+    {
+        index += _State(Context, index, (0x03910 >> 2) + (0 << 2), ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (clusterAliveMask) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0))), 4, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x03908 >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1))))))) << (0 ?
+ 2:0))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 2:0) - (0 ?
+ 2:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:0) - (0 ? 2:0) + 1))))))) << (0 ? 2:0))), 1, gcvFALSE, gcvFALSE);
+    }
+
     /* Current context pointer. */
 #if gcdDEBUG
     index += _State(Context, index, 0x03850 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
@@ -2802,9 +3052,20 @@ if (halti5){    vsConstBase  = 0xD000;
 
     if (halti5)
     {
+        gctUINT32 uscControl = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 20:16) - (0 ?
+ 20:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 20:16) - (0 ?
+ 20:16) + 1))))))) << (0 ?
+ 20:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
+ 20:16) - (0 ?
+ 20:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16)));
         index += _State(Context, index, 0x03888 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
         index += _State(Context, index, 0x038C0 >> 2, 0x00000000, 16, gcvFALSE, gcvFALSE);
-        index += _State(Context, index, 0x03884 >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+
+        uscControl |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  2:0) - (0 ?
  2:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -2813,20 +3074,21 @@ if (halti5){    vsConstBase  = 0xD000;
  2:0))) | (((gctUINT32) ((gctUINT32) (hardware->options.uscL1CacheRatio) & ((gctUINT32) ((((1 ?
  2:0) - (0 ?
  2:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 2:0) - (0 ?
- 2:0) + 1))))))) << (0 ?
- 2:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 20:16) - (0 ?
- 20:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 20:16) - (0 ?
- 20:16) + 1))))))) << (0 ?
- 20:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ?
- 20:16) - (0 ?
- 20:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16))), 1, gcvFALSE, gcvFALSE);
+ ~0U : (~(~0U << ((1 ? 2:0) - (0 ? 2:0) + 1))))))) << (0 ? 2:0)));
+        if (multiCluster)
+        {
+            uscControl |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 11:8) - (0 ?
+ 11:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 11:8) - (0 ?
+ 11:8) + 1))))))) << (0 ?
+ 11:8))) | (((gctUINT32) ((gctUINT32) (hardware->options.uscAttribCacheRatio) & ((gctUINT32) ((((1 ?
+ 11:8) - (0 ?
+ 11:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8)));
+        }
+        index += _State(Context, index, 0x03884 >> 2, uscControl, 1, gcvFALSE, gcvFALSE);
     }
     else
     {
@@ -2851,13 +3113,16 @@ if (halti5){    vsConstBase  = 0xD000;
         index += _State(Context, index, 0x17800 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
         index += _CLOSE_RANGE();
         index += _State(Context, index, 0x007C4 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x007D0 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x007D8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x17A80 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+        if (genericAttrib)
+        {
             index += _State(Context, index, 0x17880 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
             index += _State(Context, index, 0x17900 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
             index += _State(Context, index, 0x17980 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
             index += _State(Context, index, 0x17A00 >> 2, 0x3F800000, 32, gcvFALSE, gcvFALSE);
-        index += _State(Context, index, 0x007D0 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
-        index += _State(Context, index, 0x007D8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
-        index += _State(Context, index, 0x17A80 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
+        }
     }
     else
     {
@@ -2904,9 +3169,74 @@ if (halti5){    vsConstBase  = 0xD000;
         index += _CLOSE_RANGE();
     }
 
+    /* WD */
+    if (multiCluster)
+    {
+        index += _State(Context, index, 0x18404 >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1))))))) << (0 ?
+ 1:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:0) - (0 ?
+ 1:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))), 1, gcvFALSE, gcvFALSE);
+    }
+
     if (halti5)
     {
-        index += _State(Context, index, 0x008B8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x008B8 >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) ((gctUINT32) (smallBatch ?
+ 0x0 : 0x1) & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) ((gctUINT32) (smallBatch ?
+ 0x0 : 0x1) & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1))))))) << (0 ?
+ 8:8))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:8) - (0 ?
+ 8:8) + 1))))))) << (0 ?
+ 8:8))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))), 1, gcvFALSE, gcvFALSE);
+
         index += _State(Context, index, 0x15600 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
     }
     else
@@ -2942,6 +3272,11 @@ if (halti5){    vsConstBase  = 0xD000;
         }
     }
 
+    if (multiCluster)
+    {
+        index += _State(Context, index, 0x010A8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+    }
+
     /* Vertex Shader states. */
     index += _State(Context, index, 0x00804 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
     index += _State(Context, index, 0x00808 >> 2, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -2973,6 +3308,12 @@ if (halti5){    vsConstBase  = 0xD000;
         index += _State(Context, index, 0x00820 >> 2, 0x00000000, 4, gcvFALSE, gcvFALSE);
     }
 
+    if (multiCluster)
+    {
+        index += _State(Context, index, 0x007FC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x15608 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+    }
+
     index += _CLOSE_RANGE();
 
     /* GS */
@@ -2995,7 +3336,6 @@ if (halti5){    vsConstBase  = 0xD000;
     }
 
     /* TCS & TES */
-
     if (hasTS)
     {
         index += _State(Context, index, 0x007C0 >> 2, 0x00000003, 1, gcvFALSE, gcvFALSE);
@@ -3078,6 +3418,11 @@ if (halti5){    vsConstBase  = 0xD000;
         index += _State(Context, index, 0x00A40 >> 2, 0x00000000, Context->hardware->identity.varyingsCount, gcvFALSE, gcvFALSE);
     }
 
+    if (multiCluster)
+    {
+        index += _State(Context, index, 0x00AAC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+    }
+
     index += _State(Context, index, 0x03A00 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
     index += _State(Context, index, 0x03A04 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
     index += _State(Context, index, 0x03A08 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
@@ -3105,7 +3450,18 @@ if (halti5){    vsConstBase  = 0xD000;
     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, 0x17000031, 1, gcvFALSE, gcvFALSE);
+    index += _State(Context, index, 0x00E08 >> 2, ((((gctUINT32) (0x17000031)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) ((gctUINT32) (smallBatch ?
+ 0x0 : 0x1) & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))), 1, gcvFALSE, gcvFALSE);
     index += _State(Context, index, 0x00E24 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
     index += _State(Context, index, 0x00E20 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
 
@@ -3133,15 +3489,22 @@ if (halti5){    vsConstBase  = 0xD000;
         index += _State(Context, index, 0x01040 >> 2, 0x00000000, 2, gcvFALSE, gcvFALSE);
     }
 
-    if (numRT == 8)
+    if (numRT == 16)
+    {
+        index += _State(Context, index, 0x0102C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x010C8 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x010CC >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+    }
+    else if (numRT == 8)
     {
         index += _State(Context, index, 0x0102C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
         index += _State(Context, index, 0x01038 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
     }
 
-    if (halti4)
+    if (hasMsaaFragOperation)
     {
         index += _State(Context, index, 0x01054 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x01060 >> 2, 0x00000000, 8, gcvFALSE, gcvFALSE);
     }
 
     if (halti5)
@@ -3151,6 +3514,10 @@ if (halti5){    vsConstBase  = 0xD000;
         index += _State(Context, index, 0x01098 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
     }
 
+    if (hasPSCSThrottle)
+    {
+        index += _State(Context, index, 0x0109C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
+    }
 
     index += _CLOSE_RANGE();
 
@@ -3160,24 +3527,43 @@ if (halti5){    vsConstBase  = 0xD000;
         /* Texture descriptor states */
         index += _State(Context, index, 0x14C40 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
 
-        index += _State(Context, index, 0x16C00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
-        index += _State(Context, index, 0x16E00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
-        index += _State(Context, index, 0x17000 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
-        index += _State(Context, index, 0x17200 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
-        index += _State(Context, index, 0x17400 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+        if (smallBatch)
+        {
+            index += _State(Context, index, 0x010B0 >> 2, numSamplers, 1, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x010B4 >> 2, numSamplers, 1, gcvFALSE, gcvFALSE);
 
-        index += _State(Context, index, (0x15C00 >> 2) + (0 << 0), 0x00000000, numSamplers, gcvFALSE, gcvTRUE);
-        index += _State(Context, index, 0x15E00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x16000 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x16200 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x16400 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x16600 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x16800 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
 
-        index += _CLOSE_RANGE();
+            index += _State(Context, index, (0x15800 >> 2) + (0 << 0), 0x00000000, numSamplers, gcvFALSE, gcvTRUE);
+            index += _State(Context, index, 0x15A00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+
+            index += _CLOSE_RANGE();
+        }
+        else
+        {
+            index += _State(Context, index, 0x16C00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x16E00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x17000 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x17200 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+            index += _State(Context, index, 0x17400 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
 
-        _StateMirror(Context, 0x16000 >> 2, numSamplers , 0x16C00 >> 2);
-        _StateMirror(Context, 0x16200 >> 2, numSamplers , 0x16E00 >> 2);
-        _StateMirror(Context, 0x16400 >> 2, numSamplers , 0x17000 >> 2);
-        _StateMirror(Context, 0x16600 >> 2, numSamplers , 0x17200 >> 2);
-        _StateMirror(Context, 0x16800 >> 2, numSamplers , 0x17400 >> 2);
-        _StateMirror(Context, 0x15800 >> 2, numSamplers , 0x15C00 >> 2);
-        _StateMirror(Context, 0x15A00 >> 2, numSamplers , 0x15E00 >> 2);
+            index += _State(Context, index, (0x15C00 >> 2) + (0 << 0), 0x00000000, numSamplers, gcvFALSE, gcvTRUE);
+            index += _State(Context, index, 0x15E00 >> 2, 0x00000000, numSamplers, gcvFALSE, gcvFALSE);
+
+            index += _CLOSE_RANGE();
+
+            _StateMirror(Context, 0x16000 >> 2, numSamplers , 0x16C00 >> 2);
+            _StateMirror(Context, 0x16200 >> 2, numSamplers , 0x16E00 >> 2);
+            _StateMirror(Context, 0x16400 >> 2, numSamplers , 0x17000 >> 2);
+            _StateMirror(Context, 0x16600 >> 2, numSamplers , 0x17200 >> 2);
+            _StateMirror(Context, 0x16800 >> 2, numSamplers , 0x17400 >> 2);
+            _StateMirror(Context, 0x15800 >> 2, numSamplers , 0x15C00 >> 2);
+            _StateMirror(Context, 0x15A00 >> 2, numSamplers , 0x15E00 >> 2);
+        }
     }
     else
     {
@@ -3221,7 +3607,7 @@ if (halti5){    vsConstBase  = 0xD000;
             }
         }
 
-        if (halti1)
+        if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_SUPPORT_GCREGTX))
         {
             gctUINT texBlockCount;
             gctUINT gcregTXLogSizeResetValue;
@@ -3427,6 +3813,11 @@ if (halti5){    vsConstBase  = 0xD000;
         index += _State(Context, index, 0x00864 >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
         index += _CLOSE_RANGE();
 
+        if (smallBatch)
+        {
+            index += _State(Context, index, 0x010AC >> 2, numConstants, 1, gcvFALSE, gcvFALSE);
+        }
+
         for (i = 0;
              numConstants > 0;
              i += 256 << 2,
@@ -3437,11 +3828,25 @@ if (halti5){    vsConstBase  = 0xD000;
             {
                 if (numConstants >= 256)
                 {
-                    index += _State(Context, index, (0x36000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+                    if (smallBatch)
+                    {
+                        index += _State(Context, index, (0x34000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+                    }
+                    else
+                    {
+                        index += _State(Context, index, (0x36000 >> 2) + i, 0x00000000, 256 << 2, gcvFALSE, gcvFALSE);
+                    }
                 }
                 else
                 {
-                    index += _State(Context, index, (0x36000 >> 2) + i, 0x00000000, numConstants << 2, gcvFALSE, gcvFALSE);
+                    if (smallBatch)
+                    {
+                        index += _State(Context, index, (0x34000 >> 2) + i, 0x00000000, numConstants << 2, gcvFALSE, gcvFALSE);
+                    }
+                    else
+                    {
+                        index += _State(Context, index, (0x36000 >> 2) + i, 0x00000000, numConstants << 2, gcvFALSE, gcvFALSE);
+                    }
                 }
                 index += _CLOSE_RANGE();
             }
@@ -3460,7 +3865,7 @@ if (halti5){    vsConstBase  = 0xD000;
             }
         }
 
-        if (halti5)
+        if (halti5 && !smallBatch)
         {
             _StateMirror(Context, 0x34000 >> 2, Context->hardware->identity.numConstants << 2 , 0x36000 >> 2);
         }
@@ -3538,7 +3943,16 @@ if (halti5){    vsConstBase  = 0xD000;
         index += _State(Context, index, (0x01500 >> 2) + (i << 3), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
     }
 
-    if (numRT == 8)
+    if (numRT == 16)
+    {
+        for (i = 0; i < 15; i++)
+        {
+            index += _State(Context, index, (0x17C00 >> 2) + (i << 0), 0x00000000, Context->hardware->identity.pixelPipes, gcvFALSE, gcvTRUE);
+        }
+        index += _State(Context, index, 0x17C40 >> 2, 0x00000000, 15, gcvFALSE, gcvFALSE);
+        index += _State(Context, index, 0x17C80 >> 2, 0x03012000, 15, gcvFALSE, gcvFALSE);
+    }
+    else if (numRT == 8)
     {
         for (i = 0; i < 7; i++)
         {
@@ -3781,26 +4195,29 @@ _DestroyContext(
             /* Free state delta map. */
             if (buffer->logical != gcvNULL)
             {
-                if (Context->hardware->kernel->virtualCommandBuffer)
-                {
-                    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
-                        ));
-                }
+                gckKERNEL kernel = Context->hardware->kernel;
+
+                /* End cpu access. */
+                gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+                    kernel,
+                    buffer->videoMem,
+                    0,
+                    gcvFALSE
+                    ));
+
+                /* Synchronized unlock. */
+                gcmkVERIFY_OK(gckVIDMEM_NODE_Unlock(
+                    kernel,
+                    buffer->videoMem,
+                    0,
+                    gcvNULL
+                    ));
+
+                /* Free video memory. */
+                gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+                    kernel,
+                    buffer->videoMem
+                    ));
 
                 buffer->logical = gcvNULL;
             }
@@ -3812,14 +4229,6 @@ _DestroyContext(
             Context->buffer = next;
         }
 
-#if gcdSECURE_USER
-        /* Free the hint array. */
-        if (Context->hint != gcvNULL)
-        {
-            gcmkONERROR(gcmkOS_SAFE_FREE(Context->os, Context->hint));
-        }
-#endif
-
         /* Mark the gckCONTEXT object as unknown. */
         Context->object.type = gcvOBJ_UNKNOWN;
 
@@ -3839,56 +4248,41 @@ _AllocateContextBuffer(
     )
 {
     gceSTATUS status;
-    gctPOINTER pointer;
-    gctUINT32 address;
+    gckKERNEL kernel = Context->hardware->kernel;
+    gcePOOL pool = gcvPOOL_DEFAULT;
     gctSIZE_T totalSize = Context->totalSize;
-
-    if (Context->hardware->kernel->virtualCommandBuffer)
-    {
-        gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
-            Context->hardware->kernel,
-            gcvFALSE,
-            &totalSize,
-            &Buffer->physical,
-            &pointer
-            ));
-
-        gcmkONERROR(gckKERNEL_GetGPUAddress(
-            Context->hardware->kernel,
-            pointer,
-            gcvFALSE,
-            Buffer->physical,
-            &address
-            ));
-    }
-    else
-    {
-        gctUINT32 allocFlag;
+    gctUINT32 allocFlag = 0;
 
 #if gcdENABLE_CACHEABLE_COMMAND_BUFFER
-        allocFlag = gcvALLOC_FLAG_CACHEABLE | gcvALLOC_FLAG_CONTIGUOUS;
-#else
-        allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+    allocFlag = gcvALLOC_FLAG_CACHEABLE;
 #endif
-        gcmkONERROR(gckOS_AllocateNonPagedMemory(
-            Context->os,
-            gcvFALSE,
-            allocFlag,
-            &totalSize,
-            &Buffer->physical,
-            &pointer
-            ));
 
-        gcmkONERROR(gckHARDWARE_ConvertLogical(
-            Context->hardware,
-            pointer,
-            gcvFALSE,
-            &address
-            ));
-    }
+    /* Allocate video memory node for command buffers. */
+    gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+        kernel,
+        64,
+        gcvVIDMEM_TYPE_COMMAND,
+        allocFlag,
+        &totalSize,
+        &pool,
+        &Buffer->videoMem
+        ));
 
-    Buffer->logical = pointer;
-    Buffer->address = address;
+    /* Lock for GPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_Lock(
+        kernel,
+        Buffer->videoMem,
+        &Buffer->address
+        ));
+
+    /* Lock for kernel side CPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+        kernel,
+        Buffer->videoMem,
+        gcvFALSE,
+        gcvFALSE,
+        (gctPOINTER *)&Buffer->logical
+        ));
 
     return gcvSTATUS_OK;
 
@@ -3939,7 +4333,7 @@ gckCONTEXT_Construct(
     gctUINT i;
     gctPOINTER pointer = gcvNULL;
 
-    gcmkHEADER_ARG("Os=0x%08X Hardware=0x%08X", Os, Hardware);
+    gcmkHEADER_ARG("Os=%p Hardware=%p", Os, Hardware);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -4022,20 +4416,6 @@ gckCONTEXT_Construct(
         {
             context->map = context->hardware->kernel->command->stateMap;
         }
-
-        /**************************************************************************/
-        /* Allocate the hint array. ***********************************************/
-
-#if gcdSECURE_USER
-        /* Allocate hints. */
-        gcmkONERROR(gckOS_Allocate(
-            Os,
-            gcmSIZEOF(gctBOOL) * context->maxState,
-            &pointer
-            ));
-
-        context->hint = pointer;
-#endif
     }
 
     /**************************************************************************/
@@ -4126,12 +4506,12 @@ gckCONTEXT_Construct(
                 - context->entryOffsetXDFrom3D;
 
             /* Query LINK size. */
-            gcmkONERROR(gckHARDWARE_Link(
+            gcmkONERROR(gckWLFE_Link(
                 Hardware, gcvNULL, 0, 0, &linkBytes, gcvNULL, gcvNULL
                 ));
 
             /* Generate a LINK. */
-            gcmkONERROR(gckHARDWARE_Link(
+            gcmkONERROR(gckWLFE_Link(
                 Hardware,
                 xdLink,
                 xdEntryAddress,
@@ -4219,7 +4599,7 @@ gckCONTEXT_Destroy(
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Context=0x%08X", Context);
+    gcmkHEADER_ARG("Context=%p", Context);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
@@ -4267,6 +4647,7 @@ gckCONTEXT_Update(
     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;
@@ -4279,12 +4660,8 @@ gckCONTEXT_Update(
     gctUINT i, j;
     gctUINT32 dirtyRecordArraySize = 0;
 
-#if gcdSECURE_USER
-    gcskSECURE_CACHE_PTR cache;
-#endif
-
     gcmkHEADER_ARG(
-        "Context=0x%08X ProcessID=%d StateDelta=0x%08X",
+        "Context=%p ProcessID=%d StateDelta=%p",
         Context, ProcessID, StateDelta
         );
 
@@ -4306,29 +4683,26 @@ gckCONTEXT_Update(
         Context->os, buffer->signal, gcvFALSE, gcvINFINITE
         ));
 
-#if gcdSECURE_USER
-    /* Get the cache form the database. */
-    gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
-#endif
-
 #if gcmIS_DEBUG(gcdDEBUG_CODE) && 1 && gcdENABLE_3D
     /* Update current context token. */
     buffer->logical[Context->map[0x0E14].index]
         = (gctUINT32)gcmPTR2INT32(Context);
 #endif
 
-    if (StateDelta != gcvNULL)
+    /* Are there any pending deltas? */
+    if (buffer->deltaCount != 0)
     {
         /* Get the state map. */
         map = Context->map;
 
         /* Get the first delta item. */
-        uDelta = StateDelta;
+        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(
@@ -4433,17 +4807,6 @@ gckCONTEXT_Update(
  ~0U : (~(~0U << ((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;
                 }
@@ -4463,6 +4826,13 @@ gckCONTEXT_Update(
                 elementCount = kDelta->elementCount;
             }
 
+            /* Dereference delta. */
+            kDelta->refCount -= 1;
+            gcmkASSERT(kDelta->refCount >= 0);
+
+            /* Get the next state delta. */
+            nDelta = gcmUINT64_TO_PTR(kDelta->next);
+
             if (dirtyRecordArraySize)
             {
                 /* Get access to the state records. */
@@ -4483,6 +4853,9 @@ gckCONTEXT_Update(
                 uDelta, gcmSIZEOF(gcsSTATE_DELTA),
                 (gctPOINTER *) &kDelta
                 ));
+
+            /* Update the user delta pointer. */
+            uDelta = nDelta;
         }
 
         /* Hardware disables all input attribute when the attribute 0 is programmed,
@@ -4684,8 +5057,107 @@ gckCONTEXT_Update(
                 nop += 2;
             }
         }
+
+        if (gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_SMALL_BATCH) &&
+            Context->hardware->options.smallBatch)
+        {
+            gctUINT numConstant = (gctUINT)Context->hardware->identity.numConstants;
+            gctUINT32 constCount = 0;
+
+            /* Get the const number after merge. */
+            index = map[0x042B].index;
+            data = buffer->logical[index];
+            constCount = (((((gctUINT32) (data)) >> (0 ? 8:0)) & ((gctUINT32) ((((1 ? 8:0) - (0 ? 8:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 8:0) - (0 ? 8:0) + 1)))))) );
+
+            _UpdateUnifiedReg(Context, 0xD000, numConstant << 2, constCount << 2);
+        }
+
+        if (gckHARDWARE_IsFeatureAvailable(Context->hardware, gcvFEATURE_SMALL_BATCH) &&
+            Context->hardware->options.smallBatch)
+        {
+            gctUINT numSamplers = 80;
+            gctUINT32 samplerCount = 0;
+
+            /* Get the sampler number after merge. */
+            index = map[0x042C].index;
+            data = buffer->logical[index];
+            samplerCount = (((((gctUINT32) (data)) >> (0 ? 6:0)) & ((gctUINT32) ((((1 ? 6:0) - (0 ? 6:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 6:0) - (0 ? 6:0) + 1)))))) );
+
+            _UpdateUnifiedReg(Context, 0x5800, numSamplers, samplerCount);
+            _UpdateUnifiedReg(Context, 0x5880, numSamplers, samplerCount);
+            _UpdateUnifiedReg(Context, 0x5900, numSamplers, samplerCount);
+            _UpdateUnifiedReg(Context, 0x5980, numSamplers, samplerCount);
+            _UpdateUnifiedReg(Context, 0x5A00, numSamplers, samplerCount);
+            _UpdateUnifiedReg(Context, 0x5600, numSamplers, samplerCount);
+            _UpdateUnifiedReg(Context, 0x5680, numSamplers, samplerCount);
+        }
+        /* Reset pending deltas. */
+        buffer->deltaCount = 0;
+        buffer->delta      = gcvNULL;
     }
 
+    if (StateDelta)
+    {
+        /* 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
@@ -4729,56 +5201,32 @@ OnError:
 gceSTATUS
 gckCONTEXT_MapBuffer(
     IN gckCONTEXT Context,
-    OUT gctUINT32 *Physicals,
     OUT gctUINT64 *Logicals,
     OUT gctUINT32 *Bytes
     )
 {
     gceSTATUS status;
     int i = 0;
-    gctSIZE_T pageCount;
-    gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer;
     gckKERNEL kernel = Context->hardware->kernel;
     gctPOINTER logical;
-    gctPHYS_ADDR physical;
-
     gcsCONTEXT_PTR buffer;
 
-    gcmkHEADER();
-
-    gcmkVERIFY_OBJECT(Context, gcvOBJ_CONTEXT);
+    gcmkHEADER_ARG("Context=%p", Context);
 
     buffer = Context->buffer;
 
     for (i = 0; i < gcdCONTEXT_BUFFER_COUNT; i++)
     {
-        if (kernel->virtualCommandBuffer)
-        {
-            commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)buffer->physical;
-            physical = commandBuffer->virtualBuffer.physical;
-
-            gcmkONERROR(gckOS_CreateUserVirtualMapping(
-                kernel->os,
-                physical,
-                Context->totalSize,
-                &logical,
-                &pageCount));
-        }
-        else
-        {
-            physical = buffer->physical;
-
-            gcmkONERROR(gckOS_MapMemory(
-                kernel->os,
-                physical,
-                Context->totalSize,
-                &logical));
-        }
-
-        Physicals[i] = gcmPTR_TO_NAME(physical);
+        /* Lock for userspace CPU access. */
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+            kernel,
+            buffer->videoMem,
+            gcvFALSE,
+            gcvTRUE,
+            &logical
+            ));
 
         Logicals[i] = gcmPTR_TO_UINT64(logical);
-
         buffer = buffer->next;
     }
 
index d92b1e3..11d94d7 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -87,8 +87,8 @@ typedef struct _gcsCONTEXT
     /* Context busy signal. */
     gctSIGNAL                   signal;
 
-    /* Physical address of the context buffer. */
-    gctPHYS_ADDR                physical;
+    /* Video memory of the context buffer. */
+    gckVIDMEM_NODE              videoMem;
 
     /* Logical address of the context buffer. */
     gctUINT32_PTR               logical;
@@ -100,6 +100,12 @@ typedef struct _gcsCONTEXT
     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;
 }
@@ -167,11 +173,6 @@ struct _gckCONTEXT
 
     gctUINT32                   pipeSelectBytes;
 
-    /* Hint array. */
-#if gcdSECURE_USER
-    gctBOOL_PTR                 hint;
-#endif
-
     gcsPROFILER_COUNTERS_PART1    latestProfiler_part1;
     gcsPROFILER_COUNTERS_PART1    histroyProfiler_part1;
     gcsPROFILER_COUNTERS_PART1    preProfiler_part1;
index 7778da4..214e328 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -58,6 +58,7 @@
 #include "gc_hal_kernel_context.h"
 
 #include "gc_feature_database.h"
+#include <gc_hal_kernel_debug.h>
 
 #define _GC_OBJ_ZONE    gcvZONE_HARDWARE
 
@@ -93,6 +94,8 @@ typedef struct _gcsiDEBUG_REGISTERS
     gctUINT         count;
     gctUINT32       pipeMask;
     gctUINT32       selectStart;
+    gctBOOL         avail;
+    gctBOOL         inCluster;
 }
 gcsiDEBUG_REGISTERS;
 
@@ -158,6 +161,7 @@ static gceSTATUS
 _IdentifyHardwareByDatabase(
     IN gckHARDWARE Hardware,
     IN gckOS Os,
+    IN gckDEVICE Device,
     IN gceCORE Core,
     OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity
     )
@@ -167,6 +171,7 @@ _IdentifyHardwareByDatabase(
     gctUINT32 debugControl0;
     gctUINT32 chipInfo;
     gcsFEATURE_DATABASE *database;
+    gctUINT i = 0;
 
     gcmkHEADER_ARG("Os=0x%x", Os);
 
@@ -265,6 +270,41 @@ _IdentifyHardwareByDatabase(
                                 0x00030,
                                 &Identity->customerID));
 
+     /*get hw minor features*/
+    gcmkONERROR(
+        gckOS_ReadRegisterEx(Os, Core,
+                                0x0001C,
+                                &Identity->chipFeatures));
+
+    gcmkONERROR(
+        gckOS_ReadRegisterEx(Os, Core,
+                                0x00034,
+                                &Identity->chipMinorFeatures));
+    gcmkONERROR(
+        gckOS_ReadRegisterEx(Os, Core,
+                                0x00074,
+                                &Identity->chipMinorFeatures1));
+    gcmkONERROR(
+        gckOS_ReadRegisterEx(Os, Core,
+                                0x00084,
+                                &Identity->chipMinorFeatures2));
+    gcmkONERROR(
+        gckOS_ReadRegisterEx(Os, Core,
+                                0x00088,
+                                &Identity->chipMinorFeatures3));
+    gcmkONERROR(
+        gckOS_ReadRegisterEx(Os, Core,
+                                0x00094,
+                                &Identity->chipMinorFeatures4));
+    gcmkONERROR(
+        gckOS_ReadRegisterEx(Os, Core,
+                                0x000A0,
+                                &Identity->chipMinorFeatures5));
+    gcmkONERROR(
+        gckOS_ReadRegisterEx(Os, Core,
+                                0x000DC,
+                                &Identity->chipMinorFeatures6));
+
     /***************************************************************************
     ** Get chip features.
     */
@@ -290,13 +330,62 @@ _IdentifyHardwareByDatabase(
         gcmkONERROR(gcvSTATUS_NOT_FOUND);
     }
 
-    Identity->pixelPipes             = database->NumPixelPipes;
-    Identity->resolvePipes           = database->NumResolvePipes;
-    Identity->instructionCount       = database->InstructionCount;
-    Identity->numConstants           = database->NumberOfConstants;
-    Identity->varyingsCount          = database->VaryingCount;
-    Identity->gpuCoreCount           = database->CoreCount;
-    Identity->streamCount            = database->Streams;
+
+    Identity->pixelPipes                    = database->NumPixelPipes;
+    Identity->resolvePipes                  = database->NumResolvePipes;
+    Identity->instructionCount              = database->InstructionCount;
+    Identity->numConstants                  = database->NumberOfConstants;
+    Identity->varyingsCount                 = database->VaryingCount;
+    Identity->gpuCoreCount                  = database->CoreCount;
+    Identity->streamCount                   = database->Streams;
+    Identity->clusterAvailMask              = database->ClusterAliveMask;
+
+    gckOS_QueryOption(Hardware->os, "sRAMMode", (gctUINT64 *)&Hardware->sRAMNonExclusive);
+
+    if (gcmIS_SUCCESS(gckOS_QueryOption(Hardware->os, "sRAMBases", Device->sRAMBases[0])))
+    {
+        gckOS_MemCopy(
+            Identity->sRAMBases,
+            Device->sRAMBases[Core],
+            sizeof(gctUINT64) * gcvSRAM_COUNT
+            );
+    }
+    else
+    {
+        for (i = 0; i < gcvSRAM_COUNT; i++)
+        {
+            Identity->sRAMBases[i] = gcvINVALID_PHYSICAL_ADDRESS;
+        }
+    }
+
+    if (gcmIS_SUCCESS(gckOS_QueryOption(Hardware->os, "sRAMSizes", (gctUINT64 *)Device->sRAMSizes[0])))
+    {
+        gckOS_MemCopy(
+            Identity->sRAMSizes,
+            Device->sRAMSizes[Core],
+            sizeof(gctUINT32) * gcvSRAM_COUNT
+            );
+    }
+
+    for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_COUNT; i++)
+    {
+        if (Identity->sRAMSizes[i])
+        {
+            break;
+        }
+    }
+
+    /* If module parameter doesn't set SRAM sizes. */
+    if (i == gcvSRAM_COUNT)
+    {
+        /* Set default mode to exclusive mode. */
+        Hardware->sRAMNonExclusive = gcvFALSE;
+
+        /* Try to get SRAM sizes from database. */
+        /* Need this path for VIP exclusive mode. */
+        Device->sRAMSizes[Core][gcvSRAM_INTERNAL] = Identity->sRAMSizes[gcvSRAM_INTERNAL] = database->VIP_SRAM_SIZE;
+        Device->sRAMSizes[Core][gcvSRAM_EXTERNAL0] = Identity->sRAMSizes[gcvSRAM_EXTERNAL0] = database->AXI_SRAM_SIZE;
+    }
 
     if (Identity->chipModel == gcv320)
     {
@@ -766,17 +855,15 @@ _ConfigureModuleLevelClockGating(
 }
 #endif
 
-#if gcdPOWEROFF_TIMEOUT
-void
-_PowerTimerFunction(
+static void
+_PowerStateTimerFunc(
     gctPOINTER Data
     )
 {
     gckHARDWARE hardware = (gckHARDWARE)Data;
-    gcmkVERIFY_OK(
-        gckHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
+
+    gckHARDWARE_SetPowerState(hardware, hardware->nextPowerState);
 }
-#endif
 
 static gceSTATUS
 _VerifyDMA(
@@ -836,10 +923,14 @@ _DumpDebugRegisters(
     gcmkHEADER_ARG("Os=0x%X Descriptor=0x%X", Os, Descriptor);
 
     /* Record control. */
-    gckOS_ReadRegisterEx(Os, Core, 0x0, &oldControl);
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x0, &oldControl));
 
-    for (pipe = 0; pipe < 2; pipe++)
+    for (pipe = 0; pipe < 4; pipe++)
     {
+        if (!Descriptor->avail)
+        {
+            continue;
+        }
         if (!(Descriptor->pipeMask & (1 << pipe)))
         {
             continue;
@@ -965,21 +1056,21 @@ _DumpFEStack(
 
         for (j = 0; j < _feStacks[i].count; j++)
         {
-            gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].highSelect);
+            gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].highSelect));
 
-            gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &stack[j][0]);
+            gcmkVERIFY_OK(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &stack[j][0]));
 
-            gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].lowSelect);
+            gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].lowSelect));
 
-            gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &stack[j][1]);
+            gcmkVERIFY_OK(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &stack[j][1]));
 
-            gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].next);
+            gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].next));
 
             if (_feStacks[i].linkSelect)
             {
-                gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].linkSelect);
+                gcmkVERIFY_OK(gckOS_WriteRegisterEx(Os, Core, Descriptor->index, _feStacks[i].linkSelect));
 
-                gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &link[j]);
+                gcmkVERIFY_OK(gckOS_ReadRegisterEx(Os, Core, Descriptor->data, &link[j]));
             }
         }
 
@@ -1085,7 +1176,7 @@ OnError:
     return status;
 }
 
-gceSTATUS
+static gceSTATUS
 _FlushCache(
     gckHARDWARE Hardware,
     gckCOMMAND Command
@@ -1129,7 +1220,7 @@ _IsGPUIdle(
     return Idle == 0x7FFFFFFF;
 }
 
-gctBOOL
+static gctBOOL
 _QueryFeatureDatabase(
     IN gckHARDWARE Hardware,
     IN gceFEATURE Feature
@@ -1422,6 +1513,10 @@ _QueryFeatureDatabase(
         available = database->RA_CG_FIX;
         break;
 
+    case gcvFEATURE_MULTI_CLUSTER:
+        available = database->MULTI_CLUSTER;
+        break;
+
     case gcvFEATURE_ZERO_ATTRIB_SUPPORT:
         available = database->REG_Halti4;
         break;
@@ -1431,7 +1526,7 @@ _QueryFeatureDatabase(
         break;
 
     case gcvFEATURE_GPIPE_CLOCK_GATE_FIX:
-        available = gcvTRUE;
+        available = gcvFALSE;
         break;
 
     case gcvFEATURE_NEW_GPIPE:
@@ -1446,10 +1541,26 @@ _QueryFeatureDatabase(
         available = database->SECURITY_AHB;
         break;
 
+    case gcvFEATURE_SMALL_BATCH:
+        available = database->SMALLBATCH;
+        break;
+
     case gcvFEATURE_ASYNC_BLIT:
         available = database->ASYNC_BLT;
         break;
 
+    case gcvFEATURE_PSCS_THROTTLE:
+        available = database->PSCS_THROTTLE;
+        break;
+
+    case gcvFEATURE_SEPARATE_LS:
+        available = database->SEPARATE_LS;
+        break;
+
+    case gcvFEATURE_MCFE:
+        available = database->MCFE;
+        break;
+
     case gcvFEATURE_COMPUTE_ONLY:
         available = database->COMPUTE_ONLY;
         break;
@@ -1470,6 +1581,36 @@ _QueryFeatureDatabase(
         available = database->DEC400;
         break;
 
+    case gcvFEATURE_SUPPORT_GCREGTX:
+        available = database->REG_Halti1;
+
+        if (Hardware->identity.chipModel == gcv880 &&
+            ((Hardware->identity.chipRevision & 0xfff0) == 0x5120))
+        {
+            available = gcvTRUE;
+        }
+        break;
+
+    case gcvFEATURE_MSAA_FRAGMENT_OPERATION:
+        available = database->MSAA_FRAGMENT_OPERATION;
+        break;
+
+    case gcvFEATURE_OCB_COUNTER:
+        available = database->OCB_COUNTER;
+        break;
+
+    case gcvFEATURE_NN_ENGINE:
+        available = database->NNCoreCount > 0;
+        break;
+
+    case gcvFEATURE_TP_ENGINE:
+        available = database->TP_ENGINE;
+        break;
+
+    case gcvFEATURE_HI_REORDER_FIX:
+        available = database->HI_REORDER_FIX;
+        break;
+
     default:
         gcmkFATAL("Invalid feature has been requested.");
         available = gcvFALSE;
@@ -1495,7 +1636,7 @@ _ConfigurePolicyID(
     gctUINT32 shift;
     gctUINT32 currentAxiConfig;
 
-    status = gckOS_GetPolicyID(os, gcvSURF_TYPE_UNKNOWN, &policyID, &axiConfig);
+    status = gckOS_GetPolicyID(os, gcvVIDMEM_TYPE_GENERIC, &policyID, &axiConfig);
 
     if (status == gcvSTATUS_NOT_SUPPORTED)
     {
@@ -1506,7 +1647,7 @@ _ConfigurePolicyID(
     for (i = 0; i < 16; i++)
     {
         /* Mapping 16 surface type.*/
-        status = gckOS_GetPolicyID(os, (gceSURF_TYPE) i, &policyID, &axiConfig);
+        status = gckOS_GetPolicyID(os, (gceVIDMEM_TYPE) i, &policyID, &axiConfig);
 
         if (gcmIS_SUCCESS(status))
         {
@@ -1587,111 +1728,117 @@ _SetHardwareOptions(
     )
 {
     gceSTATUS status;
+    gctUINT i;
+    gctUINT64 data = 0;
     gcsHAL_QUERY_CHIP_OPTIONS *options = &Hardware->options;
+    gcsFEATURE_DATABASE *database = Hardware->featureDatabase;
+    gctBOOL featureUSC = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC) ? gcvTRUE : gcvFALSE;
+    gctBOOL featureSeparateLS = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SEPARATE_LS) ? gcvTRUE : gcvFALSE;
+    gctBOOL featureComputeOnly = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_COMPUTE_ONLY) ? gcvTRUE : gcvFALSE;
+    gctBOOL featureTS = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TESSELLATION) ? gcvTRUE : gcvFALSE;
+    gctUINT32 featureL1CacheSize = database->L1CacheSize;
+    gctUINT32 featureUSCMaxPages = database->USC_MAX_PAGES;
+    gctBOOL featureGS = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_GEOMETRY_SHADER) ? gcvTRUE : gcvFALSE;
+    gctBOOL featureUSCFullCacheFix = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC_FULLCACHE_FIX) ? gcvTRUE : gcvFALSE;
 
-    status = gckOS_QueryOption(Hardware->os, "powerManagement", (gctUINT32*)&options->powerManagement);
+
+    status = gckOS_QueryOption(Hardware->os, "powerManagement", &data);
+    options->powerManagement = (data != 0);
 
     if (status == gcvSTATUS_NOT_SUPPORTED)
     {
         /* Enable power management by default. */
-        Hardware->options.powerManagement = gcvTRUE;
+        options->powerManagement = gcvTRUE;
     }
 
     /* Disable profiler by default */
-    status = gckOS_QueryOption(Hardware->os, "gpuProfiler", (gctUINT32*)&options->gpuProfiler);
+    status = gckOS_QueryOption(Hardware->os, "gpuProfiler", &data);
+    options->gpuProfiler = (data != 0);
+
     if (status == gcvSTATUS_NOT_SUPPORTED)
     {
         /* Disable profiler by default */
-        Hardware->options.gpuProfiler= gcvFALSE;
+        options->gpuProfiler= gcvFALSE;
     }
-    gckOS_QueryOption(Hardware->os, "mmu", (gctUINT32_PTR)&options->enableMMU);
 
-    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC))
+    status = gckOS_QueryOption(Hardware->os, "mmu", &data);
+    options->enableMMU = (data != 0);
+
+    if (status == gcvSTATUS_NOT_SUPPORTED)
     {
-        gctUINT L1cacheSize;
-        gcsFEATURE_DATABASE *database = Hardware->featureDatabase;
+        /* Disable MMU if we can't get result from OS layer query */
+        options->enableMMU = gcvFALSE;
+    }
+
+    {    Hardware->options.uscAttribCacheRatio = 0x2;
+       if (featureUSC)    {        if (featureSeparateLS)        {            Hardware->options.uscL1CacheRatio = 0x0;
+        }        else        {            gctUINT L1cacheSize;
+                       if (featureComputeOnly)            {                L1cacheSize = featureL1CacheSize;
+            }            else            {                gctUINT attribBufSizeInKB;
+                if (featureTS)                {                    gcmkASSERT(featureGS);
+                    featureGS = featureGS;
+                    attribBufSizeInKB = 42;
+                }                else                {                    gcmkASSERT(!featureGS);
+                    attribBufSizeInKB = 8;
+                }                L1cacheSize = featureUSCMaxPages - attribBufSizeInKB;
+            }            gcmkASSERT(L1cacheSize);
+            if (L1cacheSize >= featureL1CacheSize)            {                Hardware->options.uscL1CacheRatio = 0x0;
+                gcmkASSERT(featureUSCFullCacheFix);
+                featureUSCFullCacheFix = featureUSCFullCacheFix;
+            }            else            {                static const gctINT s_uscCacheRatio[] =                {                    100000,                    50000,                    25000,                    12500,                    62500,                    3125,                    75000,                    0,                };
+                gctINT maxL1cacheSize = L1cacheSize * 100000;
+                gctINT delta = 2147483647;
+                gctINT i = 0;
+                gctINT curIndex = -1;
+                for (;
+ i < gcmCOUNTOF(s_uscCacheRatio);
+ ++i)                {                    gctINT curL1cacheSize = featureL1CacheSize * s_uscCacheRatio[i];
+                                     if ((maxL1cacheSize >= curL1cacheSize) &&                        ((maxL1cacheSize - curL1cacheSize) < delta))                    {                        curIndex = i;
+                        delta = maxL1cacheSize - curL1cacheSize;
+                    }                }                gcmkASSERT(-1 != curIndex);
+                Hardware->options.uscL1CacheRatio = curIndex;
+            }        }    }};
+
+
+    status = gckOS_QueryOption(Hardware->os, "smallBatch", &data);
+    options->smallBatch = (data != 0);
 
-        if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_COMPUTE_ONLY))
-        {
-            L1cacheSize = database->L1CacheSize;
-        }
-        else
-        {
-            gctUINT attribBufSizeInKB;
-            if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TESSELLATION))
-            {
-                /* GS/TS must be bundled. */
-                gcmkASSERT(gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_GEOMETRY_SHADER));
-                attribBufSizeInKB = 42;
-            }
-            else
-            {
-                gcmkASSERT(!gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_GEOMETRY_SHADER));
-                attribBufSizeInKB = 8;
-            }
+    if (status == gcvSTATUS_NOT_SUPPORTED)
+    {
+        options->smallBatch = gcvTRUE;
+    }
 
-            if (attribBufSizeInKB < database->USC_MAX_PAGES)
-            {
-                L1cacheSize = database->USC_MAX_PAGES - attribBufSizeInKB;
-            }
-            else
-            {
-                attribBufSizeInKB -= 4;
-                L1cacheSize = 4;
-            }
-        }
-        gcmkASSERT(L1cacheSize);
-        if (L1cacheSize >= database->L1CacheSize)
-        {
-            Hardware->options.uscL1CacheRatio = 0x0;
-            gcmkASSERT(gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC_FULLCACHE_FIX));
-        }
-        else
-        {
-            static const gctINT s_uscCacheRatio[] =
-            {
-                100000,/* 1.0f */
-                50000, /* 0.5f */
-                25000, /* 0.25f */
-                12500, /* 0.125f */
-                62500, /* 0.0625f */
-                3125, /* 0.03125f */
-                75000, /* 0.75f */
-                0, /*0.0f */
-            };
-            gctINT maxL1cacheSize = L1cacheSize * 100000;
-            gctINT delta = 2147483647; /* start with very big delta */
-            gctINT i = 0;
-            gctINT curIndex = -1;
-            for (; i < gcmCOUNTOF(s_uscCacheRatio); ++i)
-            {
-                gctINT curL1cacheSize = database->L1CacheSize * s_uscCacheRatio[i];
+    status = gckOS_QueryOption(Hardware->os, "userClusterMask", &data);
+    options->userClusterMask = (gctUINT32)data;
 
-                if ((maxL1cacheSize >= curL1cacheSize) &&
-                    ((maxL1cacheSize - curL1cacheSize) < delta))
-                {
-                    curIndex = i;
-                    delta = maxL1cacheSize - curL1cacheSize;
-                }
-            }
-            gcmkASSERT(-1 != curIndex);
-            Hardware->options.uscL1CacheRatio = curIndex;
-        }
+    if (status == gcvSTATUS_NOT_SUPPORTED || (options->userClusterMask == 0))
+    {
+        /* use all clusters identified in database */
+        options->userClusterMask = Hardware->identity.clusterAvailMask;
+    }
+    else if (options->userClusterMask & (~Hardware->identity.clusterAvailMask))
+    {
+        gcmkPRINT("%s(%d): user cluster mask(0x%x) must be a subset of available clusters(0x%x),ignored it!",
+                  __FUNCTION__, __LINE__, options->userClusterMask, Hardware->identity.clusterAvailMask);
+        options->userClusterMask= Hardware->identity.clusterAvailMask;
+    }
+
+    for (i = 0; i < gcvSRAM_COUNT; i++)
+    {
+        options->sRAMBaseAddress[i] = gcvINVALID_ADDRESS;
     }
 
     options->secureMode = gcvSECURE_NONE;
 
     if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY))
     {
-        gctUINT32 ta = 0;
-
         gcmkASSERT(gcvSTATUS_TRUE == gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY_AHB));
 
         options->secureMode = gcvSECURE_IN_NORMAL;
 
-        status = gckOS_QueryOption(Hardware->os, "TA", &ta);
+        status = gckOS_QueryOption(Hardware->os, "TA", &data);
 
-        if (gcmIS_SUCCESS(status) && ta)
+        if (gcmIS_SUCCESS(status) && data)
         {
             options->secureMode = gcvSECURE_IN_TA;
         }
@@ -1707,7 +1854,7 @@ _SetHardwareOptions(
 /*
 * State timer helper must be called with powerMutex held.
 */
-void
+static void
 gckSTATETIMER_Reset(
     IN gcsSTATETIMER * StateTimer,
     IN gctUINT64 Start
@@ -1729,7 +1876,8 @@ gckSTATETIMER_Reset(
     gckOS_ZeroMemory(StateTimer->elapse, gcmSIZEOF(StateTimer->elapse));
 }
 
-void
+
+static void
 gckSTATETIMER_Accumulate(
     IN gcsSTATETIMER * StateTimer,
     IN gceCHIPPOWERSTATE OldState
@@ -1747,30 +1895,156 @@ gckSTATETIMER_Accumulate(
     StateTimer->elapse[OldState] += elapse;
 }
 
-void
+static void
 gckSTATETIMER_Query(
     IN gcsSTATETIMER * StateTimer,
     IN gceCHIPPOWERSTATE State,
-    OUT gctUINT64_PTR Start,
-    OUT gctUINT64_PTR End,
     OUT gctUINT64_PTR On,
     OUT gctUINT64_PTR Off,
     OUT gctUINT64_PTR Idle,
     OUT gctUINT64_PTR Suspend
     )
 {
-    *Start = StateTimer->start;
-
     gckSTATETIMER_Accumulate(StateTimer, State);
 
-    *End = StateTimer->recent;
-
     *On      = StateTimer->elapse[gcvPOWER_ON];
     *Off     = StateTimer->elapse[gcvPOWER_OFF];
     *Idle    = StateTimer->elapse[gcvPOWER_IDLE];
     *Suspend = StateTimer->elapse[gcvPOWER_SUSPEND];
+}
+
+static gceSTATUS
+_PrepareFunctions(
+    IN gckHARDWARE Hardware
+    );
+
+static gceSTATUS
+_InitPageTableArray(
+    IN gckHARDWARE Hardware
+    )
+{
+    gceSTATUS status;
+    gcmkHEADER_ARG("Hardware=%p", Hardware);
+
+    if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+    {
+        gcePOOL pool = gcvPOOL_DEFAULT;
+        gctUINT32 flags = gcvALLOC_FLAG_CONTIGUOUS;
+
+#if defined(CONFIG_ZONE_DMA32)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+        flags |= gcvALLOC_FLAG_4GB_ADDR;
+#endif
+#endif
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+        flags |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+        Hardware->pagetableArray.size = 1024;
+
+        /* Allocate mmu table array within 32bit space */
+        gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+            Hardware->kernel,
+            64,
+            gcvVIDMEM_TYPE_COMMAND,
+            flags,
+            &Hardware->pagetableArray.size,
+            &pool,
+            &Hardware->pagetableArray.videoMem
+            ));
+
+        /* Lock for kernel side CPU access. */
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+            Hardware->kernel,
+            Hardware->pagetableArray.videoMem,
+            gcvFALSE,
+            gcvFALSE,
+            &Hardware->pagetableArray.logical
+            ));
+
+        /* Get CPU physical address. */
+        gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+            Hardware->kernel,
+            Hardware->pagetableArray.videoMem,
+            0,
+            &Hardware->pagetableArray.address
+            ));
+
+        /* Convert to GPU physical address. */
+        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+            Hardware->os,
+            Hardware->pagetableArray.address,
+            &Hardware->pagetableArray.address
+            ));
+    }
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    if (Hardware->pagetableArray.videoMem)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+            Hardware->kernel,
+            Hardware->pagetableArray.videoMem
+            ));
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_SetupSRAMVidMem(
+    IN gckHARDWARE Hardware
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    gctUINT i;
 
-    gckSTATETIMER_Reset(StateTimer, StateTimer->recent);
+    for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_COUNT; i++)
+    {
+        if (Hardware->identity.sRAMSizes[i] &&
+           (Hardware->identity.sRAMBases[i] != gcvINVALID_PHYSICAL_ADDRESS))
+        {
+            char sRAMName[20];
+            gcmkSPRINTF(sRAMName, gcmSIZEOF(sRAMName) - 1, "GPU core%d axi sram%d", Hardware->core, i);
+
+            gcmkPRINT("%s\n", sRAMName);
+
+            status = gckVIDMEM_Construct(
+                Hardware->os,
+                Hardware->identity.sRAMBases[i],
+                Hardware->identity.sRAMSizes[i],
+                64,
+                0,
+                &Hardware->sRAMVideoMem[i]
+                );
+
+            if (gcmIS_ERROR(status))
+            {
+                Hardware->identity.sRAMSizes[i] = 0;
+                Hardware->sRAMVideoMem[i] = gcvNULL;
+            }
+            else
+            {
+                gcmkONERROR(gckOS_RequestReservedMemory(
+                    Hardware->os,
+                    Hardware->identity.sRAMBases[i],
+                    Hardware->identity.sRAMSizes[i],
+                    sRAMName,
+                    0,
+                    &Hardware->sRAMPhysical[i]
+                    ));
+
+                Hardware->sRAMVideoMem[i]->physical = Hardware->sRAMPhysical[i];
+            }
+        }
+    }
+
+OnError:
+    return status;
 }
 
 /******************************************************************************\
@@ -1800,6 +2074,7 @@ gckSTATETIMER_Query(
 gceSTATUS
 gckHARDWARE_Construct(
     IN gckOS Os,
+    IN gckDEVICE Device,
     IN gceCORE Core,
     OUT gckHARDWARE * Hardware
     )
@@ -1840,7 +2115,13 @@ gckHARDWARE_Construct(
     gcmkONERROR(_GetHardwareSignature(hardware, Os, Core, &hardware->signature));
 
     /* Identify the hardware. */
-    gcmkONERROR(_IdentifyHardwareByDatabase(hardware, Os, Core, &hardware->identity));
+    gcmkONERROR(_IdentifyHardwareByDatabase(hardware, Os, Device, Core, &hardware->identity));
+
+    /* Setup SRAM memory heap. */
+    if (hardware->sRAMNonExclusive)
+    {
+        gcmkONERROR(_SetupSRAMVidMem(hardware));
+    }
 
     _SetHardwareOptions(hardware);
 
@@ -1918,11 +2199,13 @@ gckHARDWARE_Construct(
     gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1));
 
 #if !gcdENABLE_128B_MERGE
+
     if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_MULTI_SOURCE_BLT))
     {
         /* 128B merge is turned on by default. Disable it. */
         gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, 0));
     }
+
 #endif
 
 #if (gcdFPGA_BUILD && 1)
@@ -1965,14 +2248,10 @@ gckHARDWARE_Construct(
     gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
     gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
 
-#if gcdPOWEROFF_TIMEOUT
-    hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
-
     gcmkVERIFY_OK(gckOS_CreateTimer(Os,
-                                    _PowerTimerFunction,
+                                    _PowerStateTimerFunc,
                                     (gctPOINTER)hardware,
-                                    &hardware->powerOffTimer));
-#endif
+                                    &hardware->powerStateTimer));
 
     for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
     {
@@ -1981,6 +2260,7 @@ gckHARDWARE_Construct(
 
     gcmkONERROR(gckOS_AtomConstruct(Os, &hardware->pendingEvent));
 
+
 #if defined(LINUX) || defined(__QNXNTO__) || defined(UNDER_CE)
     if (hardware->mmuVersion)
     {
@@ -1990,45 +2270,39 @@ gckHARDWARE_Construct(
     else
 #endif
     {
-        hardware->stallFEPrefetch = gcvTRUE;
+        hardware->stallFEPrefetch =
+            _QueryFeatureDatabase(hardware, gcvFEATURE_MCFE) == gcvFALSE;
     }
 
-    hardware->hasAsyncFe
-        = gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_ASYNC_BLIT);
-
     hardware->minFscaleValue = 1;
     hardware->waitCount = 200;
 
-    gckSTATETIMER_Reset(&hardware->powerStateTimer, 0);
+    gckSTATETIMER_Reset(&hardware->powerStateCounter, 0);
 
 #if gcdLINK_QUEUE_SIZE
     gcmkONERROR(gckQUEUE_Allocate(hardware->os, &hardware->linkQueue, gcdLINK_QUEUE_SIZE));
 #endif
 
-    if (hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+    /* Initialize FEs, either MCFE or wait-link FE. */
+    if (_QueryFeatureDatabase(hardware, gcvFEATURE_MCFE))
     {
-        hardware->pagetableArray.size = 4096;
+        hardware->mcfeChannels[0] = gcvMCFE_CHANNEL_SYSTEM;
+        hardware->mcfeChannels[1] = gcvMCFE_CHANNEL_SHADER;
+        hardware->mcfeChannels[2] = gcvMCFE_CHANNEL_NN;
+        hardware->mcfeChannels[3] = gcvMCFE_CHANNEL_TP;
 
-        gcmkONERROR(gckOS_AllocateNonPagedMemory(
-            hardware->os,
-            gcvFALSE,
-            gcvALLOC_FLAG_CONTIGUOUS,
-            &hardware->pagetableArray.size,
-            &hardware->pagetableArray.physical,
-            &hardware->pagetableArray.logical
-            ));
+        hardware->mcfeChannelCount = 4;
 
-        gcmkONERROR(gckOS_GetPhysicalAddress(
-            hardware->os,
-            hardware->pagetableArray.logical,
-            &hardware->pagetableArray.address
-            ));
+        gcmkONERROR(gckMCFE_Construct(hardware, &hardware->mcFE));
+    }
+    else
+    {
+        gcmkONERROR(gckWLFE_Construct(hardware, &hardware->wlFE));
+    }
 
-        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
-            hardware->os,
-            hardware->pagetableArray.address,
-            &hardware->pagetableArray.address
-            ));
+    if (_QueryFeatureDatabase(hardware, gcvFEATURE_ASYNC_BLIT))
+    {
+        gcmkONERROR(gckASYNC_FE_Construct(hardware, &hardware->asyncFE));
     }
 
     /* Return pointer to the gckHARDWARE object. */
@@ -2058,13 +2332,11 @@ OnError:
             gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex));
         }
 
-#if gcdPOWEROFF_TIMEOUT
-        if (hardware->powerOffTimer != gcvNULL)
+        if (hardware->powerStateTimer != gcvNULL)
         {
-            gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerOffTimer));
-            gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerOffTimer));
+            gcmkVERIFY_OK(gckOS_StopTimer(Os, hardware->powerStateTimer));
+            gcmkVERIFY_OK(gckOS_DestroyTimer(Os, hardware->powerStateTimer));
         }
-#endif
 
         for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
         {
@@ -2079,16 +2351,6 @@ OnError:
             gcmkVERIFY_OK(gckOS_AtomDestroy(Os, hardware->pendingEvent));
         }
 
-        if (hardware->pagetableArray.logical != gcvNULL)
-        {
-            gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
-                Os,
-                hardware->pagetableArray.size,
-                hardware->pagetableArray.physical,
-                hardware->pagetableArray.logical
-                ));
-        }
-
         gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware));
     }
 
@@ -2097,11 +2359,31 @@ OnError:
     return status;
 }
 
+gceSTATUS
+gckHARDWARE_PostConstruct(
+    IN gckHARDWARE Hardware
+    )
+{
+    gceSTATUS status;
+
+    /* Initialize MMU page table array. */
+    gcmkONERROR(_InitPageTableArray(Hardware));
+
+    /* Initialize function commands. */
+    gcmkONERROR(_PrepareFunctions(Hardware));
+
+    return gcvSTATUS_OK;
+
+OnError:
+    return status;
+}
+
 /*******************************************************************************
 **
-**  gckHARDWARE_Destroy
+**  gckHARDWARE_PreDestroy
 **
-**  Destroy an gckHARDWARE object.
+**  Prepare destroying an gckHARDWARE object.
+**  This is to destroy resources relevant to other modules such as MMU.
 **
 **  INPUT:
 **
@@ -2113,11 +2395,117 @@ OnError:
 **      Nothing.
 */
 gceSTATUS
-gckHARDWARE_Destroy(
+gckHARDWARE_PreDestroy(
     IN gckHARDWARE Hardware
     )
 {
-    gceSTATUS status;
+    gcmkHEADER_ARG("%x", Hardware);
+
+    if (Hardware->auxFuncVideoMem)
+    {
+        /* Synchroneous unlock. */
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Unlock(
+            Hardware->kernel,
+            Hardware->auxFuncVideoMem,
+            0,
+            gcvNULL
+            ));
+
+        gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+            Hardware->kernel,
+            Hardware->auxFuncVideoMem,
+            0,
+            gcvFALSE
+            ));
+
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+            Hardware->kernel,
+            Hardware->auxFuncVideoMem
+            ));
+
+        Hardware->auxFuncVideoMem = gcvNULL;
+        Hardware->auxFuncLogical  = gcvNULL;
+    }
+
+    if (Hardware->mmuFuncVideoMem)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+            Hardware->kernel,
+            Hardware->mmuFuncVideoMem,
+            0,
+            gcvFALSE
+            ));
+
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+            Hardware->kernel,
+            Hardware->mmuFuncVideoMem
+            ));
+
+        Hardware->mmuFuncVideoMem = gcvNULL;
+        Hardware->mmuFuncLogical  = gcvNULL;
+    }
+
+    if (Hardware->pagetableArray.videoMem)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+            Hardware->kernel,
+            Hardware->pagetableArray.videoMem,
+            0,
+            gcvFALSE
+            ));
+
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+            Hardware->kernel,
+            Hardware->pagetableArray.videoMem
+            ));
+
+        Hardware->pagetableArray.videoMem = gcvNULL;
+        Hardware->pagetableArray.logical  = gcvNULL;
+    }
+
+    if (Hardware->wlFE)
+    {
+        gckWLFE_Destroy(Hardware, Hardware->wlFE);
+        Hardware->wlFE = gcvNULL;
+    }
+
+    if (Hardware->asyncFE)
+    {
+        gckASYNC_FE_Destroy(Hardware, Hardware->asyncFE);
+        Hardware->asyncFE = gcvNULL;
+    }
+
+    if (Hardware->mcFE)
+    {
+        gckMCFE_Destroy(Hardware, Hardware->mcFE);
+        Hardware->mcFE = gcvNULL;
+    }
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+**  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;
     gctUINT i;
 
     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
@@ -2132,10 +2520,8 @@ gckHARDWARE_Destroy(
     /* 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_DestroyTimer(Hardware->os, Hardware->powerOffTimer));
-#endif
+    gcmkVERIFY_OK(gckOS_StopTimer(Hardware->os, Hardware->powerStateTimer));
+    gcmkVERIFY_OK(gckOS_DestroyTimer(Hardware->os, Hardware->powerStateTimer));
 
     for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
     {
@@ -2148,16 +2534,6 @@ gckHARDWARE_Destroy(
     gckQUEUE_Free(Hardware->os, &Hardware->linkQueue);
 #endif
 
-    if (Hardware->pagetableArray.logical != gcvNULL)
-    {
-        gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
-            Hardware->os,
-            Hardware->pagetableArray.size,
-            Hardware->pagetableArray.physical,
-            Hardware->pagetableArray.logical
-            ));
-    }
-
     /* Mark the object as unknown. */
     Hardware->object.type = gcvOBJ_UNKNOWN;
 
@@ -2272,16 +2648,10 @@ gckHARDWARE_InitializeHardware(
     if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_SECURITY_AHB) &&
         (Hardware->options.secureMode == gcvSECURE_IN_NORMAL))
     {
-        gctUINT32 ahbControl = 0;
-
-        gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os,
-                                         Hardware->core,
-                                         0x003A8,
-                                         &ahbControl));
         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
                                           Hardware->core,
                                           0x003A8,
-                                          ((((gctUINT32) (ahbControl)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                                          ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  1:1) - (0 ?
  1:1) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -2292,7 +2662,6 @@ gckHARDWARE_InitializeHardware(
  1:1) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))));
     }
-
     /* Reset memory counters. */
     gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
                                       Hardware->core,
@@ -2375,6 +2744,21 @@ gckHARDWARE_InitializeHardware(
                                       + 0x00100,
                                       data));
 
+    /* Initialize FE. */
+    if (Hardware->wlFE)
+    {
+        gckWLFE_Initialize(Hardware, Hardware->wlFE);
+    }
+    else if (Hardware->mcFE)
+    {
+        gckMCFE_Initialize(Hardware, gcvFALSE, Hardware->mcFE);
+    }
+
+    if (Hardware->asyncFE)
+    {
+        gckASYNC_FE_Initialize(Hardware, Hardware->asyncFE);
+    }
+
 #if gcdENABLE_3D
     /* Disable PE clock gating on revs < 5.0 when HZ is present without a
     ** bug fix. */
@@ -2528,7 +2912,13 @@ gckHARDWARE_InitializeHardware(
 
     gcmkONERROR(
         gckHARDWARE_SetMMU(Hardware,
-                           Hardware->kernel->mmu->area[0].pageTableLogical));
+                           Hardware->kernel->mmu));
+
+    if (Hardware->mcFE)
+    {
+        /* Reinitialize MCFE, now MMU is enabled. */
+        gckMCFE_Initialize(Hardware, gcvTRUE, Hardware->mcFE);
+    }
 
     if (Hardware->identity.chipModel >= gcv400
     &&  Hardware->identity.chipModel != gcv420
@@ -2859,6 +3249,29 @@ gckHARDWARE_InitializeHardware(
             Hardware->os, Hardware->core, 0x00090, data));
     }
 
+    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_NN_ENGINE) &&
+        (!gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HI_REORDER_FIX) ||
+        (((gcsFEATURE_DATABASE *)Hardware->featureDatabase)->AXI_SRAM_SIZE == 0))
+        )
+    {
+        gcmkONERROR(gckOS_ReadRegisterEx(
+            Hardware->os, Hardware->core, 0x00090, &data));
+
+        data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+
+        gcmkONERROR(gckOS_WriteRegisterEx(
+            Hardware->os, Hardware->core, 0x00090, data));
+    }
+
     _ConfigurePolicyID(Hardware);
 
 #if gcdDEBUG_MODULE_CLOCK_GATING
@@ -3131,351 +3544,239 @@ gckHARDWARE_SplitMemory(
 
 /*******************************************************************************
 **
-**  gckHARDWARE_Execute
+**  gckHARDWARE_PipeSelect
+**
+**  Append a PIPESELECT command at the specified user logical memory.
 **
-**  Kickstart the hardware's command processor with an initialized command
-**  buffer.
+**  WARNING: Only for writing to USERSPACE!
 **
 **  INPUT:
 **
 **      gckHARDWARE Hardware
-**          Pointer to the gckHARDWARE object.
+**          Pointer to an gckHARDWARE object.
 **
-**      gctUINT32 Address
-**          Hardware address of command buffer.
+**      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
-**          Number of bytes for the prefetch unit (until after the first LINK).
+**      gctSIZE_T * Bytes
+**          Pointer to the number of bytes available for the PIPESELECT command.
+**          If 'Logical' is gcvNULL, this argument will be ignored.
 **
 **  OUTPUT:
 **
-**      Nothing.
+**      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_Execute(
+gckHARDWARE_PipeSelect(
     IN gckHARDWARE Hardware,
-    IN gctUINT32 Address,
-    IN gctSIZE_T Bytes
+    IN gctPOINTER Logical,
+    IN gcePIPE_SELECT Pipe,
+    IN OUT gctUINT32 * Bytes
     )
 {
+    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
     gceSTATUS status;
-    gctUINT32 control;
 
-    gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Bytes=%lu",
-                   Hardware, Address, Bytes);
+    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));
 
-    /* Enable all events. */
-    gcmkONERROR(
-        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U));
+    /* Append a PipeSelect. */
+    if (Logical != gcvNULL)
+    {
+        gctUINT32 flush, stall;
 
-    /* Write address register. */
-    gcmkONERROR(
-        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address));
+        if (*Bytes < 32)
+        {
+            /* Command queue too small. */
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+        }
 
-    /* Build control register. */
-    control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 16:16) - (0 ?
- 16:16) + 1) == 32) ?
+        flush = (Pipe == gcvPIPE_2D)
+              ?
+ ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 16:16) - (0 ?
- 16:16) + 1))))))) << (0 ?
- 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 16:16) - (0 ?
- 16:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+              : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
+
+        stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+
+        /* LoadState(AQFlush, 1), flush. */
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((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) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 21:20) - (0 ?
- 21:20) + 1))))))) << (0 ?
- 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
- 21:20) - (0 ?
- 21:20) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20)));
-    }
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            ));
 
-    /* Make sure writing to command buffer and previous AHB register is done. */
-    gcmkONERROR(gckOS_MemoryBarrier(Hardware->os, gcvNULL));
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            logical + 1,
+            flush
+            ));
 
-    /* Write control register. */
-    switch (Hardware->options.secureMode)
-    {
-    case gcvSECURE_NONE:
-        gcmkONERROR(
-            gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
-        break;
-    case gcvSECURE_IN_NORMAL:
-
-#if defined(__KERNEL__)
-        gcmkONERROR(
-            gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
-#endif
-        gcmkONERROR(
-            gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x003A4, control));
-
-        break;
-#if gcdENABLE_TRUST_APPLICATION
-    case gcvSECURE_IN_TA:
-        /* Send message to TA. */
-        gcmkONERROR(gckKERNEL_SecurityStartCommand(Hardware->kernel, Address, (gctUINT32)Bytes));
-        break;
-#endif
-    default:
-        break;
-    }
-
-    /* Increase execute count. */
-    Hardware->executeCount++;
-
-    /* Record last execute address. */
-    Hardware->lastExecuteAddress = Address;
-
-    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;
-}
-
-/* Atomic version of Execute, for IRQ routine. */
-static gceSTATUS
-gckHARDWARE_AtomicExecute(
-    IN gckHARDWARE Hardware,
-    IN gctUINT32 Address,
-    IN gctSIZE_T Bytes
-    )
-{
-    gctUINT32 control;
-
-    /* Enable all events. */
-    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U);
-
-    /* Write address register. */
-    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address);
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+                       "0x%x: FLUSH 0x%x", logical, flush);
 
-    /* Build control register. */
-    control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 16:16) - (0 ?
- 16:16) + 1) == 32) ?
+        /* LoadState(AQSempahore, 1), stall. */
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            logical + 2,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 16:16) - (0 ?
- 16:16) + 1))))))) << (0 ?
- 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 16:16) - (0 ?
- 16:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((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) ?
- ~0U : (~(~0U << ((1 ?
- 21:20) - (0 ?
- 21:20) + 1))))))) << (0 ?
- 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
- 21:20) - (0 ?
- 21:20) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20)));
-    }
-
-    /* Make sure writing to command buffer and previous AHB register is done. */
-    gckOS_MemoryBarrier(Hardware->os, gcvNULL);
-
-    /* Write control register. */
-    switch (Hardware->options.secureMode)
-    {
-    case gcvSECURE_NONE:
-        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control);
-        break;
-    case gcvSECURE_IN_NORMAL:
-
-#if defined(__KERNEL__)
-        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control);
-#endif
-        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x003A4, control);
-
-        break;
-#if gcdENABLE_TRUST_APPLICATION
-    case gcvSECURE_IN_TA:
-        /* Send message to TA. */
-        gckKERNEL_SecurityStartCommand(Hardware->kernel, Address, (gctUINT32)Bytes);
-        break;
-#endif
-    default:
-        break;
-    }
-
-    /* Increase execute count. */
-    Hardware->executeCount++;
-
-    /* Record last execute address. */
-    Hardware->lastExecuteAddress = Address;
-
-    /* Success. */
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  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 Address
-**          GPU address of current location inside the command queue.
-**
-**      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 Address,
-    IN gctUINT32 Offset,
-    IN OUT gctUINT32 * Bytes,
-    OUT gctUINT32 * WaitOffset,
-    OUT gctUINT32 * WaitSize
-    )
-{
-    gceSTATUS status;
-    gctUINT32_PTR logical;
-    gctUINT32 bytes;
-    gctBOOL useL2;
-
-    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));
-
-    useL2 = Hardware->hasL2Cache;
-
-    /* Compute number of bytes required. */
-    if (useL2)
-    {
-        bytes = gcmALIGN(Offset + 24, 8) - Offset;
-    }
-    else
-    {
-        bytes = gcmALIGN(Offset + 16, 8) - Offset;
-    }
-
-    /* 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);
-        }
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+            ));
 
-        gcmkASSERT(Address != ~0U);
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            logical + 3,
+            stall
+            ));
 
-        /* Store the WAIT/LINK address. */
-        Hardware->lastWaitLink = Address;
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+                       "0x%x: SEMAPHORE 0x%x", logical + 2, stall);
 
-        /* Append WAIT(count). */
-        *logical++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        /* Stall, stall. */
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            logical + 4,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (Hardware->waitCount) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+            ));
+
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            logical + 5,
+            stall
+            ));
 
-        logical++;
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+                       "0x%x: STALL 0x%x", logical + 4, stall);
 
-        if (useL2)
-        {
-            /* LoadState(AQFlush, 1), flush. */
-            *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        /* LoadState(AQPipeSelect, 1), pipe. */
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            logical + 6,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -3485,17 +3786,17 @@ gckHARDWARE_WaitLink(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -3504,88 +3805,30 @@ gckHARDWARE_WaitLink(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
-
-            *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 6:6) - (0 ?
- 6:6) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 6:6) - (0 ?
- 6:6) + 1))))))) << (0 ?
- 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 6:6) - (0 ?
- 6:6) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
-        }
-
-        /* Append LINK(2, address). */
-        *logical++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            ));
 
-        *logical++ = Address;
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            logical + 7,
+            (Pipe == gcvPIPE_2D)
+            ? 0x1
+            : 0x0
+            ));
 
-        gcmkTRACE_ZONE(
-            gcvLEVEL_INFO, gcvZONE_HARDWARE,
-            "0x%08x: WAIT %u", Address, Hardware->waitCount
-            );
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+                       "0x%x: PIPE %d", logical + 6, Pipe);
+    }
 
-        gcmkTRACE_ZONE(
-            gcvLEVEL_INFO, gcvZONE_HARDWARE,
-            "0x%08x: LINK 0x%08x, #%lu",
-            Address + 8, Address, bytes
-            );
+    if (Bytes != gcvNULL)
+    {
+        /* Return number of bytes required by the PIPESELECT command. */
+        *Bytes = 32;
+    }
 
-        if (WaitOffset != gcvNULL)
-        {
-            /* Return the offset pointer to WAIT command. */
-            *WaitOffset = 0;
-        }
-
-        if (WaitSize != gcvNULL)
-        {
-            /* Return number of bytes used by the WAIT command. */
-            if (useL2)
-            {
-                *WaitSize = 16;
-            }
-            else
-            {
-                *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;
+    /* Success. */
+    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+    return gcvSTATUS_OK;
 
 OnError:
     /* Return the status. */
@@ -3593,135 +3836,101 @@ OnError:
     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.
-**
-**      gctUINT32 Address
-**          GPU address of current location inside the command queue.
-**
-**      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(
+static gceSTATUS
+_FenceRender(
     IN gckHARDWARE Hardware,
     IN gctPOINTER Logical,
-    IN gctUINT32 Address,
+    IN gctUINT32 FenceAddress,
+    IN gctUINT64 FenceData,
     IN OUT gctUINT32 * Bytes
     )
 {
-    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
-    gctUINT32 address;
-    gceSTATUS status;
-
-    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
-                   Hardware, Logical, gcmOPT_VALUE(Bytes));
+    gckOS os = Hardware->os;
+    gctUINT32_PTR logical = (gctUINT32_PTR)Logical;
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+    gctUINT32 dataLow = (gctUINT32)FenceData;
+    gctUINT32 dataHigh = (gctUINT32)(FenceData >> 32);
 
-    if (Logical != gcvNULL)
+    if (logical)
     {
-        if (*Bytes < 8)
-        {
-            /* Command queue too small. */
-            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
-        }
-
-        /* Append END. */
-        logical[0] =
+        gcmkWRITE_MEMORY(
+            logical,
             ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
-
-        /* Record the count of execution which is finised by this END. */
-        logical[1] =
-            Hardware->executeCount;
-
-        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));
-
-
-        gcmkASSERT(Address != ~0U);
-        address = Address;
-
-        Hardware->lastEnd = address;
-    }
-
-    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;
-}
-
-gceSTATUS
-gckHARDWARE_ChipEnable(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gceCORE_3D_MASK ChipEnable,
-    IN OUT gctSIZE_T * Bytes
-    )
-{
-    gckOS os = Hardware->os;
-    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
-    gceSTATUS status;
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E1A) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            );
 
-    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x ChipEnable=0x%x *Bytes=%lu",
-                   Hardware, Logical, ChipEnable, gcmOPT_VALUE(Bytes));
+        gcmkWRITE_MEMORY(
+            logical,
+            FenceAddress
+            );
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E26) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            );
 
-    if (Logical != gcvNULL)
-    {
-        if (*Bytes < 8)
-        {
-            /* Command queue too small. */
-            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
-        }
+        gcmkWRITE_MEMORY(
+            logical,
+            dataHigh
+            );
 
-        /* Append CHIPENABLE. */
         gcmkWRITE_MEMORY(
             logical,
             ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -3730,263 +3939,86 @@ gckHARDWARE_ChipEnable(
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E1B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ChipEnable
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
             );
 
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: CHIPENABLE 0x%x", Logical, ChipEnable);
+        gcmkWRITE_MEMORY(
+            logical,
+            dataLow
+            );
     }
 
-    if (Bytes != gcvNULL)
+    if (Bytes)
     {
-        /* Return number of bytes required by the CHIPENABLE command. */
-        *Bytes = 8;
+        *Bytes = gcdRENDER_FENCE_LENGTH;
     }
 
-    /* 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(
+static gceSTATUS
+_FenceBlt(
     IN gckHARDWARE Hardware,
     IN gctPOINTER Logical,
-    IN OUT gctSIZE_T * Bytes
+    IN gctUINT32 FenceAddress,
+    IN gctUINT64 FenceData,
+    IN OUT gctUINT32 * Bytes
     )
 {
-    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
-    gceSTATUS status;
-
-    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
-                   Hardware, Logical, gcmOPT_VALUE(Bytes));
+    gckOS os = Hardware->os;
+    gctUINT32_PTR logical = (gctUINT32_PTR)Logical;
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+    gctUINT32 dataLow = (gctUINT32)FenceData;
+    gctUINT32 dataHigh = (gctUINT32)(FenceData >> 32);
 
-    if (Logical != gcvNULL)
+    if (logical)
     {
-        if (*Bytes < 8)
-        {
-            /* Command queue too small. */
-            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
-        }
-
-        /* Append NOP. */
-        logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((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_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 gctUINT32 * Bytes
-    )
-{
-    gctUINT size;
-    gctUINT32 destination = 0;
-    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
-    gceSTATUS status;
-    gctBOOL blt;
-    gctBOOL extraEventStates;
-
-    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);
-
-    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE))
-    {
-        /* Send all event from blt. */
-        if (FromWhere == gcvKERNEL_PIXEL)
-        {
-            FromWhere = gcvKERNEL_BLT;
-        }
-    }
-
-    blt = FromWhere == gcvKERNEL_BLT ? gcvTRUE : gcvFALSE;
-
-    /* Determine the size of the command. */
-
-    extraEventStates = Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL);
-
-    size = extraEventStates
-         ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
-         : 8;
-
-    if (blt)
-    {
-        size += 16;
-    }
-
-    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) ?
- ~0U : (~(~0U << ((1 ?
- 5:5) - (0 ?
- 5:5) + 1))))))) << (0 ?
- 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 5:5) - (0 ?
- 5:5) + 1) == 32) ?
- ~0U : (~(~0U << ((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) ?
- ~0U : (~(~0U << ((1 ?
- 6:6) - (0 ?
- 6:6) + 1))))))) << (0 ?
- 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 6:6) - (0 ?
- 6:6) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
-            break;
-
-        case gcvKERNEL_BLT:
-            destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 7:7) - (0 ?
- 7:7) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 7:7) - (0 ?
- 7:7) + 1))))))) << (0 ?
- 7:7))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 7:7) - (0 ?
- 7:7) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
-            break;
-
-        default:
-            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-        }
-
-        if (blt)
-        {
-            *logical++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -3996,19 +4028,11 @@ gckHARDWARE_Event(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+            );
 
-            *logical++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -4017,12 +4041,12 @@ gckHARDWARE_Event(
  0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
-        }
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+            );
 
-        /* Append EVENT(Event, destination). */
-        *logical++
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -4032,17 +4056,17 @@ gckHARDWARE_Event(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x5029) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -4051,24 +4075,17 @@ gckHARDWARE_Event(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            );
 
-        *logical++
-            = ((((gctUINT32) (destination)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) ((gctUINT32) (Event) & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+        gcmkWRITE_MEMORY(
+            logical,
+            FenceAddress
+            );
 
-        if (blt)
-        {
-            *logical++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -4078,7 +4095,17 @@ gckHARDWARE_Event(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502D) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -4088,52 +4115,55 @@ gckHARDWARE_Event(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            );
+
+        gcmkWRITE_MEMORY(
+            logical,
+            dataHigh
+            );
+
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502A) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-            *logical++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
-        }
-
-
-        /* Make sure the event ID gets written out before GPU can access it. */
-        gcmkONERROR(
-            gckOS_MemoryBarrier(Hardware->os, logical + 1));
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            );
 
-#if gcmIS_DEBUG(gcdDEBUG_TRACE)
-        {
-            gctPHYS_ADDR_T phys;
-            gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
-            gckOS_CPUPhysicalToGPUPhysical(Hardware->os, phys, &phys);
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                           "0x%08x: EVENT %d", phys, Event);
-        }
-#endif
+        gcmkWRITE_MEMORY(
+            logical,
+            dataLow
+            );
 
-        /* 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 (extraEventStates)
-        {
-            *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -4143,75 +4173,78 @@ gckHARDWARE_Event(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0100) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  25:16) - (0 ?
  25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
-            *logical++ = 0;
-            *logical++ = 0;
-            *logical++ = 0;
-            *logical++ = 0;
-            *logical++ = 0;
-        }
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            );
 
-#if gcdINTERRUPT_STATISTIC
-        if (Event < gcmCOUNTOF(Hardware->kernel->eventObj->queues))
-        {
-            gckOS_AtomSetMask(Hardware->pendingEvent, 1 << Event);
-        }
-#endif
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+            );
     }
 
-    if (Bytes != gcvNULL)
+    if (Bytes)
     {
-        /* Return number of bytes required by the EVENT command. */
-        *Bytes = size;
+        *Bytes = gcdBLT_FENCE_LENGTH;
     }
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
     return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
 }
 
 /*******************************************************************************
 **
-**  gckHARDWARE_PipeSelect
+**  gckHARDWARE_Fence
 **
-**  Append a PIPESELECT command at the specified location in the command queue.
+**  Append a HW FENCE states at the specified user logical memory.
+**
+**  WARNING: Only for writing to USERSPACE!
 **
 **  INPUT:
 **
 **      gckHARDWARE Hardware
 **          Pointer to an gckHARDWARE object.
 **
+**      gceENGINE Engine
+**          Engine type, render or 3d-blit currently.
+**
+**
 **      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.
+**      gctUINT32 FenceAddress
+**          GPU address to write out the data.
+**
+**      gctUINT64 FenceData
+**          The 64bit data to write out.
 **
 **      gctSIZE_T * Bytes
 **          Pointer to the number of bytes available for the PIPESELECT command.
@@ -4225,1208 +4258,359 @@ OnError:
 **          returned.
 */
 gceSTATUS
-gckHARDWARE_PipeSelect(
+gckHARDWARE_Fence(
     IN gckHARDWARE Hardware,
+    IN gceENGINE  Engine,
     IN gctPOINTER Logical,
-    IN gcePIPE_SELECT Pipe,
+    IN gctUINT32 FenceAddress,
+    IN gctUINT64 FenceData,
     IN OUT gctUINT32 * Bytes
     )
 {
-    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+    if (Engine == gcvENGINE_RENDER)
+    {
+        return _FenceRender(Hardware, Logical, FenceAddress, FenceData, Bytes);
+    }
+    else
+    {
+         return _FenceBlt(Hardware, Logical, FenceAddress, FenceData, Bytes);
+    }
+}
+
+/*******************************************************************************
+**
+**  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 Pipe=%d *Bytes=%lu",
-                   Hardware, Logical, Pipe, gcmOPT_VALUE(Bytes));
+    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x",
+                   Hardware, Logical, Offset);
 
-    /* Verify the arguments. */
+    /* Verify the hardware. */
     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
 
-    /* Append a PipeSelect. */
-    if (Logical != gcvNULL)
+    /* Force a barrier. */
+    gcmkONERROR(
+        gckOS_MemoryBarrier(Hardware->os, Logical));
+
+    /* Notify gckKERNEL object of change. */
+    gcmkONERROR(
+        gckKERNEL_Notify(Hardware->kernel,
+                         gcvNOTIFY_COMMAND_QUEUE));
+
+    if (status == gcvSTATUS_CHIP_NOT_READY)
     {
-        gctUINT32 flush, stall;
+        gcmkONERROR(gcvSTATUS_DEVICE);
+    }
 
-        if (*Bytes < 32)
-        {
-            /* Command queue too small. */
-            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
-        }
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
 
-        flush = (Pipe == gcvPIPE_2D)
-              ?
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
-              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+
+static void
+_ResumeWaitLinkFE(
+    gckHARDWARE Hardware
+    )
+{
+    gctUINT32 resume;
+    gctUINT32 bytes;
+    gctUINT32 idle;
+
+    /* Make sure FE is idle. */
+    do
+    {
+        gckOS_ReadRegisterEx(Hardware->os,
+                             Hardware->core,
+                             0x00004,
+                             &idle);
+    }
+    while (idle != 0x7FFFFFFF);
+
+    gcmkDUMP(Hardware->os, "@[register.wait 0x%05X 0x%08X 0x%08X]",
+             0x00004,
+             ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  0:0) - (0 ?
  0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (~0U) & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-              : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 3:3) - (0 ?
- 3:3) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 3:3) - (0 ?
- 3:3) + 1))))))) << (0 ?
- 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 3:3) - (0 ?
- 3:3) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)));
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))),
+             idle);
 
-        stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+    gckOS_ReadRegisterEx(Hardware->os,
+                         Hardware->core,
+                         0x00664,
+                         &resume);
 
-        /* LoadState(AQFlush, 1), flush. */
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            ));
+    gckOS_ReadRegisterEx(Hardware->os,
+                         Hardware->core,
+                         0x00664,
+                         &resume);
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            logical + 1,
-            flush
-            ));
+    bytes = Hardware->hasL2Cache ? 24 : 16;
 
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                       "0x%x: FLUSH 0x%x", logical, flush);
+    /* Start Command Parser. */
+    gckWLFE_AtomicExecute(Hardware, resume, bytes);
+}
 
-        /* LoadState(AQSempahore, 1), stall. */
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            logical + 2,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-            ));
+/*******************************************************************************
+**
+**  gckHARDWARE_Interrupt
+**
+**  Process an interrupt. This function will read the interrupt acknowledge
+**  register, stores the data, and return whether the interrupt is from us.
+**
+**  INPUT:
+**
+**      gckHARDWARE Hardware
+**          Pointer to an gckHARDWARE object.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Interrupt(
+    IN gckHARDWARE Hardware
+    )
+{
+    gctUINT32 data = 0;
+    gctUINT32 dataEx = 0;
+    gceSTATUS status;
+    gceSTATUS statusEx;
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            logical + 3,
-            stall
-            ));
+    /*
+     * Notice:
+     * In isr here.
+     * We should return success when either FE or AsyncFE reports correct
+     * interrupts, so that isr can wake up threadRoutine for either FE.
+     * That means, only need return ERROR when both FEs reports ERROR.
+     */
+    /* Read AQIntrAcknowledge register. */
+    status = gckOS_ReadRegisterEx(Hardware->os,
+                                  Hardware->core,
+                                  0x00010,
+                                  &data);
 
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                       "0x%x: SEMAPHORE 0x%x", logical + 2, stall);
+    if (gcmIS_ERROR(status))
+    {
+        goto OnError;
+    }
 
-        /* Stall, stall. */
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            logical + 4,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            ));
+    if (data == 0)
+    {
+        /* Not our interrupt. */
+        status = gcvSTATUS_NOT_OUR_INTERRUPT;
+    }
+    else
+    {
+#if gcdINTERRUPT_STATISTIC
+        gckOS_AtomClearMask(Hardware->pendingEvent, data);
+#endif
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            logical + 5,
-            stall
-            ));
+        if (data & (1 << 29))
+        {
+            /* Event ID 29 is not a normal event, but for invalidating pipe. */
+            _ResumeWaitLinkFE(Hardware);
+            data &= ~(1 << 29);
+        }
 
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                       "0x%x: STALL 0x%x", logical + 4, stall);
+        /* Inform gckEVENT of the interrupt. */
+        status = gckEVENT_Interrupt(Hardware->kernel->eventObj, data);
+    }
 
-        /* LoadState(AQPipeSelect, 1), pipe. */
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            logical + 6,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            ));
+    if (!Hardware->asyncFE)
+    {
+        /* Done. */
+        goto OnError;
+    }
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            logical + 7,
-            (Pipe == gcvPIPE_2D)
-            ? 0x1
-            : 0x0
-            ));
+    /* Read BLT interrupt. */
+    statusEx = gckOS_ReadRegisterEx(
+        Hardware->os,
+        Hardware->core,
+        0x000D4,
+        &dataEx
+        );
 
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                       "0x%x: PIPE %d", logical + 6, Pipe);
+    if (gcmIS_ERROR(statusEx))
+    {
+        /*
+         * Do not overwrite status here, so that former status from
+         * AQIntrAck is returned.
+         */
+        goto OnError;
     }
 
-    if (Bytes != gcvNULL)
+    /*
+     * This bit looks useless now, we can use this check if this interrupt is
+     * from FE.
+     */
+    dataEx &= ~0x80000000;
+
+    /*
+     * Descriptor fetched, update counter.
+     * We can't do this at dataEx != 0 only, because read HW acknowledge
+     * register will overwrite 0x007E4. If one
+     * interrupt we don't read it, we will miss it for ever.
+     */
+    gckASYNC_FE_UpdateAvaiable(Hardware);
+
+    /* Do not need report NOT_OUT_INTERRUPT error if dataEx is 0. */
+    if (dataEx)
     {
-        /* Return number of bytes required by the PIPESELECT command. */
-        *Bytes = 32;
-    }
+        statusEx = gckEVENT_Interrupt(Hardware->kernel->asyncEvent, dataEx);
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
-    return gcvSTATUS_OK;
+        if (gcmIS_SUCCESS(statusEx))
+        {
+            /* At least AsyncFE is success, treat all as success. */
+            status = gcvSTATUS_OK;
+        }
+    }
 
 OnError:
     /* Return the status. */
-    gcmkFOOTER();
     return status;
 }
 
 /*******************************************************************************
 **
-**  gckHARDWARE_Link
+**  gckHARDWARE_Notify
 **
-**  Append a LINK command at the specified location in the command queue.
+**  This functions will handle the event notifications.
 **
 **  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.
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gckHARDWARE_Notify(
+    IN gckHARDWARE Hardware
+    )
+{
+    gceSTATUS status;
+    gcmkHEADER_ARG("Hardware=%p", Hardware);
+
+    /* Handle events. */
+    status = gckEVENT_Notify(Hardware->kernel->eventObj, 0);
+
+    if (Hardware->asyncFE)
+    {
+        status = gckEVENT_Notify(Hardware->kernel->asyncEvent, 0);
+    }
+
+     gcmkFOOTER();
+     return status;
+}
+
+/*******************************************************************************
+**
+**  gckHARDWARE_QueryCommandBuffer
 **
-**      gctUINT32 FetchAddress
-**          Hardware address of destination of LINK.
+**  Query the command buffer alignment and number of reserved bytes.
 **
-**      gctSIZE_T FetchSize
-**          Number of bytes in destination of LINK.
+**  INPUT:
 **
-**      gctSIZE_T * Bytes
-**          Pointer to the number of bytes available for the LINK command.  If
-**          'Logical' is gcvNULL, this argument will be ignored.
+**      gckHARDWARE Harwdare
+**          Pointer to an gckHARDWARE object.
 **
 **  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.
+**      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_Link(
+gckHARDWARE_QueryCommandBuffer(
     IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctUINT32 FetchAddress,
-    IN gctUINT32 FetchSize,
-    IN OUT gctUINT32 * Bytes,
-    OUT gctUINT32 * Low,
-    OUT gctUINT32 * High
+    IN gceENGINE Engine,
+    OUT gctUINT32 * Alignment,
+    OUT gctUINT32 * ReservedHead,
+    OUT gctUINT32 * ReservedTail
     )
 {
-    gceSTATUS status;
-    gctSIZE_T bytes;
-    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));
+    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
 
-    if (Logical != gcvNULL)
+    if (Alignment != gcvNULL)
     {
-        if (*Bytes < 8)
-        {
-            /* Command queue too small. */
-            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
-        }
+        /* Align every 8 bytes. */
+        *Alignment = 8;
+    }
 
-        gcmkONERROR(
-            gckOS_WriteMemory(Hardware->os, logical + 1, FetchAddress));
+    if (ReservedHead != gcvNULL)
+    {
+        /* Reserve space for SelectPipe(). */
+        *ReservedHead = 32;
+    }
 
-        if (High)
+    if (ReservedTail != gcvNULL)
+    {
+        if (Engine == gcvENGINE_RENDER)
         {
-            *High = FetchAddress;
+            gcmkFOOTER_NO();
+            return gcvSTATUS_NOT_SUPPORTED;
         }
-
-        /* 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(FetchAddress + FetchSize, 64) - FetchAddress;
-
-        /* Append LINK(bytes / 8), FetchAddress. */
-        link = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-        gcmkONERROR(
-            gckOS_WriteMemory(Hardware->os, logical, link));
-
-        if (Low)
+        else
         {
-            *Low = link;
+            *ReservedTail = gcdBLT_FENCE_LENGTH;
         }
-
-        /* Memory barrier. */
-        gcmkONERROR(
-            gckOS_MemoryBarrier(Hardware->os, logical));
-    }
-
-    if (Bytes != gcvNULL)
-    {
-        /* Return number of bytes required by the LINK command. */
-        *Bytes = 8;
     }
 
     /* Success. */
-    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+    gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu",
+                   gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead),
+                   gcmOPT_VALUE(ReservedTail));
     return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckHARDWARE_FenceRender(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctUINT32 FenceAddress,
-    IN gctUINT64 FenceData,
-    IN OUT gctUINT32 * Bytes
-    )
-{
-    gckOS os = Hardware->os;
-    gctUINT32_PTR logical = (gctUINT32_PTR)Logical;
-
-    gctUINT32 dataLow = (gctUINT32)FenceData;
-    gctUINT32 dataHigh = (gctUINT32)(FenceData >> 32);
-
-    if (logical)
-    {
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E1A) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            FenceAddress
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E26) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            dataHigh
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E1B) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            dataLow
-            );
-    }
-    else
-    {
-        *Bytes = gcdRENDER_FENCE_LENGTH;
-    }
-
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckHARDWARE_FenceBlt(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctUINT32 FenceAddress,
-    IN gctUINT64 FenceData,
-    IN OUT gctUINT32 * Bytes
-    )
-{
-    gckOS os = Hardware->os;
-    gctUINT32_PTR logical = (gctUINT32_PTR)Logical;
-
-    gctUINT32 dataLow = (gctUINT32)FenceData;
-    gctUINT32 dataHigh = (gctUINT32)(FenceData >> 32);
-
-    if (logical)
-    {
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x5029) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            FenceAddress
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502D) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            dataHigh
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502A) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            dataLow
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            );
-
-        gcmkWRITE_MEMORY(
-            logical,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-            );
-    }
-    else
-    {
-        *Bytes = gcdBLT_FENCE_LENGTH;
-    }
-
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckHARDWARE_Fence(
-    IN gckHARDWARE Hardware,
-    IN gceENGINE  Engine,
-    IN gctPOINTER Logical,
-    IN gctUINT32 FenceAddress,
-    IN gctUINT64 FenceData,
-    IN OUT gctUINT32 * Bytes
-    )
-{
-    if (Engine == gcvENGINE_RENDER)
-    {
-        return gckHARDWARE_FenceRender(Hardware, Logical, FenceAddress, FenceData, Bytes);
-    }
-    else
-    {
-         return gckHARDWARE_FenceBlt(Hardware, Logical, FenceAddress, FenceData, Bytes);
-    }
-}
-
-/*******************************************************************************
-**
-**  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_DEVICE);
-    }
-
-    /* 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.
-**
-**      gctBOOL InUserSpace
-**          gcvTRUE if the memory in user space.
-**
-**      gctUINT32* Address
-**          Return hardware specific address.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckHARDWARE_ConvertLogical(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctBOOL InUserSpace,
-    OUT gctUINT32 * Address
-    )
-{
-    gctUINT32 address;
-    gceSTATUS status;
-    gctPHYS_ADDR_T physical;
-
-    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x InUserSpace=%d",
-                   Hardware, Logical, InUserSpace);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Address != gcvNULL);
-
-    /* Convert logical address into a physical address. */
-    if (InUserSpace)
-    {
-        gcmkONERROR(gckOS_UserLogicalToPhysical(Hardware->os, Logical, &physical));
-    }
-    else
-    {
-        gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &physical));
-    }
-
-    gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
-
-    gcmkSAFECASTPHYSADDRT(address, physical);
-
-    /* For old MMU, get GPU address according to baseAddress. */
-    if (Hardware->mmuVersion == 0)
-    {
-        /* Subtract base address to get a GPU address. */
-        gcmkASSERT(address >= Hardware->baseAddress);
-        address -= Hardware->baseAddress;
-    }
-
-    /* Return hardware specific address. */
-    *Address = (Hardware->mmuVersion == 0)
-             ?
- ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:31) - (0 ?
- 31:31) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:31) - (0 ?
- 31:31) + 1))))))) << (0 ?
- 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
- 31:31) - (0 ?
- 31:31) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
-               | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 30:0) - (0 ?
- 30:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 30:0) - (0 ?
- 30:0) + 1))))))) << (0 ?
- 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ?
- 30:0) - (0 ?
- 30:0) + 1) == 32) ?
- ~0U : (~(~0U << ((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;
-}
-
-static void
-_ResumeWaitLinkFE(
-    gckHARDWARE Hardware
-    )
-{
-    gctUINT32 resume;
-    gctUINT32 bytes;
-    gctUINT32 idle;
-
-    /* Make sure FE is idle. */
-    do
-    {
-        gckOS_ReadRegisterEx(Hardware->os,
-                             Hardware->core,
-                             0x00004,
-                             &idle);
-    }
-    while (idle != 0x7FFFFFFF);
-
-    gckOS_ReadRegisterEx(Hardware->os,
-                         Hardware->core,
-                         0x00664,
-                         &resume);
-
-    gckOS_ReadRegisterEx(Hardware->os,
-                         Hardware->core,
-                         0x00664,
-                         &resume);
-
-    /* Determine the wait-link command size. */
-    bytes = Hardware->hasL2Cache ? 24 : 16;
-
-    /* Start Command Parser. */
-    gckHARDWARE_AtomicExecute(Hardware, resume, bytes);
-}
-
-/*******************************************************************************
-**
-**  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 = 0;
-    gctUINT32 dataEx;
-    gceSTATUS status;
-    gceSTATUS statusEx;
-
-    /* Extract gckEVENT object. */
-    eventObj = Hardware->kernel->eventObj;
-
-    if (InterruptValid)
-    {
-        /*
-         * Notice:
-         * In isr here.
-         * We should return success when either FE or AsyncFE reports correct
-         * interrupts, so that isr can wake up threadRoutine for either FE.
-         * That means, only need return ERROR when both FEs reports ERROR.
-         */
-        /* Read AQIntrAcknowledge register. */
-        status = gckOS_ReadRegisterEx(Hardware->os,
-                                      Hardware->core,
-                                      0x00010,
-                                      &data);
-
-        if (gcmIS_ERROR(status))
-        {
-            goto OnError;
-        }
-
-        if (data == 0)
-        {
-            /* Not our interrupt. */
-            status = gcvSTATUS_NOT_OUR_INTERRUPT;
-        }
-        else
-        {
-#if gcdINTERRUPT_STATISTIC
-            gckOS_AtomClearMask(Hardware->pendingEvent, data);
-#endif
-            if (data & (1 << 29))
-            {
-                /* Event ID 29 is not a normal event, but for invalidating pipe. */
-                _ResumeWaitLinkFE(Hardware);
-                data &= ~(1 << 29);
-            }
-
-            /* Inform gckEVENT of the interrupt. */
-            status = gckEVENT_Interrupt(eventObj, data);
-        }
-
-        if (!Hardware->hasAsyncFe)
-        {
-            /* Done. */
-            goto OnError;
-        }
-
-        /* Read BLT interrupt. */
-        statusEx = gckOS_ReadRegisterEx(
-            Hardware->os,
-            Hardware->core,
-            0x000D4,
-            &dataEx
-            );
-
-        if (gcmIS_ERROR(statusEx))
-        {
-            /*
-             * Do not overwrite status here, so that former status from
-             * AQIntrAck is returned.
-             */
-            goto OnError;
-        }
-
-        /*
-         * This bit looks useless now, we can use this check if this interrupt
-         * is from FE.
-         */
-        dataEx &= ~0x80000000;
-
-        /*
-         * Descriptor fetched, update counter.
-         * We can't do this at dataEx != 0 only, because read HW acknowledge
-         * register will overwrite 0x007E4. If one
-         * interrupt we don't read it, we will miss it for ever.
-         */
-        gckFE_UpdateAvaiable(Hardware, &Hardware->kernel->asyncCommand->fe);
-
-        /* Do not need report NOT_OUT_INTERRUPT error if dataEx is 0. */
-        if (dataEx)
-        {
-            statusEx = gckEVENT_Interrupt(Hardware->kernel->asyncEvent, dataEx);
-
-            if (gcmIS_SUCCESS(statusEx))
-            {
-                /* At least AsyncFE is success, treat all as success. */
-                status = gcvSTATUS_OK;
-            }
-        }
-    }
-    else
-    {
-        /* Handle events. */
-        status = gckEVENT_Notify(eventObj, 0);
-
-        if (Hardware->hasAsyncFe)
-        {
-            status = gckEVENT_Notify(Hardware->kernel->asyncEvent, 0);
-        }
-    }
-
-OnError:
-    /* Return the status. */
-    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,
-    IN gceENGINE Engine,
-    OUT gctUINT32 * Alignment,
-    OUT gctUINT32 * ReservedHead,
-    OUT gctUINT32 * 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)
-    {
-        if (Engine == gcvENGINE_RENDER)
-        {
-            gcmkFOOTER_NO();
-            return gcvSTATUS_NOT_SUPPORTED;
-        }
-        else
-        {
-            *ReservedTail = gcdBLT_FENCE_LENGTH;
-        }
-    }
-
-    /* Success. */
-    gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu",
-                   gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead),
-                   gcmOPT_VALUE(ReservedTail));
-    return gcvSTATUS_OK;
-}
+}
 
 /*******************************************************************************
 **
@@ -5488,113 +4672,6 @@ gckHARDWARE_QuerySystemMemory(
     return gcvSTATUS_OK;
 }
 
-#if gcdENABLE_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.
-**
-**      gctBOOL * UnifiedUnforms
-**          Pointer to a variable receiving whether the uniformas are unified.
-*/
-gceSTATUS
-gckHARDWARE_QueryShaderCaps(
-    IN gckHARDWARE Hardware,
-    OUT gctUINT * VertexUniforms,
-    OUT gctUINT * FragmentUniforms,
-    OUT gctBOOL * UnifiedUnforms
-    )
-{
-    gctBOOL unifiedConst;
-    gctUINT32 vsConstMax;
-    gctUINT32 psConstMax;
-    gctUINT32 vsConstBase;
-    gctUINT32 psConstBase;
-    gctUINT32 ConstMax;
-    gctBOOL   halti5;
-
-    gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x "
-                   "FragmentUniforms=0x%x UnifiedUnforms=0x%x",
-                   Hardware, VertexUniforms,
-                   FragmentUniforms, UnifiedUnforms);
-
-    halti5 = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI5);
-
-    {if (Hardware->identity.numConstants > 256){    unifiedConst = gcvTRUE;
-if (halti5){    vsConstBase  = 0xD000;
-    psConstBase  = 0xD800;
-}else{    vsConstBase  = 0xC000;
-    psConstBase  = 0xC000;
-}if ((Hardware->identity.chipModel == gcv880) && ((Hardware->identity.chipRevision & 0xfff0) == 0x5120)){    vsConstMax   = 512;
-    psConstMax   = 64;
-    ConstMax     = 576;
-}else{    vsConstMax   = gcmMIN(512, Hardware->identity.numConstants - 64);
-    psConstMax   = gcmMIN(512, Hardware->identity.numConstants - 64);
-    ConstMax     = Hardware->identity.numConstants;
-}}else if (Hardware->identity.numConstants == 256){    if (Hardware->identity.chipModel == gcv2000 && (Hardware->identity.chipRevision == 0x5118 || Hardware->identity.chipRevision == 0x5140))    {        unifiedConst = gcvFALSE;
-        vsConstBase  = 0x1400;
-        psConstBase  = 0x1C00;
-        vsConstMax   = 256;
-        psConstMax   = 64;
-        ConstMax     = 320;
-    }    else    {        unifiedConst = gcvFALSE;
-        vsConstBase  = 0x1400;
-        psConstBase  = 0x1C00;
-        vsConstMax   = 256;
-        psConstMax   = 256;
-        ConstMax     = 512;
-    }}else{    unifiedConst = gcvFALSE;
-    vsConstBase  = 0x1400;
-    psConstBase  = 0x1C00;
-    vsConstMax   = 168;
-    psConstMax   = 64;
-    ConstMax     = 232;
-}};
-
-
-    if (VertexUniforms != gcvNULL)
-    {
-        /* Return the vs shader const count. */
-        *VertexUniforms = vsConstMax;
-    }
-
-    if (FragmentUniforms != gcvNULL)
-    {
-        /* Return the ps shader const count. */
-        *FragmentUniforms = psConstMax;
-    }
-
-    if (UnifiedUnforms != gcvNULL)
-    {
-        /* Return whether the uniformas are unified. */
-        *UnifiedUnforms = unifiedConst;
-    }
-
-    psConstBase = psConstBase;
-    vsConstBase = vsConstBase;
-    ConstMax = ConstMax;
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-#endif
-
 /*******************************************************************************
 **
 **  gckHARDWARE_SetMMU
@@ -5606,8 +4683,8 @@ if (halti5){    vsConstBase  = 0xD000;
 **      gckHARDWARE Harwdare
 **          Pointer to an gckHARDWARE object.
 **
-**      gctPOINTER Logical
-**          Logical address of the page table.
+**      gckMMU Mmu
+**          Pointer to mmu object.
 **
 **  OUTPUT:
 **
@@ -5616,30 +4693,23 @@ if (halti5){    vsConstBase  = 0xD000;
 gceSTATUS
 gckHARDWARE_SetMMU(
     IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical
+    IN gckMMU Mmu
     )
 {
     gceSTATUS status;
     gctUINT32 address = 0;
     gctUINT32 idle;
     gctUINT32 timer = 0, delay = 1;
-    gctPHYS_ADDR_T physical;
 
-    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical);
+    gcmkHEADER_ARG("Hardware=0x%x Mmu=0x%x", Hardware, Mmu);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
 
     if (Hardware->mmuVersion == 0)
     {
-        gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-
-        /* Convert the logical address into physical address. */
-        gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, Logical, &physical));
-
-        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
-
-        gcmkSAFECASTPHYSADDRT(address, physical);
+        /* mmu v0 only support 1 level translation, only uses stlb level mapping. */
+        gcmkSAFECASTPHYSADDRT(address, Mmu->dynamicArea4K.stlbPhysical);
 
         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
                        "Setting page table to 0x%08X",
@@ -5727,11 +4797,14 @@ gckHARDWARE_SetMMU(
 
             Hardware->lastEnd = function->endAddress;
 
-            *(endLogical + 1) = Hardware->executeCount + 1;
+            if (Hardware->wlFE)
+            {
+                /* Append a executeCount in End command, MCFE does not support such End command. */
+                *(endLogical + 1) = Hardware->executeCount + 1;
+            }
 
             if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
             {
-                gctUINT32_PTR safeLogical = Hardware->kernel->mmu->safePageLogical;
                 gctUINT32 extSafeAddress;
                 /* Set up base address of page table array. */
                 gcmkONERROR(gckOS_WriteRegisterEx(
@@ -5755,14 +4828,8 @@ gckHARDWARE_SetMMU(
                     1
                     ));
 
-                gcmkONERROR(
-                    gckOS_GetPhysicalAddress(Hardware->os, safeLogical, &physical));
-
-                gcmkVERIFY_OK(
-                    gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
-
-                address = (gctUINT32)(physical & 0xFFFFFFFF);
-                extSafeAddress = (gctUINT32)(physical >> 32);
+                address = (gctUINT32)(Mmu->safePagePhysical & 0xFFFFFFFF);
+                extSafeAddress = (gctUINT32)(Mmu->safePagePhysical >> 32);
 
                 if (address & 0x3F)
                 {
@@ -5775,25 +4842,25 @@ gckHARDWARE_SetMMU(
                     gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
                 }
 
-                gckOS_WriteRegisterEx(
+                gcmkONERROR(gckOS_WriteRegisterEx(
                     Hardware->os,
                     Hardware->core,
                     0x0039C,
                     address
-                    );
+                    ));
 
-                gckOS_WriteRegisterEx(
+                gcmkONERROR(gckOS_WriteRegisterEx(
                     Hardware->os,
                     Hardware->core,
                     0x00398,
                     address
-                    );
+                    ));
 
-                gckOS_WriteRegisterEx(
+                gcmkONERROR(gckOS_WriteRegisterEx(
                     Hardware->os,
                     Hardware->core,
                     0x003A0,
-                    (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  23:16) - (0 ?
  23:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -5802,10 +4869,8 @@ gckHARDWARE_SetMMU(
  23:16))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)extSafeAddress) & ((gctUINT32) ((((1 ?
  23:16) - (0 ?
  23:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 23:16) - (0 ?
- 23:16) + 1))))))) << (0 ?
- 23:16))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:31) - (0 ?
  31:31) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -5814,8 +4879,8 @@ gckHARDWARE_SetMMU(
  31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  31:31) - (0 ?
  31:31) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))))
-                  | (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  7:0) - (0 ?
  7:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -5824,10 +4889,8 @@ gckHARDWARE_SetMMU(
  7:0))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)extSafeAddress) & ((gctUINT32) ((((1 ?
  7:0) - (0 ?
  7:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 7:0) - (0 ?
- 7:0) + 1))))))) << (0 ?
- 7:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:15) - (0 ?
  15:15) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -5836,16 +4899,37 @@ gckHARDWARE_SetMMU(
  15:15))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  15:15) - (0 ?
  15:15) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))))
-                    );
+ ~0U : (~(~0U << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15)))
+                    ));
             }
 
-            /* Execute prepared command sequence. */
-            gcmkONERROR(gckHARDWARE_Execute(
-                Hardware,
+            gcmkDUMP(Hardware->os, "#[function: set mmu]");
+            gcmkDUMP_BUFFER(
+                Hardware->os,
+                gcvDUMP_BUFFER_KERNEL_COMMAND,
+                function->logical,
                 function->address,
-                function->bytes
-                ));
+                function->bytes);
+
+            /* Execute prepared command sequence. */
+            if (Hardware->mcFE)
+            {
+                gcmkONERROR(gckMCFE_Execute(
+                    Hardware,
+                    gcvFALSE,
+                    0,
+                    function->address,
+                    function->bytes
+                    ));
+            }
+            else
+            {
+                gcmkONERROR(gckWLFE_Execute(
+                    Hardware,
+                    function->address,
+                    function->bytes
+                    ));
+            }
 
 #if gcdLINK_QUEUE_SIZE
             {
@@ -5880,7 +4964,11 @@ gckHARDWARE_SetMMU(
                 if (timer >= Hardware->kernel->timeOut)
                 {
                     gckHARDWARE_DumpGPUState(Hardware);
-                    gckCOMMAND_DumpExecutingBuffer(Hardware->kernel->command);
+
+                    if (Hardware->kernel->command)
+                    {
+                        gckCOMMAND_DumpExecutingBuffer(Hardware->kernel->command);
+                    }
 
                     /* Even if hardware is not reset correctly, let software
                     ** continue to avoid software stuck. Software will timeout again
@@ -5892,10 +4980,24 @@ gckHARDWARE_SetMMU(
             }
             while (!(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ));
 
+            gcmkDUMP(Hardware->os, "@[register.wait 0x%05X 0x%08X 0x%08X]",
+                     0x00004,
+                     ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (~0U) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))),
+                     idle);
+
             /* Enable MMU. */
             if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
             {
-                gcmkONERROR(gckOS_WriteRegisterEx(
+                gcmkONERROR(gckOS_WriteRegisterEx_NoDump(
                     Hardware->os,
                     Hardware->core,
                     0x00388,
@@ -5942,32 +5044,73 @@ OnError:
     return status;
 }
 
+/*******************************************************************************
+**
+**  gckHARDWARE_FlushMMU
+**
+**  Flush the page table.
+**
+**  INPUT:
+**
+**      gckHARDWARE Harwdare
+**          Pointer to an gckHARDWARE object.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
 gceSTATUS
-gckHARDWARE_FlushAsyncMMU(
+gckHARDWARE_FlushMMU(
     IN gckHARDWARE Hardware,
     IN gctPOINTER Logical,
+    IN gctUINT32 Address,
+    IN gctUINT32 SubsequentBytes,
     IN OUT gctUINT32 * Bytes
     )
 {
-    gctUINT32 semaphore, stall;
-    gctUINT32_PTR buffer;
     gceSTATUS status;
+    gctUINT32_PTR buffer;
+    gctUINT32 flushSize;
+    gctBOOL bltEngine = gcvFALSE;
+    gctBOOL multiCluster = gcvFALSE;
 
-    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
-                   Hardware, Logical, gcmOPT_VALUE(Bytes));
+    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+    if (Hardware->mmuVersion == 0)
+    {
+        flushSize = 8;
+    }
+    else
+    {
+        flushSize = 10 * 4;
 
-    if (Logical != gcvNULL)
+        bltEngine    = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE);
+        multiCluster = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MULTI_CLUSTER);
+
+        if (bltEngine)
+        {
+            flushSize +=  4 * 4;
+
+            if (multiCluster)
+            {
+                flushSize += 2 * 4;
+            }
+        }
+    }
+
+    if (Logical)
     {
-        buffer = (gctUINT32_PTR) Logical;
+        if (*Bytes < flushSize)
+        {
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+        }
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        /* Flush the memory controller. */
+        if (Hardware->mmuVersion == 0)
+        {
+            buffer = (gctUINT32_PTR)Logical;
+
+            buffer[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -5977,17 +5120,17 @@ gckHARDWARE_FlushAsyncMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E04) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -5996,13 +5139,9 @@ gckHARDWARE_FlushAsyncMMU(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            ));
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 1,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            buffer[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6012,12 +5151,93 @@ gckHARDWARE_FlushAsyncMMU(
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-            ));
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1))))))) << (0 ?
+ 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 1:1) - (0 ?
+ 1:1) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1))))))) << (0 ?
+ 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 2:2) - (0 ?
+ 2:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1))))))) << (0 ?
+ 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 3:3) - (0 ?
+ 3:3) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+        }
+        else
+        {
+            gctUINT32 count;
+            gctUINT32 offset = 2;
+            gctUINT32 prefetchCount = 4;
+            gctUINT32 semaphore, stall;
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 2,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            if (bltEngine)
+            {
+                prefetchCount += 2;
+                if (multiCluster)
+                {
+                    prefetchCount++;
+                }
+            }
+
+            buffer = (gctUINT32_PTR)Logical;
+
+            count = SubsequentBytes >> 3;
+
+            /* LINK to next slot to flush FE FIFO. */
+            *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (prefetchCount) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *buffer++ = Address + offset * gcmSIZEOF(gctUINT32);
+
+            /* Flush MMU cache. */
+            *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6027,7 +5247,7 @@ gckHARDWARE_FlushAsyncMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6037,7 +5257,7 @@ gckHARDWARE_FlushAsyncMMU(
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6046,13 +5266,9 @@ gckHARDWARE_FlushAsyncMMU(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-          ));
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 3,
-            (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++ = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:4) - (0 ?
  4:4) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6073,13 +5289,12 @@ gckHARDWARE_FlushAsyncMMU(
  7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  7:7) - (0 ?
  7:7) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))))
-            ));
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 4,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            if (bltEngine)
+            {
+                /* Blt lock. */
+                *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6089,7 +5304,7 @@ gckHARDWARE_FlushAsyncMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6099,7 +5314,96 @@ gckHARDWARE_FlushAsyncMMU(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+                if (multiCluster)
+                {
+                    *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x50CE) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                    *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.clusterAvailMask & Hardware->options.userClusterMask) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
+                }
+            }
+
+            /* Arm the PE-FE Semaphore. */
+            *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6108,10 +5412,9 @@ gckHARDWARE_FlushAsyncMMU(
  15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-            ));
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-        semaphore = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            semaphore = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6120,21 +5423,11 @@ gckHARDWARE_FlushAsyncMMU(
  4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
 
-        if (Hardware->stallFEPrefetch)
-        {
-            semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            if (Hardware->stallFEPrefetch)
+            {
+                semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  29:28) - (0 ?
  29:28) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6144,17 +5437,39 @@ gckHARDWARE_FlushAsyncMMU(
  29:28) - (0 ?
  29:28) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 29:28) - (0 ? 29:28) + 1))))))) << (0 ? 29:28)));
-        }
+            }
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 5,
-            semaphore));
+            if (bltEngine)
+            {
+                semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            }
+            else
+            {
+                semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            }
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 6,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++ = semaphore;
+
+            /* STALL FE until PE is done flushing. */
+            *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6163,10 +5478,9 @@ gckHARDWARE_FlushAsyncMMU(
  31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            ));
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
 
-        stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6175,21 +5489,11 @@ gckHARDWARE_FlushAsyncMMU(
  4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
 
-        if (Hardware->stallFEPrefetch)
-        {
-           stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            if (Hardware->stallFEPrefetch)
+            {
+               stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  29:28) - (0 ?
  29:28) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6199,17 +5503,41 @@ gckHARDWARE_FlushAsyncMMU(
  29:28) - (0 ?
  29:28) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 29:28) - (0 ? 29:28) + 1))))))) << (0 ? 29:28)));
-        }
+            }
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 7,
-            stall));
+            if (bltEngine)
+            {
+                stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            }
+            else
+            {
+                stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            }
 
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 8,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++ = stall;
+
+            if (bltEngine)
+            {
+                /* Blt unlock. */
+                *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6219,17 +5547,7 @@ gckHARDWARE_FlushAsyncMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6239,226 +5557,147 @@ gckHARDWARE_FlushAsyncMMU(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-          ));
-
-        gcmkONERROR(gckOS_WriteMemory(
-            Hardware->os,
-            buffer + 9,
-            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-            ));
-    }
-
-    if (Bytes != gcvNULL)
-    {
-        /* Return number of bytes required by the PIPESELECT command. */
-        *Bytes = 40;
-    }
-
-    /* Success. */
-    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Success. */
-    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
-    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;
-    gctUINT32 bufferSize;
-    gctPOINTER pointer = gcvNULL;
-    gctUINT32 flushSize;
-    gctUINT32 count, offset;
-    gctUINT32 address;
-    gctUINT32 semaphore, stall;
-
-    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-
-    /* Verify the gckCOMMAND object pointer. */
-    command = Hardware->kernel->command;
-
-    /* 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) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E04) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-        buffer[1]
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  0:0) - (0 ?
  0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 2:2) - (0 ?
- 2:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 2:2) - (0 ?
- 2:2) + 1))))))) << (0 ?
- 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 2:2) - (0 ?
- 2:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 3:3) - (0 ?
- 3:3) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 3:3) - (0 ?
- 3:3) + 1))))))) << (0 ?
- 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 3:3) - (0 ?
- 3:3) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+            }
+
+            /* LINK to next slot to flush FE FIFO. */
+            *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 4:4) - (0 ?
- 4:4) + 1))))))) << (0 ?
- 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (count) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
 
-        gcmkONERROR(gckCOMMAND_Execute(command, 8));
+            *buffer++ = Address + flushSize;
+        }
     }
-    else
+
+    if (Bytes)
     {
-        gctUINT32 prefetchCount = 4;
-        gctBOOL bltEngine = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE);
+        *Bytes = flushSize;
+    }
 
-        flushSize = 10 * 4;
-        offset = 2;
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
 
-        if (bltEngine)
-        {
-            flushSize +=  4 * 4;
-            prefetchCount += 2;
-        }
+OnError:
 
-        gcmkONERROR(gckCOMMAND_Reserve(
-            command, flushSize, &pointer, &bufferSize
-            ));
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckHARDWARE_FlushAsyncMMU(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+    gctUINT32 semaphore, stall;
+    gctUINT32_PTR buffer;
+    gceSTATUS status;
 
-        buffer = (gctUINT32_PTR) pointer;
+    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu",
+                   Hardware, Logical, gcmOPT_VALUE(Bytes));
 
-        count = ((gctUINT)bufferSize - flushSize + 7) >> 3;
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
 
-        address = command->address + command->offset;
+    if (Logical != gcvNULL)
+    {
+        buffer = (gctUINT32_PTR) Logical;
 
-        /* LINK to next slot to flush FE FIFO. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (prefetchCount) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+            ));
 
-        *buffer++
-            = address + offset * gcmSIZEOF(gctUINT32);
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 1,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+            ));
 
-        /* Flush MMU cache. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 2,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6468,7 +5707,7 @@ gckHARDWARE_FlushMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6478,7 +5717,7 @@ gckHARDWARE_FlushMMU(
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6487,10 +5726,13 @@ gckHARDWARE_FlushMMU(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+          ));
 
-        *buffer++
-            = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 3,
+            (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:4) - (0 ?
  4:4) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6511,59 +5753,13 @@ gckHARDWARE_FlushMMU(
  7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  7:7) - (0 ?
  7:7) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
-
-        if (bltEngine)
-        {
-            /* Blt lock. */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
-        }
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))))
+            ));
 
-        /* Arm the PE-FE Semaphore. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 4,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6592,7 +5788,8 @@ gckHARDWARE_FlushMMU(
  15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+            ));
 
         semaphore = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
@@ -6603,7 +5800,17 @@ gckHARDWARE_FlushMMU(
  4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
         if (Hardware->stallFEPrefetch)
         {
@@ -6619,39 +5826,15 @@ gckHARDWARE_FlushMMU(
  ~0U : (~(~0U << ((1 ? 29:28) - (0 ? 29:28) + 1))))))) << (0 ? 29:28)));
         }
 
-        if (bltEngine)
-        {
-            semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-        }
-        else
-        {
-            semaphore |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-        }
-
-        *buffer++
-            = semaphore;
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 5,
+            semaphore));
 
-        /* STALL FE until PE is done flushing. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 6,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6660,7 +5843,8 @@ gckHARDWARE_FlushMMU(
  31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            ));
 
         stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
@@ -6671,7 +5855,17 @@ gckHARDWARE_FlushMMU(
  4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
+              | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1))))))) << (0 ?
+ 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
+ 12:8) - (0 ?
+ 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
 
         if (Hardware->stallFEPrefetch)
         {
@@ -6687,41 +5881,15 @@ gckHARDWARE_FlushMMU(
  ~0U : (~(~0U << ((1 ? 29:28) - (0 ? 29:28) + 1))))))) << (0 ? 29:28)));
         }
 
-        if (bltEngine)
-        {
-            stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x10 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-        }
-        else
-        {
-            stall |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-        }
-
-        *buffer++
-            = stall;
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 7,
+            stall));
 
-        if (bltEngine)
-        {
-            /* Blt unlock. */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 8,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6731,7 +5899,17 @@ gckHARDWARE_FlushMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+          | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6741,19 +5919,12 @@ gckHARDWARE_FlushMMU(
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+          ));
 
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        gcmkONERROR(gckOS_WriteMemory(
+            Hardware->os,
+            buffer + 9,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -6762,36 +5933,191 @@ gckHARDWARE_FlushMMU(
  0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
+            ));
+    }
+
+    if (Bytes != gcvNULL)
+    {
+        /* Return number of bytes required by the PIPESELECT command. */
+        *Bytes = 40;
+    }
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Success. */
+    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+    return status;
+}
+
+gceSTATUS
+gckHARDWARE_FlushMcfeMMU(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+    gceSTATUS status;
+    gctUINT32_PTR buffer;
+    gctUINT32 flushSize;
+
+    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+    /* MCFE with old mmu? nonsense!. */
+    gcmkASSERT(Hardware->mmuVersion > 0);
+
+    flushSize = 4 * 6;
+
+    if (Logical)
+    {
+        if (*Bytes < flushSize)
+        {
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
         }
 
-        /* LINK to next slot to flush FE FIFO. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        buffer = (gctUINT32_PTR)Logical;
+
+        /* Flush MMU cache. */
+        *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (count) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-        *buffer++
-            = address + flushSize;
+        *buffer++ = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:4) - (0 ?
+ 4:4) + 1))))))) << (0 ?
+ 4:4))) &  ((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
+
+        /*
+         * System channel can only take one command at a time, Trigger and
+         * SubmitJob are not required.
+         */
+
+        /* AQHiIdle to trigger. */
+        *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0001) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+        *buffer++ = 0;
+
+        /* SubmitJob. */
+        *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+                  | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_SUBMIT_JOB & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)));
+
+        *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+    }
 
-        gcmkONERROR(gckCOMMAND_Execute(command, flushSize));
+    if (Bytes)
+    {
+        *Bytes = flushSize;
     }
 
     /* Success. */
@@ -6803,26 +6129,27 @@ OnError:
     /* Return the status. */
     gcmkFOOTER();
     return status;
+#else
+    return gcvSTATUS_NOT_SUPPORTED;
+#endif
 }
 
-gceSTATUS
-gckHARDWARE_SetMMUStates(
+static gceSTATUS
+_ProgramMMUStates(
     IN gckHARDWARE Hardware,
-    IN gctPOINTER MtlbAddress,
+    IN gckMMU Mmu,
     IN gceMMU_MODE Mode,
-    IN gctPOINTER SafeAddress,
     IN gctPOINTER Logical,
     IN OUT gctUINT32 * Bytes
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     gctUINT32 config, address;
     gctUINT32 extMtlb, extSafeAddress, configEx = 0;
     gctPHYS_ADDR_T physical;
     gctUINT32_PTR buffer;
     gctBOOL ace;
     gctUINT32 reserveBytes = 0;
-    gcsMMU_TABLE_ARRAY_ENTRY * entry;
 
     gctBOOL config2D;
 
@@ -6832,8 +6159,6 @@ gckHARDWARE_SetMMUStates(
     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
     gcmkVERIFY_ARGUMENT(Hardware->mmuVersion != 0);
 
-    entry = (gcsMMU_TABLE_ARRAY_ENTRY *) Hardware->pagetableArray.logical;
-
     ace = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ACE);
 
     switch (Hardware->options.secureMode)
@@ -6876,12 +6201,7 @@ gckHARDWARE_SetMMUStates(
 
     reserveBytes += 8;
 
-    /* Convert logical address into physical address. */
-    gcmkONERROR(
-        gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &physical));
-
-    gcmkVERIFY_OK(
-        gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
+    physical = Mmu->mtlbPhysical;
 
     config  = (gctUINT32)(physical & 0xFFFFFFFF);
     extMtlb = (gctUINT32)(physical >> 32);
@@ -6892,11 +6212,7 @@ gckHARDWARE_SetMMUStates(
         gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
     }
 
-    gcmkONERROR(
-        gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &physical));
-
-    gcmkVERIFY_OK(
-        gckOS_CPUPhysicalToGPUPhysical(Hardware->os, physical, &physical));
+    physical = Mmu->safePagePhysical;
 
     address = (gctUINT32)(physical & 0xFFFFFFFF);
     extSafeAddress = (gctUINT32)(physical >> 32);
@@ -6981,118 +6297,43 @@ gckHARDWARE_SetMMUStates(
     }
 
     if (Logical != gcvNULL)
-    {
-        buffer = Logical;
-
-        if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
-        {
-            /* Setup page table array entry. */
-            if (Hardware->bigEndian)
-            {
-                entry->low = gcmBSWAP32(config);
-                entry->high = gcmBSWAP32(extMtlb);
-            }
-            else
-            {
-                entry->low = config;
-                entry->high = extMtlb;
-            }
-
-            /* Setup command buffer to load index 0 of page table array. */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x006B) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
-
-            *buffer++
-                = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 16:16) - (0 ?
- 16:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 16:16) - (0 ?
- 16:16) + 1))))))) << (0 ?
- 16:16))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
- 16:16) - (0 ?
- 16:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))));
-        }
-        else
+    {
+        buffer = Logical;
+
+        if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
         {
-            gcmkASSERT(Hardware->options.secureMode == gcvSECURE_NONE);
+            gcsMMU_TABLE_ARRAY_ENTRY * entry;
+            entry = (gcsMMU_TABLE_ARRAY_ENTRY *) Hardware->pagetableArray.logical;
 
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+            /* Setup page table array entry. */
+            if (Hardware->bigEndian)
+            {
+                entry->low = gcmBSWAP32(config);
+                entry->high = gcmBSWAP32(extMtlb);
+            }
+            else
+            {
+                entry->low = config;
+                entry->high = extMtlb;
+            }
 
-            *buffer++ = config;
+            gcmkDUMP(Mmu->os, "#[mmu: page table array]");
 
+            gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)Hardware->pagetableArray.address, entry->low, 4);
+
+            gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)Hardware->pagetableArray.address + 4, entry->high, 4);
+
+            gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
+                Hardware->kernel,
+                Hardware->pagetableArray.videoMem,
+                0,
+                entry,
+                8
+                ));
+
+            /* Setup command buffer to load index 0 of page table array. */
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
@@ -7110,7 +6351,7 @@ gckHARDWARE_SetMMUStates(
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x006B) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
@@ -7125,215 +6366,33 @@ gckHARDWARE_SetMMUStates(
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-            *buffer++ = address;
-
-            if (ace)
-            {
-                *buffer++
-                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++
+                = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0068) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
-
-                *buffer++
-                    = configEx;
-            }
-        }
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E12) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  16:16) - (0 ?
  16:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  16:16) - (0 ?
  16:16) + 1))))))) << (0 ?
- 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 16:16))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  16:16) - (0 ?
  16:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
-
-        do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);
-;
-
-
-        if (config2D)
-        {
-            /* LoadState(AQPipeSelect, 1), pipe. */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
-
-            *buffer++ = 0x1;
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))));
+        }
+        else
+        {
+            gcmkASSERT(Hardware->options.secureMode == gcvSECURE_NONE);
 
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -7440,8 +6499,53 @@ gckHARDWARE_SetMMUStates(
                 *buffer++
                     = configEx;
             }
+        }
 
-            do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        *buffer++
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E12) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+        *buffer++
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
+
+        do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7529,6 +6633,8 @@ gckHARDWARE_SetMMUStates(
 ;
 
 
+        if (config2D)
+        {
             /* LoadState(AQPipeSelect, 1), pipe. */
             *buffer++
                 = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -7562,9 +6668,10 @@ gckHARDWARE_SetMMUStates(
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-            *buffer++ = 0x0;
+            *buffer++ = 0x1;
 
-            do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7573,10 +6680,18 @@ gckHARDWARE_SetMMUStates(
  31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7585,260 +6700,83 @@ gckHARDWARE_SetMMUStates(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+            *buffer++ = config;
+
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+            *buffer++ = address;
+
+            if (ace)
+            {
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);
-;
-
-        }
-
-    }
-
-    if (Bytes != gcvNULL)
-    {
-        *Bytes = reserveBytes;
-    }
-
-    /* Return the status. */
-    gcmkFOOTER_NO();
-    return status;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-#if gcdPROCESS_ADDRESS_SPACE
-/*******************************************************************************
-**
-**  gckHARDWARE_ConfigMMU
-**
-**  Append a MMU Configuration command sequence at the specified location in the command
-**  queue. That command sequence consists of mmu configuration, LINK and WAIT/LINK.
-**  LINK is fetched and paresed with new mmu configuration.
-**
-**  If MMU Configuration is not changed between commit, change last WAIT/LINK to
-**  link to ENTRY.
-**
-**  -+-----------+-----------+-----------------------------------------
-**   | WAIT/LINK | WAIT/LINK |
-**  -+-----------+-----------+-----------------------------------------
-**         |          /|\
-**        \|/          |
-**    +--------------------+
-**    | ENTRY | ... | LINK |
-**    +--------------------+
-**
-**  If MMU Configuration is changed between commit, change last WAIT/LINK to
-**  link to MMU CONFIGURATION command sequence, and there are an EVNET and
-**  an END at the end of this command sequence, when interrupt handler
-**  receives this event, it will start FE at ENTRY to continue the command
-**  buffer execution.
-**
-**  -+-----------+-------------------+---------+---------+-----------+--
-**   | WAIT/LINK | MMU CONFIGURATION |  EVENT  |  END    | WAIT/LINK |
-**  -+-----------+-------------------+---------+---------+-----------+--
-**        |            /|\                                   /|\
-**        +-------------+                                     |
-**                                          +--------------------+
-**                                          | ENTRY | ... | LINK |
-**                                          +--------------------+
-**  INPUT:
-**
-**      gckHARDWARE Hardware
-**          Pointer to an gckHARDWARE object.
-**
-**      gctPOINTER Logical
-**          Pointer to the current location inside the command queue to append
-**          command sequence at or gcvNULL just to query the size of the
-**          command sequence.
-**
-**      gctPOINTER MtlbLogical
-**          Pointer to the current Master TLB.
-**
-**      gctUINT32 Offset
-**          Offset into command buffer required for alignment.
-**
-**      gctSIZE_T * Bytes
-**          Pointer to the number of bytes available for the 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 command sequence.  If 'Bytes' is gcvNULL, nothing will
-**          be returned.
-**
-**      gctUINT32 * WaitLinkOffset
-**          Pointer to a variable that will receive the offset of the WAIT/LINK command
-**          from the specified logcial pointer.
-**          If 'WaitLinkOffset' is gcvNULL nothing will be returned.
-**
-**      gctSIZE_T * WaitLinkBytes
-**          Pointer to a variable that will receive the number of bytes used by
-**          the WAIT command.
-**          If 'WaitLinkBytes' is gcvNULL nothing will be returned.
-*/
-gceSTATUS
-gckHARDWARE_ConfigMMU(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctPOINTER MtlbLogical,
-    IN gctUINT32 Offset,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctSIZE_T * WaitLinkOffset,
-    OUT gctSIZE_T * WaitLinkBytes
-    )
-{
-    gceSTATUS status;
-    gctSIZE_T bytes, bytesAligned;
-    gctUINT32 config;
-    gctUINT32_PTR buffer = (gctUINT32_PTR) Logical;
-    gctPHYS_ADDR_T physical;
-    gctUINT32 address;
-    gctUINT32 event;
-    gctSIZE_T stCmds; /* semaphore stall cmd size */;
-
-    gcmkHEADER_ARG("Hardware=0x%08X Logical=0x%08x MtlbLogical=0x%08X",
-                   Hardware, Logical, MtlbLogical);
-
-    stCmds = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TEX_CACHE_FLUSH_FIX) ? 0 : 4;
-
-    bytes
-        /* Semaphore stall states. */
-        = stCmds * 4
-        /* Flush cache states. */
-        + 20 * 4
-        /* MMU configuration states. */
-        + 6 * 4
-        /* EVENT. */
-        + 2 * 4
-        /* END. */
-        + 2 * 4
-        /* WAIT/LINK. */
-        + 4 * 4;
-
-    /* Compute number of bytes required. */
-    bytesAligned = gcmALIGN(Offset + bytes, 8) - Offset;
-
-    if (buffer != gcvNULL)
-    {
-        if (MtlbLogical == gcvNULL)
-        {
-            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-        }
-
-        /* Get physical address of this command buffer segment. */
-        gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, buffer, &physical));
-
-        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
-            Hardware->os,
-            physical,
-            &physical
-            ));
-
-        gcmkSAFECASTPHYSADDRT(address, physical);
-
-        /* Get physical address of Master TLB. */
-        gcmkONERROR(gckOS_GetPhysicalAddress(Hardware->os, MtlbLogical, &physical));
-
-        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
-            Hardware->os,
-            physical,
-            &physical
-            ));
-
-        gcmkSAFECASTPHYSADDRT(config, physical);
-
-        config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 4:4) - (0 ?
- 4:4) + 1))))))) << (0 ?
- 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0068) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-        if (stCmds)
-        {
-            /* Arm the PE-FE Semaphore. */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                *buffer++
+                    = configEx;
+            }
+
+            do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7847,8 +6785,10 @@ gckHARDWARE_ConfigMMU(
  31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7857,8 +6797,10 @@ gckHARDWARE_ConfigMMU(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7867,10 +6809,7 @@ gckHARDWARE_ConfigMMU(
  15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7879,8 +6818,10 @@ gckHARDWARE_ConfigMMU(
  4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7889,11 +6830,7 @@ gckHARDWARE_ConfigMMU(
  12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-
-            /* STALL FE until PE is done flushing. */
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7902,10 +6839,7 @@ gckHARDWARE_ConfigMMU(
  31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
-
-            *buffer++
-                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7914,8 +6848,10 @@ gckHARDWARE_ConfigMMU(
  4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7924,12 +6860,13 @@ gckHARDWARE_ConfigMMU(
  12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-        }
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);
+;
 
-        /* Flush cache. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+
+            /* LoadState(AQPipeSelect, 1), pipe. */
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -7939,126 +6876,17 @@ gckHARDWARE_ConfigMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 3:3) - (0 ?
- 3:3) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 3:3) - (0 ?
- 3:3) + 1))))))) << (0 ?
- 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 3:3) - (0 ?
- 3:3) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 2:2) - (0 ?
- 2:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 2:2) - (0 ?
- 2:2) + 1))))))) << (0 ?
- 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 2:2) - (0 ?
- 2:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 5:5) - (0 ?
- 5:5) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 5:5) - (0 ?
- 5:5) + 1))))))) << (0 ?
- 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 5:5) - (0 ?
- 5:5) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- AQ_FLUSH_VSHL1_CACHE) - (0 ?
- AQ_FLUSH_VSHL1_CACHE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- AQ_FLUSH_VSHL1_CACHE) - (0 ?
- AQ_FLUSH_VSHL1_CACHE) + 1))))))) << (0 ?
- AQ_FLUSH_VSHL1_CACHE))) | (((gctUINT32) (AQ_FLUSH_VSHL1_CACHE_ENABLE & ((gctUINT32) ((((1 ?
- AQ_FLUSH_VSHL1_CACHE) - (0 ?
- AQ_FLUSH_VSHL1_CACHE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- AQ_FLUSH_VSHL1_CACHE) - (0 ?
- AQ_FLUSH_VSHL1_CACHE) + 1))))))) << (0 ? AQ_FLUSH_VSHL1_CACHE)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- AQ_FLUSH_PSHL1_CACHE) - (0 ?
- AQ_FLUSH_PSHL1_CACHE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- AQ_FLUSH_PSHL1_CACHE) - (0 ?
- AQ_FLUSH_PSHL1_CACHE) + 1))))))) << (0 ?
- AQ_FLUSH_PSHL1_CACHE))) | (((gctUINT32) (AQ_FLUSH_PSHL1_CACHE_ENABLE & ((gctUINT32) ((((1 ?
- AQ_FLUSH_PSHL1_CACHE) - (0 ?
- AQ_FLUSH_PSHL1_CACHE) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- AQ_FLUSH_PSHL1_CACHE) - (0 ?
- AQ_FLUSH_PSHL1_CACHE) + 1))))))) << (0 ? AQ_FLUSH_PSHL1_CACHE)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 6:6) - (0 ?
- 6:6) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 6:6) - (0 ?
- 6:6) + 1))))))) << (0 ?
- 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 6:6) - (0 ?
- 6:6) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
-
-        /* Flush VTS in separate command */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8067,33 +6895,11 @@ gckHARDWARE_ConfigMMU(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:4) - (0 ?
- 4:4) + 1))))))) << (0 ?
- 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4)));
+            *buffer++ = 0x0;
 
-        /* Flush tile status cache. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            do{*buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8102,53 +6908,10 @@ gckHARDWARE_ConfigMMU(
  31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0594) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
-
-        /* Arm the PE-FE Semaphore. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  31:27) - (0 ?
  31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8157,8 +6920,10 @@ gckHARDWARE_ConfigMMU(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8167,10 +6932,7 @@ gckHARDWARE_ConfigMMU(
  15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8179,8 +6941,10 @@ gckHARDWARE_ConfigMMU(
  4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8189,11 +6953,7 @@ gckHARDWARE_ConfigMMU(
  12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-
-        /* STALL FE until PE is done flushing. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8202,10 +6962,7 @@ gckHARDWARE_ConfigMMU(
  31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8214,8 +6971,10 @@ gckHARDWARE_ConfigMMU(
  4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
  4:0) - (0 ?
  4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8224,94 +6983,210 @@ gckHARDWARE_ConfigMMU(
  12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
  12:8) - (0 ?
  12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+ ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));} while(0);
+;
 
-        /* LINK to next slot to flush FE FIFO. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 15:0) - (0 ?
- 15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+        }
 
-        *buffer++
-            = address + (stCmds + 12) * gcmSIZEOF(gctUINT32);
+    }
 
-        /* Configure MMU. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
+    if (Bytes != gcvNULL)
+    {
+        *Bytes = reserveBytes;
+    }
+
+    /* Return the status. */
+    gcmkFOOTER_NO();
+    return status;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_ProgramMMUStatesMCFE(
+    IN gckHARDWARE Hardware,
+    IN gckMMU Mmu,
+    IN gceMMU_MODE Mode,
+    IN gctPOINTER Logical,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+    gceSTATUS status = gcvSTATUS_OK;
+    gctUINT32 config, address;
+    gctUINT32 extMtlb, extSafeAddress, configEx = 0;
+    gctPHYS_ADDR_T physical;
+    gctUINT32_PTR buffer;
+    gctBOOL ace;
+    gctUINT32 reserveBytes = 0;
+
+    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+    gcmkVERIFY_ARGUMENT(Hardware->mmuVersion != 0);
+
+    ace = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ACE);
+
+    switch (Hardware->options.secureMode)
+    {
+    case gcvSECURE_IN_NORMAL:
+        reserveBytes = 8;
+        reserveBytes += 8;
+        break;
+    case gcvSECURE_NONE:
+        reserveBytes = 16;;
+        if (ace)
+        {
+            reserveBytes += 8;
+            reserveBytes += 8;
+        }
+        break;
+    case gcvSECURE_IN_TA:
+    default:
+        gcmkASSERT(gcvFALSE);
+        gcmkPRINT("%s(%d): secureMode is wrong", __FUNCTION__, __LINE__);
+        break;
+    }
+
+    physical = Mmu->mtlbPhysical;
+
+    config  = (gctUINT32)(physical & 0xFFFFFFFF);
+    extMtlb = (gctUINT32)(physical >> 32);
+
+    /* more than 40bit physical address */
+    if (extMtlb & 0xFFFFFF00)
+    {
+        gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+    }
+
+    physical = Mmu->safePagePhysical;
+
+    address = (gctUINT32)(physical & 0xFFFFFFFF);
+    extSafeAddress = (gctUINT32)(physical >> 32);
+
+    if (address & 0x3F)
+    {
+        gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
+    }
+
+    /* more than 40bit physical address */
+    if (extSafeAddress & 0xFFFFFF00)
+    {
+        gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+    }
+
+    if (ace)
+    {
+        configEx = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
15:0) - (0 ?
15:0) + 1))))))) << (0 ?
15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ?
15:0) - (0 ?
15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
7:0) - (0 ?
7:0) + 1))))))) << (0 ?
7:0))) | (((gctUINT32) ((gctUINT32) (extSafeAddress) & ((gctUINT32) ((((1 ?
7:0) - (0 ?
7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+ 23:16) - (0 ?
+ 23:16) + 1))))))) << (0 ?
+ 23:16))) | (((gctUINT32) ((gctUINT32) (extMtlb) & ((gctUINT32) ((((1 ?
+ 23:16) - (0 ?
+ 23:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)));
+    }
 
-        *buffer++
-            = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:4) - (0 ?
- 4:4) + 1))))))) << (0 ?
- 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 4:4) - (0 ?
- 4:4) + 1) == 32) ?
+    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) ?
  ~0U : (~(~0U << ((1 ?
- 4:4) - (0 ?
- 4:4) + 1))))))) << (0 ?
- 4:4))) &  ((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 7:7) - (0 ?
- 7:7) + 1) == 32) ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((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) ?
  ~0U : (~(~0U << ((1 ?
- 7:7) - (0 ?
- 7:7) + 1))))))) << (0 ?
- 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
- 7:7) - (0 ?
- 7:7) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))));
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+        break;
+
+    default:
+        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+    }
+
+    if (Logical != gcvNULL)
+    {
+        buffer = Logical;
+
+        if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+        {
+            gcsMMU_TABLE_ARRAY_ENTRY * entry;
+            entry = (gcsMMU_TABLE_ARRAY_ENTRY *) Hardware->pagetableArray.logical;
+
+            /* Setup page table array entry. */
+            if (Hardware->bigEndian)
+            {
+                entry->low = gcmBSWAP32(config);
+                entry->high = gcmBSWAP32(extMtlb);
+            }
+            else
+            {
+                entry->low = config;
+                entry->high = extMtlb;
+            }
+
+            gcmkDUMP(Mmu->os, "#[mmu: page table array]");
+
+            gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)Hardware->pagetableArray.address, entry->low, 4);
+
+            gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)Hardware->pagetableArray.address + 4, entry->high, 4);
+
+            gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
+                Hardware->kernel,
+                Hardware->pagetableArray.videoMem,
+                0,
+                entry,
+                8
+                ));
 
-        /* Arm the PE-FE Semaphore. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            /* Setup command buffer to load index 0 of page table array. */
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8321,7 +7196,17 @@ gckHARDWARE_ConfigMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x006B) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8330,103 +7215,63 @@ gckHARDWARE_ConfigMMU(
  25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+            *buffer++
+                = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-
-        /* STALL FE until PE is done flushing. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-
-        /* LINK to next slot to flush FE FIFO. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
- 15:0) - (0 ?
- 15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+ 15:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))));
 
-        *buffer++
-            = physical + (stCmds + 20) * 4;
+            *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+            *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+        }
+        else
+        {
+            gcmkASSERT(Hardware->options.secureMode == gcvSECURE_NONE);
 
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8436,7 +7281,7 @@ gckHARDWARE_ConfigMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8446,7 +7291,7 @@ gckHARDWARE_ConfigMMU(
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8457,12 +7302,10 @@ gckHARDWARE_ConfigMMU(
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-        *buffer++
-            = config;
+            *buffer++ = config;
 
-        /* Arm the PE-FE Semaphore. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            *buffer++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8472,87 +7315,33 @@ gckHARDWARE_ConfigMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 25:16) - (0 ?
- 25:16) + 1))))))) << (0 ?
- 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 25:16) - (0 ?
- 25:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
-
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
-
-        /* STALL FE until PE is done flushing. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
31:27) - (0 ?
31:27) + 1))))))) << (0 ?
31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ?
31:27) - (0 ?
31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
25:16) - (0 ?
25:16) + 1))))))) << (0 ?
25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
25:16) - (0 ?
25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 12:8) - (0 ?
- 12:8) + 1))))))) << (0 ?
- 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
- 12:8) - (0 ?
- 12:8) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
+            *buffer++ = address;
 
-        /* Event 29. */
-        *buffer++
-            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+            if (ace)
+            {
+                *buffer++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8562,17 +7351,17 @@ gckHARDWARE_ConfigMMU(
  31:27) - (0 ?
  31:27) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  15:0) - (0 ?
  15:0) + 1))))))) << (0 ?
- 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0068) & ((gctUINT32) ((((1 ?
  15:0) - (0 ?
  15:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
-            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  25:16) - (0 ?
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8583,67 +7372,53 @@ gckHARDWARE_ConfigMMU(
  25:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
-        event = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 6:6) - (0 ?
- 6:6) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 6:6) - (0 ?
- 6:6) + 1))))))) << (0 ?
- 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
- 6:6) - (0 ?
- 6:6) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
-        event = ((((gctUINT32) (event)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 4:0) - (0 ?
- 4:0) + 1))))))) << (0 ?
- 4:0))) | (((gctUINT32) ((gctUINT32) (29) & ((gctUINT32) ((((1 ?
- 4:0) - (0 ?
- 4:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
-
-        *buffer++
-            = event;
-
-        /* Append END. */
-        *buffer++
-           = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 31:27) - (0 ?
- 31:27) + 1))))))) << (0 ?
- 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
- 31:27) - (0 ?
- 31:27) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
-    }
-
-    if (Bytes != gcvNULL)
-    {
-        *Bytes = bytesAligned;
-    }
-
-    if (WaitLinkOffset != gcvNULL)
-    {
-        *WaitLinkOffset = bytes - 4 * 4;
+                *buffer++ = configEx;
+
+                *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+                *buffer++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+            }
+        }
     }
 
-    if (WaitLinkBytes != gcvNULL)
+    if (Bytes != gcvNULL)
     {
-        *WaitLinkBytes = 4 * 4;
+        *Bytes = reserveBytes;
     }
 
+    /* Return the status. */
     gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
+    return status;
 
 OnError:
+    /* Return the status. */
     gcmkFOOTER();
     return status;
-}
+#else
+    return gcvSTATUS_NOT_SUPPORTED;
 #endif
+}
 
 /*******************************************************************************
 **
@@ -8819,6 +7594,7 @@ gckHARDWARE_Flush(
     gctBOOL hwTFB;
     gctBOOL blt;
     gctBOOL peTSFlush;
+    gctBOOL multiCluster;
 
     gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu",
                    Hardware, Flush, Logical, gcmOPT_VALUE(Bytes));
@@ -8834,6 +7610,7 @@ gckHARDWARE_Flush(
     hwTFB = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HW_TFB);
 
     blt = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE);
+    multiCluster = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MULTI_CLUSTER);
 
     peTSFlush = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX);
 
@@ -8850,9 +7627,26 @@ gckHARDWARE_Flush(
     flushTFB = (Flush & gcvFLUSH_TFBHEADER) && hwTFB;
 
     /* Flush TFB for vertex buffer */
-    if (hwTFB && (Flush & gcvFLUSH_VERTEX))
+    if (Flush & gcvFLUSH_VERTEX)
     {
-        flushTFB = gcvTRUE;
+        if (hwTFB)
+        {
+            flushTFB = gcvTRUE;
+        }
+
+        if (multiCluster)
+        {
+            flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 14:14) - (0 ?
+ 14:14) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 14:14) - (0 ?
+ 14:14) + 1))))))) << (0 ?
+ 14:14))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 14:14) - (0 ?
+ 14:14) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 14:14) - (0 ? 14:14) + 1))))))) << (0 ? 14:14)));
+        }
     }
 
     /* Flush 3D color cache. */
@@ -8888,7 +7682,8 @@ gckHARDWARE_Flush(
     /* Flush 3D texture cache. */
     if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0))
     {
-        flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        flush |= multiCluster ?
+ 0 : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  2:2) - (0 ?
  2:2) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -8990,6 +7785,7 @@ gckHARDWARE_Flush(
     }
     else
     {
+        gctBOOL appendNop = gcvFALSE;
         gctUINT32 reserveBytes = 0;
         gctBOOL txCacheFix = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_TEX_CACHE_FLUSH_FIX)
                            ? gcvTRUE : gcvFALSE;
@@ -9034,6 +7830,14 @@ gckHARDWARE_Flush(
         /* Semaphore/Stall */
         reserveBytes += blt ? (8 * gcmSIZEOF(gctUINT32)) : (4 * gcmSIZEOF(gctUINT32));
 
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+        if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MCFE) && (reserveBytes & 8))
+        {
+            appendNop = gcvTRUE;
+            reserveBytes += 8;
+        }
+#endif
+
         /* Copy to command queue. */
         if (Logical != gcvNULL)
         {
@@ -9763,7 +8567,7 @@ gckHARDWARE_Flush(
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
 
                 *logical++
-                    = 0x12345678;
+                    = 0x1;
 
                 gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
                                "0x%x: FLUSH TFB cache 0x%x", logical - 1, logical[-1]);
@@ -10042,6 +8846,38 @@ gckHARDWARE_Flush(
  12:8) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8)));
             }
+            if (appendNop)
+            {
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+#endif
+            }
         }
 
         if (Bytes != gcvNULL)
@@ -10164,148 +9000,126 @@ OnError:
 #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)
 static gctCONST_STRING
 _PowerEnum(gceCHIPPOWERSTATE State)
 {
-    const gctCONST_STRING states[] =
-    {
-        gcmSTRING(gcvPOWER_ON),
-        gcmSTRING(gcvPOWER_OFF),
-        gcmSTRING(gcvPOWER_IDLE),
-        gcmSTRING(gcvPOWER_SUSPEND),
-        gcmSTRING(gcvPOWER_IDLE_BROADCAST),
-        gcmSTRING(gcvPOWER_SUSPEND_BROADCAST),
-        gcmSTRING(gcvPOWER_OFF_BROADCAST),
-        gcmSTRING(gcvPOWER_OFF_TIMEOUT),
-        gcmSTRING(gcvPOWER_ON_AUTO)
+    const gctCONST_STRING baseStates[] =
+    {
+        "ON",
+        "IDLE",
+        "SUSPEND",
+        "OFF",
+        "ON[auto]",
+    };
+
+    const gctCONST_STRING broadcastStates[] =
+    {
+        "",
+        "IDLE[broadcast]",
+        "SUSPEND[broadcast]",
+        "OFF[broadcast]",
+    };
+
+    const gctCONST_STRING timeoutStates[] =
+    {
+        "",
+        "IDLE[timeout]",
+        "SUSPEND[timeout]",
+        "OFF[timeout]",
     };
 
-    if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO))
+    gcmSTATIC_ASSERT(gcvPOWER_ON == 0 && gcvPOWER_IDLE == 1 &&
+                     gcvPOWER_SUSPEND == 2 && gcvPOWER_OFF == 3 &&
+                     gcvPOWER_ON_AUTO == 4,
+                     "array subscript does not match");
+
+    if (State & gcvPOWER_FLAG_BROADCAST)
+    {
+        return broadcastStates[State & ~gcvPOWER_FLAG_BROADCAST];
+    }
+    else if (State & gcvPOWER_FLAG_TIMEOUT)
+    {
+        return timeoutStates[State & ~gcvPOWER_FLAG_TIMEOUT];
+    }
+    else if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO))
     {
-        return states[State - gcvPOWER_ON];
+        return baseStates[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(
+static gceSTATUS
+_PmClockOn(
     IN gckHARDWARE Hardware,
-    IN gceCHIPPOWERSTATE State
+    OUT gctBOOL * RequireInit
     )
 {
     gceSTATUS status;
-    gckCOMMAND command = gcvNULL;
-    gckOS os;
-    gctUINT flag, clock;
-    gctBOOL acquired = gcvFALSE;
-    gctBOOL mutexAcquired = gcvFALSE;
-    gctBOOL broadcast = gcvFALSE;
-#if gcdPOWEROFF_TIMEOUT
-    gctBOOL timeout = gcvFALSE;
-    gctBOOL isAfter = gcvFALSE;
-    gctUINT32 currentTime;
-#endif
-    gctUINT32 process, thread;
-    gctBOOL commandStarted = gcvFALSE;
 
-#if gcdENABLE_PROFILING
-    gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime,
-              initTime, offTime, startTime, totalTime;
-#endif
-    gctBOOL global = gcvFALSE;
-    gctBOOL globalAcquired = gcvFALSE;
+    /* Turn on the power. */
+    gcmkONERROR(gckOS_SetGPUPower(Hardware->os, Hardware->core,
+                                  gcvTRUE, gcvTRUE));
 
-    /* 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,
-        },
-    };
+    Hardware->clockState = Hardware->powerState = gcvTRUE;
+
+    /* Check if GPU is present and awake. */
+    while (_IsGPUPresent(Hardware) == gcvSTATUS_GPU_NOT_RESPONDING)
+    {
+        /* Turn off the power and clock. */
+        gcmkONERROR(gckOS_SetGPUPower(Hardware->os, Hardware->core,
+                                      gcvFALSE, gcvFALSE));
+
+        Hardware->clockState = Hardware->powerState = gcvFALSE;
+
+        /* Wait a little. */
+        gckOS_Delay(Hardware->os, 1);
+
+        /* Turn on the power and clock. */
+        gcmkONERROR(gckOS_SetGPUPower(Hardware->os, Hardware->core,
+                                      gcvTRUE, gcvTRUE));
+
+        Hardware->clockState = Hardware->powerState = gcvTRUE;
+
+        if (RequireInit)
+        {
+            *RequireInit = gcvTRUE;
+        }
+    }
+
+OnError:
+    return status;
+}
+
+static gceSTATUS
+_PmClockOff(
+    IN gckHARDWARE Hardware,
+    IN gctBOOL PowerState
+    )
+{
+    gceSTATUS status;
+
+    gcmkONERROR(gckOS_SetGPUPower(Hardware->os, Hardware->core,
+                                  gcvFALSE, PowerState));
+
+    Hardware->clockState = gcvFALSE;
+    Hardware->powerState = PowerState;
+
+OnError:
+    return status;
+}
+
+static gceSTATUS
+_PmClockControl(
+    IN gckHARDWARE Hardware,
+    IN gceCHIPPOWERSTATE State
+    )
+{
+    gceSTATUS status;
+    gctUINT32 clock;
 
-    /* Clocks. */
     static const gctUINT clocks[4] =
     {
         /* gcvPOWER_ON */
@@ -10350,14 +9164,14 @@ gckHARDWARE_SetPowerManagementState(
  9:9) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
 
-        /* gcvPOWER_OFF */
+        /* gcvPOWER_IDLE */
         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  0:0) - (0 ?
  0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
@@ -10367,7 +9181,7 @@ gckHARDWARE_SetPowerManagementState(
  ~0U : (~(~0U << ((1 ?
  1:1) - (0 ?
  1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
  1:1) - (0 ?
  1:1) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
@@ -10392,14 +9206,14 @@ gckHARDWARE_SetPowerManagementState(
  9:9) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
 
-        /* gcvPOWER_IDLE */
+        /* gcvPOWER_SUSPEND */
         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  0:0) - (0 ?
  0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
@@ -10409,7 +9223,7 @@ gckHARDWARE_SetPowerManagementState(
  ~0U : (~(~0U << ((1 ?
  1:1) - (0 ?
  1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
  1:1) - (0 ?
  1:1) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
@@ -10434,7 +9248,7 @@ gckHARDWARE_SetPowerManagementState(
  9:9) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))),
 
-        /* gcvPOWER_SUSPEND */
+        /* gcvPOWER_OFF */
         ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  0:0) - (0 ?
  0:0) + 1) == 32) ?
@@ -10475,734 +9289,691 @@ gckHARDWARE_SetPowerManagementState(
  9:9) - (0 ?
  9:9) + 1) == 32) ?
  ~0U : (~(~0U << ((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));
+    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) ?
+ ~0U : (~(~0U << ((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1))))))) << (0 ?
+ 8:2))) | (((gctUINT32) ((gctUINT32) (Hardware->powerOnFscaleVal) & ((gctUINT32) ((((1 ?
+ 8:2) - (0 ?
+ 8:2) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)));
+    }
 #endif
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+    if (Hardware->clockState && Hardware->powerState
+#if gcdDVFS
+    /* Don't touch clock control if dynamic frequency scaling is available. */
+    && !gckHARDWARE_IsFeatureAvailable(Hardware,
+                                       gcvFEATURE_DYNAMIC_FREQUENCY_SCALING)
+#endif
+    )
+    {
+        if ((State == gcvPOWER_OFF) &&
+            (Hardware->identity.chipModel == gcv4000) &&
+            ((Hardware->identity.chipRevision == 0x5208) ||
+             (Hardware->identity.chipRevision == 0x5222)))
+        {
+            clock &= ~2U;
+        }
+
+        /* Write the clock control register. */
+        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core,
+                                          0x00000,
+                                          clock));
+
+        clock = ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1))))))) << (0 ?
+ 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
+ 9:9) - (0 ?
+ 9:9) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)));
+
+        /* Done loading the frequency scaler. */
+        gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core,
+                                          0x00000,
+                                          clock));
+    }
+
+    return gcvSTATUS_OK;
+
+OnError:
+    return status;
+}
+
+static gceSTATUS
+_PmInitializeGPU(
+    IN gckHARDWARE Hardware,
+    IN gckCOMMAND Command
+    )
+{
+    gceSTATUS status;
+
+    /* Initialize hardware. */
+    gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
+
+    gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
+                                         Hardware->options.allowFastClear,
+                                         Hardware->options.allowCompression));
+
+    /* Force the command queue to reload the next context. */
+    Command->currContext = gcvNULL;
+
+    /* Trigger a possible dummy draw. */
+    Command->dummyDraw = gcvTRUE;
+
+OnError:
+    return status;
+}
+
+/*
+ * Notice: this function may return gcvSTATUS_NOT_READY, which is not an error,
+ * but either not success.
+ */
+static gceSTATUS
+_PmStallCommand(
+    gckHARDWARE Hardware,
+    gckCOMMAND Command,
+    gctBOOL Broadcast
+    )
+{
+    gceSTATUS status;
+    gctBOOL idle;
+
+    if (Broadcast)
+    {
+        /* Check for idle. */
+        gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
+
+        if (!idle)
+        {
+            status = gcvSTATUS_CHIP_NOT_READY;
+            goto OnError;
+        }
+    }
+    else
+    {
+        /* Wait to finish all commands. */
+        status = gckCOMMAND_Stall(Command, gcvTRUE);
+
+        if (!gcmIS_SUCCESS(status))
+        {
+            goto OnError;
+        }
+
+        for (;;)
+        {
+            gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
+
+            if (idle)
+            {
+                break;
+            }
+
+            gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
+        }
+    }
+
+OnError:
+    return status;
+}
+
+static gceSTATUS
+_PmFlushCache(
+    gckHARDWARE Hardware,
+    gckCOMMAND Command
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+
+    if (Hardware->clockState == gcvFALSE)
+    {
+        /* Turn on the GPU power. */
+        gcmkONERROR(gckOS_SetGPUPower(Hardware->os, Hardware->core,
+                                      gcvTRUE, gcvTRUE));
+
+        Hardware->clockState = gcvTRUE;
+
+        /* Clock control, to ON state. */
+        gcmkONERROR(_PmClockControl(Hardware, gcvPOWER_ON));
+    }
 
-    /* Get the gckOS object pointer. */
-    os = Hardware->os;
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+    if (_IsHardwareMatch(Hardware, gcv400, 0x4645))
+    {
+        gcmkONERROR(gckCOMMAND_Start(Command));
 
-    /* Get the gckCOMMAND object pointer. */
-    gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL);
-    command = Hardware->kernel->command;
-    gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND);
+        gcmkONERROR(_FlushCache(Hardware, Command));
+        gckOS_Delay(gcvNULL, 1);
 
-    /* Start profiler. */
-    gcmkPROFILE_INIT(freq, time);
+        /* Stop the command parser. */
+        gcmkONERROR(gckCOMMAND_Stop(Command));
+    }
+    else
+    {
+        gckHARDWARE_ExecuteFunctions(Hardware, gcvHARDWARE_FUNCTION_FLUSH);
+        gckOS_Delay(gcvNULL, 1);
+    }
 
+OnError:
+    return status;
+}
 
-    /* Convert the broadcast power state. */
-    switch (State)
+/*
+ * Put power to on direction:
+ * Off -> Suspend
+ * Off            -> Idle
+ * Off                    -> On
+ *        Suspend -> Idle
+ *        Suspend         -> On
+ *                   Idle -> On
+ */
+static gceSTATUS
+_PmSetPowerOnDirection(
+    IN gckHARDWARE Hardware,
+    IN gceCHIPPOWERSTATE State
+    )
+{
+    gceSTATUS status;
+    gckCOMMAND command = Hardware->kernel->command;
+    gctBOOL clockOn = gcvFALSE;
+    gctBOOL requireInit = gcvFALSE;
+
+    switch (Hardware->chipPowerState)
     {
-    case gcvPOWER_IDLE_BROADCAST:
-        /* Convert to IDLE and note we are inside broadcast. */
-        State     = gcvPOWER_IDLE;
-        broadcast = gcvTRUE;
-        break;
+    case gcvPOWER_OFF:
+        if (State == gcvPOWER_SUSPEND)
+        {
+            gcmkONERROR(_PmClockOn(Hardware, gcvNULL));
+            clockOn = gcvTRUE;
 
-    case gcvPOWER_SUSPEND_BROADCAST:
-        /* Convert to SUSPEND and note we are inside broadcast. */
-        State     = gcvPOWER_SUSPEND;
-        broadcast = gcvTRUE;
-        break;
+            /* Clock control, put to suspend. */
+            gcmkONERROR(_PmClockControl(Hardware, gcvPOWER_SUSPEND));
 
-    case gcvPOWER_OFF_BROADCAST:
-        /* Convert to OFF and note we are inside broadcast. */
-        State     = gcvPOWER_OFF;
-        broadcast = gcvTRUE;
-        break;
+            /* Initialize GPU. */
+            gcmkONERROR(_PmInitializeGPU(Hardware, command));
 
-    case gcvPOWER_ON_AUTO:
-        /* Convert to ON and note we are inside recovery. */
-        State = gcvPOWER_ON;
-        break;
+            /* Suspend: clock off, power on. */
+            gcmkONERROR(_PmClockOff(Hardware, gcvTRUE));
+            break;
+        }
+
+        requireInit = gcvTRUE;
 
-    case gcvPOWER_ON:
-    case gcvPOWER_IDLE:
     case gcvPOWER_SUSPEND:
-    case gcvPOWER_OFF:
-        /* Mark as global power management. */
-        global = gcvTRUE;
+        /* Clock on. */
+        gcmkONERROR(_PmClockOn(Hardware, &requireInit));
+        clockOn = gcvTRUE;
+
+        /* Clock control, put to target state (On or idle). */
+        gcmkONERROR(_PmClockControl(Hardware, State));
+
+        /* Delay. */
+        gcmkONERROR(gckOS_Delay(Hardware->os, gcdPOWER_CONTROL_DELAY));
+
+        if (requireInit)
+        {
+            /* Initialize. */
+            gcmkONERROR(_PmInitializeGPU(Hardware, command));
+        }
+
+        /* Start. */
+        gcmkONERROR(gckCOMMAND_Start(command));
         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;
+    case gcvPOWER_IDLE:
+        /* Clock control, put to ON state. */
+        gcmkONERROR(_PmClockControl(Hardware, gcvPOWER_ON));
         break;
-#endif
 
     default:
         break;
     }
 
-    if (Hardware->options.powerManagement == gcvFALSE
-     && State != gcvPOWER_ON
-    )
+    return gcvSTATUS_OK;
+
+OnError:
+    if (clockOn)
     {
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
+        gctBOOL powerState =
+            (Hardware->chipPowerState == gcvPOWER_SUSPEND);
+
+        _PmClockOff(Hardware, powerState);
     }
 
-    /* Get current process and thread IDs. */
-    gcmkONERROR(gckOS_GetProcessID(&process));
-    gcmkONERROR(gckOS_GetThreadID(&thread));
+    return status;
+}
 
-    if (broadcast)
+/*
+ * Put power to off direction:
+ * On -> Idle
+ * On         -> Suspend
+ * On                    -> Off
+ *       Idle -> Suspend
+ *       Idle            -> Off
+ *               Suspend -> Off
+ */
+static gceSTATUS
+_PmSetPowerOffDirection(
+    IN gckHARDWARE Hardware,
+    IN gceCHIPPOWERSTATE State,
+    IN gctBOOL Broadcast
+    )
+{
+    gceSTATUS status;
+    gckCOMMAND command = Hardware->kernel->command;
+
+    switch (Hardware->chipPowerState)
     {
-        /* Try to acquire the power mutex. */
-        status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
+    case gcvPOWER_ON:
+        /* Stall. */
+        status = _PmStallCommand(Hardware, command, Broadcast);
 
-        if (gcmIS_SUCCESS(status))
+        if (!gcmIS_SUCCESS(status))
         {
-            mutexAcquired = gcvTRUE;
+            /* abort for error and NOT READY. */
+            goto OnError;
         }
-        else if (status == gcvSTATUS_TIMEOUT)
+
+        if (State == gcvPOWER_IDLE)
         {
-            /* 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_ON)
-            {
-                /* Called from IST,
-                ** so waiting here will cause deadlock,
-                ** if lock holder call gckCOMMAND_Stall() */
-                status = gcvSTATUS_OK;
-                goto OnError;
-            }
+            gcmkONERROR(_PmClockControl(Hardware, gcvPOWER_IDLE));
+            break;
         }
-    }
-
-    if (!mutexAcquired)
-    {
-        /* Acquire the power mutex. */
-        gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE));
-        mutexAcquired = gcvTRUE;
-    }
 
-    /* Get time until mtuex acquired. */
-    gcmkPROFILE_QUERY(time, mutexTime);
+    case gcvPOWER_IDLE:
+        /* Stop. */
+        gcmkONERROR(gckCOMMAND_Stop(command));
 
-    Hardware->powerProcess = process;
-    Hardware->powerThread  = thread;
-    mutexAcquired          = gcvTRUE;
+        if (State == gcvPOWER_SUSPEND)
+        {
+            /* Clock control, put to suspend state. */
+            gcmkONERROR(_PmClockControl(Hardware, gcvPOWER_SUSPEND));
 
-    /* Grab control flags and clock. */
-    flag  = flags[Hardware->chipPowerState][State];
-    clock = clocks[State];
+            /* Power on, clock off. */
+            gcmkONERROR(_PmClockOff(Hardware, gcvTRUE));
+            break;
+        }
 
-#if gcdENABLE_FSCALE_VAL_ADJUST
-    if (State == gcvPOWER_ON)
-    {
-        clock = ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 8:2) - (0 ?
- 8:2) + 1))))))) << (0 ?
- 8:2))) | (((gctUINT32) ((gctUINT32) (Hardware->powerOnFscaleVal) & ((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2)));
-    }
-#endif
+    case gcvPOWER_SUSPEND:
+        /* Flush. */
+        gcmkONERROR(_PmFlushCache(Hardware, command));
 
-    if (State == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF && broadcast)
-    {
-#if gcdPOWER_SUSPEND_WHEN_IDLE
-    /* Do nothing */
+        /* Clock control. */
+        gcmkONERROR(_PmClockControl(Hardware, gcvPOWER_OFF));
 
-        /* Release the power mutex. */
-        gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+        /* Power off, clock off. */
+        gcmkONERROR(_PmClockOff(Hardware, gcvFALSE));
+        break;
 
-           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) ?
- ~0U : (~(~0U << ((1 ?
- 0:0) - (0 ?
- 0:0) + 1))))))) << (0 ?
- 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 0:0) - (0 ?
- 0:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) |
-                ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 1:1) - (0 ?
- 1:1) + 1))))))) << (0 ?
- 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 1:1) - (0 ?
- 1:1) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) |
-                ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 8:2) - (0 ?
- 8:2) + 1))))))) << (0 ?
- 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 8:2) - (0 ?
- 8:2) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) |
-                ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) ;
-#endif
+    default:
+        break;
     }
 
-#if gcdPOWEROFF_TIMEOUT
-    if (timeout)
-    {
-        gcmkONERROR(gckOS_GetTicks(&currentTime));
+    return gcvSTATUS_OK;
 
-        gcmkONERROR(
-            gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter));
+OnError:
+    return status;
+}
 
-        /* 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));
+/*******************************************************************************
+**
+**  gckHARDWARE_SetPowerState
+**
+**  Set GPU to a specified power state.
+**
+**  INPUT:
+**
+**      gckHARDWARE Harwdare
+**          Pointer to an gckHARDWARE object.
+**
+**      gceCHIPPOWERSTATE State
+**          Power State.
+**
+*/
+gceSTATUS
+gckHARDWARE_SetPowerState(
+    IN gckHARDWARE Hardware,
+    IN gceCHIPPOWERSTATE State
+    )
+{
+    gceSTATUS status;
+    gckCOMMAND command = gcvNULL;
+    gckOS os;
+    gctBOOL acquired = gcvFALSE;
+    gctBOOL mutexAcquired = gcvFALSE;
+    gctBOOL broadcast = gcvFALSE;
+    gctBOOL timeout = gcvFALSE;
+    gceCHIPPOWERSTATE state = gcvPOWER_INVALID;
 
-            /* No need to do anything. */
-            gcmkFOOTER_NO();
-            return gcvSTATUS_OK;
-        }
+    /*
+     * Acquire globalSempahore when set to to global OFF, IDLE, SUSPEND, then
+     * can not switch to non-global state unless global ON comes and release
+     * the globalSemaphore.
+     */
+    gctBOOL global = gcvFALSE;
+    gctBOOL globalAcquired = gcvFALSE;
 
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                       "Power Off GPU[%d] at %u [supposed to be at %u]",
-                       Hardware->core, currentTime, Hardware->powerOffTime);
-    }
+    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
 
-    if (flag == 0)
-    {
-        /* Release the power mutex. */
-        gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
 
-        /* No need to do anything. */
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
+    os = Hardware->os;
+    command = Hardware->kernel->command;
 
-    /* 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)
+    /* Convert power state. */
+    switch (State)
     {
-        /* 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.*/
-                status = gcvSTATUS_OK;
-                goto OnError;
-            }
+    case gcvPOWER_ON:
+    case gcvPOWER_OFF:
+    case gcvPOWER_IDLE:
+    case gcvPOWER_SUSPEND:
+        global = gcvTRUE;
+        state  = State;
+        break;
 
-            /* Release the power mutex. */
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                           "Releasing the power mutex.");
-            gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
-            mutexAcquired = gcvFALSE;
+    case gcvPOWER_ON_AUTO:
+        state = gcvPOWER_ON;
+        break;
 
-            /* Wait for the semaphore. */
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                           "Waiting for global semaphore.");
-            gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
-            globalAcquired = gcvTRUE;
+    case gcvPOWER_OFF_TIMEOUT:
+    case gcvPOWER_IDLE_TIMEOUT:
+    case gcvPOWER_SUSPEND_TIMEOUT:
+        timeout   = gcvTRUE;
+    case gcvPOWER_OFF_BROADCAST:
+    case gcvPOWER_IDLE_BROADCAST:
+    case gcvPOWER_SUSPEND_BROADCAST:
+        broadcast = gcvTRUE;
+        state     = State & ~(gcvPOWER_FLAG_BROADCAST | gcvPOWER_FLAG_TIMEOUT);
+        break;
 
-            /* Acquire the power mutex. */
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
-                           "Reacquiring the power mutex.");
-            gcmkONERROR(gckOS_AcquireMutex(os,
-                                           Hardware->powerMutex,
-                                           gcvINFINITE));
-            mutexAcquired = gcvTRUE;
+    case gcvPOWER_INVALID:
+        /* Canceled, nothing to do. */
+        status = gcvSTATUS_OK;
+        goto OnError;
 
-            /* 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];
+    default:
+        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+    }
 
-            if (flag == 0)
-            {
-                gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
-                globalAcquired = gcvFALSE;
+    if (Hardware->options.powerManagement == gcvFALSE &&
+        (Hardware->chipPowerState == gcvPOWER_ON || state != gcvPOWER_ON))
+    {
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
 
-                gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
-                mutexAcquired = gcvFALSE;
+    if (broadcast)
+    {
+        /* Try to acquire the power mutex. */
+        status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0);
 
-                gcmkFOOTER_NO();
-                return gcvSTATUS_OK;
-            }
-        }
-        else
+        if (status == gcvSTATUS_TIMEOUT)
         {
-            /* Error. */
-            gcmkONERROR(status);
+            /* Pm in progress, abort. */
+            gcmkFOOTER_NO();
+            return gcvSTATUS_OK;
         }
+    }
+    else
+    {
+        /* Acquire the power mutex. */
+        status = gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE);
+    }
 
-        /* Release the global semaphore again. */
-        gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
-        globalAcquired = gcvFALSE;
+    gcmkONERROR(status);
+    mutexAcquired = gcvTRUE;
 
-        /* Try to acquire the semaphore to make sure commit is not in progress
-        ** Otherwise, we just abort. */
-        if (flag & gcvPOWER_FLAG_ACQUIRE)
-        {
-            /* ON -> Other, boardcast. */
-            /* Try to acquire the power management semaphore. */
-            status = gckOS_TryAcquireSemaphore(os, command->powerSemaphore);
+    if (Hardware->chipPowerState == state)
+    {
+        /* No state change. */
+        gckOS_ReleaseMutex(os, Hardware->powerMutex)
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
 
-            if (status == gcvSTATUS_OK)
-            {
-                acquired = gcvTRUE;
+    if (broadcast &&
+        state == gcvPOWER_SUSPEND && Hardware->chipPowerState == gcvPOWER_OFF)
+    {
+        /* Do nothing, donot change chipPowerState. */
+        gckOS_ReleaseMutex(os, Hardware->powerMutex)
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
 
-                /* avoid acquiring again. */
-                flag &= ~gcvPOWER_FLAG_ACQUIRE;
-            }
-            else
-            {
-                /* Not ready to swith. */
-                status = gcvSTATUS_CHIP_NOT_READY;
-                goto OnError;
-            }
+    if (timeout)
+    {
+        if (Hardware->nextPowerState == gcvPOWER_INVALID)
+        {
+            /* delayed power state change is canceled. */
+            gckOS_ReleaseMutex(os, Hardware->powerMutex)
+            gcmkFOOTER_NO();
+            return gcvSTATUS_OK;
         }
     }
-    else
+
+    if (global)
     {
-        if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
+        if (state != gcvPOWER_ON)
         {
-            /* Acquire the global semaphore if it has not been acquired. */
+            /*
+             * Switch to global non-ON (OFF, IDLE or SUSPEND), try 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)
+            else if (status == gcvSTATUS_TIMEOUT)
             {
-                /* 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;
+                /*
+                 * Ignore and leave globalSemaphore not acquired in this try.
+                 * In this condition, power state is changing between global
+                 * OFF, SUSPEND and IDLE, which is allowed.
+                 */
+                gcmkASSERT(Hardware->chipPowerState != gcvPOWER_ON);
             }
             else
             {
-                /* Test for error. */
+                /* Other errors. */
                 gcmkONERROR(status);
-
-                /* Break out of loop. */
-                break;
             }
         }
     }
-
-    /* Get time until powered on. */
-    gcmkPROFILE_QUERY(time, onTime);
-
-    if (flag & gcvPOWER_FLAG_STALL)
+    else
     {
-        gctBOOL idle;
-        gctINT32 atomValue;
+        /* Try to acquire the global semaphore. */
+        status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
 
-        /* For global operation, all pending commits have already been
-        ** blocked by globalSemaphore or powerSemaphore.*/
-        if (!global)
+        if (status == gcvSTATUS_TIMEOUT)
         {
-            /* Check commit atom. */
-            gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
+            /* In global SUSPEND, IDLE, or OFF state. */
+            gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+            mutexAcquired = gcvFALSE;
 
-            if (atomValue > 0)
+            if (broadcast)
             {
-                /* Commits are pending - abort power management. */
-                status = broadcast ? gcvSTATUS_CHIP_NOT_READY
-                                   : gcvSTATUS_MORE_DATA;
-                goto OnError;
+                /* Abort power state change. */
+                gcmkFOOTER_NO();
+                return gcvSTATUS_OK;
             }
-        }
 
-        if (broadcast)
-        {
-            /* Check for idle. */
-            gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
+            /*
+             * Only ON_AUTO can run here.
+             * ON_AUTO state can not be skipped, either can not change a global
+             * state.
+             * So we need to wait until global ON state here.
+             */
+            gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
+            globalAcquired = gcvTRUE;
+
+            /* Acquire the power mutex. */
+            gcmkONERROR(gckOS_AcquireMutex(os,
+                                           Hardware->powerMutex,
+                                           gcvINFINITE));
+            mutexAcquired = gcvTRUE;
 
-            if (!idle)
+            if (Hardware->chipPowerState == state)
             {
-                status = gcvSTATUS_CHIP_NOT_READY;
+                /* Done. */
+                status = gcvSTATUS_OK;
                 goto OnError;
             }
         }
-
         else
         {
-            /* Wait to finish all commands. */
-            gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE));
-
-            for (;;)
-            {
-                gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle));
-
-                if (idle)
-                {
-                    break;
-                }
-
-                gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1));
-            }
+            /* Check error. */
+            gcmkONERROR(status);
         }
-    }
-
-    /* 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));
+        /* We just check if in non-global state, but need not to acquire it. */
+        gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+        globalAcquired = gcvFALSE;
     }
 
-    /* Flush Cache before Power Off. */
-    if (flag & gcvPOWER_FLAG_POWER_OFF)
+    if (Hardware->chipPowerState == gcvPOWER_ON)
     {
-        if (Hardware->clockState == gcvFALSE)
+        /* Switch from power ON to other non-runnable states. */
+        if (broadcast)
         {
-            /* Turn off the GPU power. */
-            gcmkONERROR(
-                    gckOS_SetGPUPower(os,
-                        Hardware->core,
-                        gcvTRUE,
-                        gcvTRUE));
+            gctINT32 atomValue;
 
-            Hardware->clockState = gcvTRUE;
-#if gcdDVFS
-            if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE)
-#endif
+            /* Try to acquire the semaphore to block/sync with commit. */
+            status = gckOS_TryAcquireSemaphore(os, command->powerSemaphore);
+
+            if (gcmIS_ERROR(status))
             {
-                /* Write the clock control register. */
-                gcmkONERROR(gckOS_WriteRegisterEx(os,
-                                                  Hardware->core,
-                                                  0x00000,
-                                                  clocks[0]));
-
-                /* Done loading the frequency scaler. */
-                gcmkONERROR(gckOS_WriteRegisterEx(os,
-                                                  Hardware->core,
-                                                  0x00000,
-                                                  ((((gctUINT32) (clocks[0])) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
+                status = gcvSTATUS_CHIP_NOT_READY;
+                goto OnError;
             }
-        }
-
-        if(_IsHardwareMatch(Hardware, gcv400, 0x4645))
-        {
-            gcmkONERROR(gckCOMMAND_Start(command));
 
-            gcmkONERROR(_FlushCache(Hardware, command));
+            acquired = gcvTRUE;
 
-            gckOS_Delay(gcvNULL, 1);
+            /* Check commit atom, abort when commit is in progress. */
+            gcmkONERROR(gckOS_AtomGet(Hardware->os,
+                                      command->atomCommit,
+                                      &atomValue));
 
-            /* Stop the command parser. */
-            gcmkONERROR(gckCOMMAND_Stop(command));
+            if (atomValue > 0)
+            {
+                status = gcvSTATUS_CHIP_NOT_READY;
+                goto OnError;
+            }
         }
         else
         {
-            gckHARDWARE_ExecuteFunctions(Hardware, gcvHARDWARE_FUNCTION_FLUSH);
-            gckOS_Delay(gcvNULL, 1);
-        }
-
-        flag |= gcvPOWER_FLAG_CLOCK_OFF;
-    }
-
-    /* Get time until stopped. */
-    gcmkPROFILE_QUERY(time, stopTime);
-
-    /* Only process this when hardware is enabled. */
-    if (Hardware->clockState && Hardware->powerState
-#if gcdDVFS
-    /* Don't touch clock control if dynamic frequency scaling is available. */
-    && gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_DYNAMIC_FREQUENCY_SCALING) != gcvTRUE
-#endif
-    )
-    {
-        if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
-        {
-            if (Hardware->identity.chipModel == gcv4000
-            && ((Hardware->identity.chipRevision == 0x5208) || (Hardware->identity.chipRevision == 0x5222)))
-            {
-                clock &= ~2U;
-            }
+            /* Acquire/wait the semaphore to block/sync with command commit. */
+            gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+            acquired = gcvTRUE;
         }
-
-        /* 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) ?
- ~0U : (~(~0U << ((1 ?
- 9:9) - (0 ?
- 9:9) + 1))))))) << (0 ?
- 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
- 9:9) - (0 ?
- 9:9) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9)))));
     }
 
-    if (flag & gcvPOWER_FLAG_DELAY)
+    /* Do hardware power state change. */
+    if (Hardware->chipPowerState < state)
     {
-        /* Wait for the specified amount of time to settle coming back from
-        ** power-off or suspend state. */
-        gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY));
+        /* On to off direction. */
+        gcmkONERROR(_PmSetPowerOffDirection(Hardware, state, broadcast));
     }
-
-    /* Get time until delayed. */
-    gcmkPROFILE_QUERY(time, delayTime);
-
-    if (flag & gcvPOWER_FLAG_INITIALIZE)
-    {
-        /* Initialize hardware. */
-        gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
-
-        gcmkONERROR(gckHARDWARE_SetFastClear(Hardware,
-                                             Hardware->options.allowFastClear,
-                                             Hardware->options.allowCompression));
-
-        /* Force the command queue to reload the next context. */
-        command->currContext = gcvNULL;
-
-        /* Trigger a possible dummy draw. */
-        command->dummyDraw = gcvTRUE;
-    }
-
-    /* Get time until initialized. */
-    gcmkPROFILE_QUERY(time, initTime);
-
-    if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF))
+    else
     {
-        /* 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;
+        /* Off to on direction. */
+        gcmkONERROR(_PmSetPowerOnDirection(Hardware, state));
     }
 
-    /* Get time until off. */
-    gcmkPROFILE_QUERY(time, offTime);
-
-    if (flag & gcvPOWER_FLAG_START)
+    if (status == gcvSTATUS_CHIP_NOT_READY)
     {
-        /* Start the command processor. */
-        gcmkONERROR(gckCOMMAND_Start(command));
-        commandStarted = gcvTRUE;
+        /* CHIP_NOT_READY is not an error, either not success. */
+        goto OnError;
     }
 
-    /* Get time until started. */
-    gcmkPROFILE_QUERY(time, startTime);
-
-    if (flag & gcvPOWER_FLAG_RELEASE)
+    if (state == gcvPOWER_ON)
     {
-        /* Release the power management semaphore. */
+        /* Switched to power ON from other non-runnable states. */
         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. */
+            /*
+             * Global semaphore should be acquired already before, when
+             * global OFF, IDLE or SUSPEND.
+             */
             status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+
             if (status != gcvSTATUS_TIMEOUT)
             {
-                gcmkONERROR(status);
+                gcmkPRINT("%s: global state error", __FUNCTION__);
             }
 
-            /* Release the global semaphore. */
+            /* Switched to global ON, now release the global semaphore. */
             gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
             globalAcquired = gcvFALSE;
         }
     }
 
-    gckSTATETIMER_Accumulate(&Hardware->powerStateTimer, Hardware->chipPowerState);
+    gckSTATETIMER_Accumulate(&Hardware->powerStateCounter,
+                             Hardware->chipPowerState);
 
     /* Save the new power state. */
-    Hardware->chipPowerState = State;
+    Hardware->chipPowerState = state;
 
 #if gcdDVFS
-    if (State == gcvPOWER_ON && Hardware->kernel->dvfs)
+    if (state == gcvPOWER_ON && Hardware->kernel->dvfs)
     {
         gckDVFS_Start(Hardware->kernel->dvfs);
     }
 #endif
 
-#if gcdPOWEROFF_TIMEOUT
-    /* Reset power off time */
-    gcmkONERROR(gckOS_GetTicks(&currentTime));
-
-    Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
-
-    if (State == gcvPOWER_IDLE || State == gcvPOWER_SUSPEND)
+    if (!broadcast)
     {
-        /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
-        gcmkVERIFY_OK(gckOS_StartTimer(os,
-                                       Hardware->powerOffTimer,
-                                       Hardware->powerOffTimeout));
+        /*
+         * Cancel delayed power state change.
+         * Stop timer is not as good as set as no state change. Timer may run
+         * into this function already when try to to stop the timer.
+         */
+        Hardware->nextPowerState = gcvPOWER_INVALID;
     }
-    else
+
+#if gcdPOWEROFF_TIMEOUT
+    if (state == gcvPOWER_IDLE || state == gcvPOWER_SUSPEND)
     {
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Cancel powerOfftimer");
+        /* Delayed power off. */
+        Hardware->nextPowerState = gcvPOWER_OFF_TIMEOUT;
 
-        /* Cancel running timer when GPU enters ON or OFF. */
-        gcmkVERIFY_OK(gckOS_StopTimer(os, Hardware->powerOffTimer));
+        /* Start a timer to power off GPU when GPU enters IDLE or SUSPEND. */
+        gcmkVERIFY_OK(gckOS_StartTimer(os, Hardware->powerStateTimer, gcdPOWEROFF_TIMEOUT));
     }
 #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));
-    }
-
     if (acquired)
     {
         /* Release semaphore. */
@@ -11228,7 +9999,7 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckHARDWARE_QueryPowerManagementState
+**  gckHARDWARE_QueryPowerState
 **
 **  Get GPU power state.
 **
@@ -11242,7 +10013,7 @@ OnError:
 **
 */
 gceSTATUS
-gckHARDWARE_QueryPowerManagementState(
+gckHARDWARE_QueryPowerState(
     IN gckHARDWARE Hardware,
     OUT gceCHIPPOWERSTATE* State
     )
@@ -11263,7 +10034,7 @@ gckHARDWARE_QueryPowerManagementState(
 
 /*******************************************************************************
 **
-**  gckHARDWARE_SetPowerManagement
+**  gckHARDWARE_EnablePowerManagement
 **
 **  Configure GPU power management function.
 **  Only used in driver initialization stage.
@@ -11273,14 +10044,14 @@ gckHARDWARE_QueryPowerManagementState(
 **      gckHARDWARE Harwdare
 **          Pointer to an gckHARDWARE object.
 **
-**      gctBOOL PowerManagement
-**          Power Mangement State.
+**      gctBOOL Enable
+**          Power Mangement Enabling State.
 **
 */
 gceSTATUS
-gckHARDWARE_SetPowerManagement(
+gckHARDWARE_EnablePowerManagement(
     IN gckHARDWARE Hardware,
-    IN gctBOOL PowerManagement
+    IN gctBOOL Enable
     )
 {
     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
@@ -11288,15 +10059,15 @@ gckHARDWARE_SetPowerManagement(
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
 
-    if(_IsHardwareMatch(Hardware, gcv7000, 0x6008))
+    if (_IsHardwareMatch(Hardware, gcv7000, 0x6008))
     {
-        PowerManagement = gcvFALSE;
+        Enable = gcvFALSE;
     }
 
     gcmkVERIFY_OK(
         gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE));
 
-    Hardware->options.powerManagement = PowerManagement;
+    Hardware->options.powerManagement = Enable;
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
 
@@ -11619,54 +10390,23 @@ gckHARDWARE_GetFscaleValue(
     )
 {
     *FscaleValue = Hardware->powerOnFscaleVal;
-    *MinFscaleValue = Hardware->minFscaleValue;
-    *MaxFscaleValue = 64;
-
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckHARDWARE_SetMinFscaleValue(
-    IN gckHARDWARE Hardware,
-    IN gctUINT MinFscaleValue
-    )
-{
-    if (MinFscaleValue >= 1 && MinFscaleValue <= 64)
-    {
-        Hardware->minFscaleValue = MinFscaleValue;
-    }
-
-    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;
+    *MinFscaleValue = Hardware->minFscaleValue;
+    *MaxFscaleValue = 64;
 
-    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 }
 
-
 gceSTATUS
-gckHARDWARE_QueryPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    OUT gctUINT32*  Timeout
-)
+gckHARDWARE_SetMinFscaleValue(
+    IN gckHARDWARE Hardware,
+    IN gctUINT MinFscaleValue
+    )
 {
-    gcmkHEADER_ARG("Hardware=0x%x", Hardware);
-
-    *Timeout = Hardware->powerOffTimeout;
+    if (MinFscaleValue >= 1 && MinFscaleValue <= 64)
+    {
+        Hardware->minFscaleValue = MinFscaleValue;
+    }
 
-    gcmkFOOTER_ARG("*Timeout=%d", *Timeout);
     return gcvSTATUS_OK;
 }
 #endif
@@ -11773,7 +10513,7 @@ gckHARDWARE_QueryIdle(
             break;
         }
 
-        if (Hardware->hasAsyncFe)
+        if (Hardware->asyncFE)
         {
             gckEVENT asyncEvent = Hardware->kernel->asyncEvent;
 
@@ -12059,6 +10799,8 @@ gckHARDWARE_UpdateContextProfile(
 
     profiler_part2->hi_total_read_8B_count = 0;
     profiler_part2->hi_total_write_8B_count = 0;
+    profiler_part2->hi_total_readOCB_16B_count = 0;
+    profiler_part2->hi_total_writeOCB_16B_count = 0;
     profiler_part1->pe0_pixel_count_drawn_by_color_pipe = 0;
     profiler_part1->pe0_pixel_count_drawn_by_depth_pipe = 0;
     profiler_part1->pe0_pixel_count_killed_by_color_pipe = 0;
@@ -12101,6 +10843,48 @@ gckHARDWARE_UpdateContextProfile(
         profiler_part2->hi_total_read_8B_count += totalRead;
         profiler_part2->hi_total_write_8B_count += totalWrite;
 
+        /* OCB-only BW */
+        if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_OCB_COUNTER))
+        {
+            if (Hardware->identity.customerID == 0x7e ||
+                Hardware->identity.customerID == 0x7d)
+            {
+                gcmkONERROR(
+                    gckOS_ReadRegisterEx(Hardware->os,
+                    Hardware->core,
+                    0x17E00,
+                    &totalRead));
+                gcmkONERROR(
+                    gckOS_ReadRegisterEx(Hardware->os,
+                    Hardware->core,
+                    0x17E10,
+                    &totalWrite));
+            }
+            else
+            {
+                gcmkONERROR(
+                    gckOS_ReadRegisterEx(Hardware->os,
+                    Hardware->core,
+                    0x005C0,
+                    &totalRead));
+                gcmkONERROR(
+                    gckOS_ReadRegisterEx(Hardware->os,
+                    Hardware->core,
+                    0x005D0,
+                    &totalWrite));
+
+            }
+        }
+        else
+        {
+            totalRead = 0;
+            totalWrite = 0;
+        }
+
+
+        profiler_part2->hi_total_readOCB_16B_count += totalRead;
+        profiler_part2->hi_total_writeOCB_16B_count += totalWrite;
+
         /* PE */
         gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  23:16) - (0 ?
@@ -12165,6 +10949,8 @@ gckHARDWARE_UpdateContextProfile(
 
     gcmkUPDATE_PROFILE_DATA_PART2(hi_total_read_8B_count);
     gcmkUPDATE_PROFILE_DATA_PART2(hi_total_write_8B_count);
+    gcmkUPDATE_PROFILE_DATA_PART2(hi_total_readOCB_16B_count);
+    gcmkUPDATE_PROFILE_DATA_PART2(hi_total_writeOCB_16B_count);
 #if USE_SW_RESET
     gcmkRESET_PROFILE_DATA_PART1(pe0_pixel_count_killed_by_color_pipe);
     gcmkRESET_PROFILE_DATA_PART1(pe0_pixel_count_killed_by_depth_pipe);
@@ -13987,8 +12773,10 @@ _ResetGPU(
 {
     gctUINT32 control, idle;
     gceSTATUS status;
+    gctUINT32 count = 0;
+    gctUINT32 mmuEnabled;
 
-    for (;;)
+    while (count < 2)
     {
         /* Disable clock gating. */
         gcmkONERROR(gckOS_WriteRegisterEx(Os,
@@ -14107,9 +12895,13 @@ _ResetGPU(
  ~0U : (~(~0U << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12)))));
         }
 
+#if gcdFPGA_BUILD
+        /* Wait more time on FPGA for reset as lower frequency */
+        gcmkONERROR(gckOS_Delay(Os, 3));
+#else
         /* Wait for reset. */
         gcmkONERROR(gckOS_Delay(Os, 1));
-
+#endif
         /* Reset soft reset bit. */
         gcmkONERROR(gckOS_WriteRegisterEx(Os,
                                           Core,
@@ -14148,17 +12940,31 @@ _ResetGPU(
                                          0x00004,
                                          &idle));
 
+
         if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0)
         {
             continue;
         }
 
+        gcmkDUMP(Os, "@[register.wait 0x%05X 0x%08X 0x%08X]",
+                 0x00004,
+                 ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) ((gctUINT32) (~0U) & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))),
+                 idle);
+
         /* 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) ? ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0)
         ||  ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0)
         )
@@ -14166,8 +12972,64 @@ _ResetGPU(
             continue;
         }
 
-        /* GPU is idle. */
-        break;
+        gcmkDUMP(Os, "@[register.wait 0x%05X 0x%08X 0x%08X]",
+                 0x00000,
+                 ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) ((gctUINT32) (~0U) & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
+                 | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1))))))) << (0 ?
+ 17:17))) | (((gctUINT32) ((gctUINT32) (~0U) & ((gctUINT32) ((((1 ?
+ 17:17) - (0 ?
+ 17:17) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 17:17) - (0 ? 17:17) + 1))))))) << (0 ? 17:17))),
+                 control);
+
+        /* Force Disable MMU to guarantee setup command be read from physical addr */
+        if (Hardware->options.secureMode == gcvSECURE_IN_NORMAL)
+        {
+            gctUINT32 regMmuCtrl = 0;
+            gcmkONERROR(gckOS_ReadRegisterEx(
+                Hardware->os,
+                Hardware->core,
+                0x00388,
+                &regMmuCtrl
+                ));
+
+            mmuEnabled = (((((gctUINT32) (regMmuCtrl)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) );
+        }
+        else
+        {
+            gctUINT32 regMmuCtrl = 0;
+
+            gcmkONERROR(gckOS_ReadRegisterEx(
+                Hardware->os,
+                Hardware->core,
+                0x0018C,
+                &regMmuCtrl
+                ));
+
+            mmuEnabled = (((((gctUINT32) (regMmuCtrl)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) );
+        }
+
+        if (mmuEnabled)
+        {
+            /* Not reset properly, reset again. */
+            continue;
+        }
+
+        count++;
     }
 
     /* Success. */
@@ -14217,7 +13079,10 @@ gckHARDWARE_Reset(
     gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware));
 
     /* Jump to address into which GPU should run if it doesn't stuck. */
-    gcmkONERROR(gckHARDWARE_Execute(Hardware, Hardware->kernel->restoreAddress, 16));
+    if (Hardware->wlFE)
+    {
+        gcmkONERROR(gckWLFE_Execute(Hardware, Hardware->kernel->restoreAddress, 16));
+    }
 
     gcmkPRINT("[galcore]: recovery done");
 
@@ -14245,17 +13110,8 @@ gckHARDWARE_GetBaseAddress(
     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
     gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL);
 
-    /* Test if we have a new Memory Controller. */
-    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MC20))
-    {
-        /* No base address required. */
-        *BaseAddress = 0;
-    }
-    else
-    {
-        /* Get the base address from the OS. */
-        *BaseAddress = Hardware->baseAddress;
-    }
+    /* Get the base address from the OS. */
+    *BaseAddress = Hardware->baseAddress;
 
     /* Success. */
     gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress);
@@ -14297,8 +13153,8 @@ gckHARDWARE_NeedBaseAddress(
         case 0x0599:
         case 0x059A:
         case 0x05A9:
-            /* These states need a TRUE physical address. */
-            need = gcvTRUE;
+            /* These states need a TRUE physical address if MC20 fix is not there */
+            need = (gcvSTATUS_FALSE == gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MC20));
             break;
         }
 #else
@@ -14348,6 +13204,33 @@ gckHARDWARE_IsFeatureAvailable(
     return available ? gcvSTATUS_TRUE : gcvSTATUS_FALSE;
 }
 
+gceSTATUS
+gckHARDWARE_QueryMcfe(
+    IN gckHARDWARE Hardware,
+    OUT const gceMCFE_CHANNEL_TYPE * Channels[],
+    OUT gctUINT32 * Count
+    )
+{
+    if (!_QueryFeatureDatabase(Hardware, gcvFEATURE_MCFE))
+    {
+        /* No MCFE feature. */
+        return gcvSTATUS_NOT_SUPPORTED;
+    }
+
+    if (Channels)
+    {
+        *Channels = Hardware->mcfeChannels;
+    }
+
+    if (Count)
+    {
+        *Count = Hardware->mcfeChannelCount;
+    }
+
+    return gcvSTATUS_OK;
+}
+
+
 /*******************************************************************************
 **
 **  gckHARDWARE_DumpMMUException
@@ -14375,11 +13258,12 @@ gckHARDWARE_DumpMMUException(
     gctUINT32 mtlb      = 0;
     gctUINT32 stlb      = 0;
     gctUINT32 offset    = 0;
-#if gcdPROCESS_ADDRESS_SPACE
-    gcsDATABASE_PTR database;
-#endif
     gctUINT32 mmuStatusRegAddress;
     gctUINT32 mmuExceptionAddress;
+    gceAREA_TYPE areaType = gcvAREA_TYPE_UNKNOWN;
+    gctUINT32 stlbShift;
+    gctUINT32 stlbMask;
+    gctUINT32 pgoffMask;
 
     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
 
@@ -14467,15 +13351,39 @@ gckHARDWARE_DumpMMUException(
               gcmkPRINT("  MMU%d: unknown state\n", i);
         }
 
-        gcmkVERIFY_OK(
-            gckOS_ReadRegisterEx(Hardware->os,
-                                 Hardware->core,
-                                 mmuExceptionAddress + i * 4,
-                                 &address));
+        if (Hardware->options.secureMode == gcvSECURE_NONE)
+        {
+            gcmkVERIFY_OK(
+                gckOS_ReadRegisterEx(Hardware->os,
+                                     Hardware->core,
+                                     mmuExceptionAddress + i * 4,
+                                     &address));
+        }
+        else
+        {
+            gcmkVERIFY_OK(
+                gckOS_ReadRegisterEx(Hardware->os,
+                                     Hardware->core,
+                                     mmuExceptionAddress,
+                                     &address));
+        }
+
+        gckMMU_GetAreaType(Hardware->kernel->mmu, address, &areaType);
+
+        if (areaType == gcvAREA_TYPE_UNKNOWN)
+        {
+            gcmkPRINT("  MMU%d: exception address = 0x%08X, it is not mapped.\n", i, address);
+            gcmkFOOTER_NO();
+            return gcvSTATUS_OK;
+        }
+
+        pgoffMask = (areaType == gcvAREA_TYPE_4K) ? gcdMMU_OFFSET_4K_MASK : gcdMMU_OFFSET_1M_MASK;
+        stlbShift = (areaType == gcvAREA_TYPE_4K) ? gcdMMU_STLB_4K_SHIFT : gcdMMU_STLB_1M_SHIFT;
+        stlbMask  = (areaType == gcvAREA_TYPE_4K) ? gcdMMU_STLB_4K_MASK : gcdMMU_STLB_1M_MASK;
 
         mtlb   = (address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
-        stlb   = (address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
-        offset =  address & gcdMMU_OFFSET_4K_MASK;
+        stlb   = (address & stlbMask) >> stlbShift;
+        offset =  address & pgoffMask;
 
         gcmkPRINT("  MMU%d: exception address = 0x%08X\n", i, address);
 
@@ -14485,20 +13393,7 @@ gckHARDWARE_DumpMMUException(
 
         gcmkPRINT("    Offset = 0x%08X (%d)\n", offset, offset);
 
-        gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, address);
-
-#if gcdPROCESS_ADDRESS_SPACE
-        for (i = 0; i < gcmCOUNTOF(Hardware->kernel->db->db); ++i)
-        {
-            for (database = Hardware->kernel->db->db[i];
-                    database != gcvNULL;
-                    database = database->next)
-            {
-                gcmkPRINT("    database [%d] :", database->processID);
-                gckMMU_DumpPageTableEntry(database->mmu, address);
-            }
-        }
-#endif
+        gckMMU_DumpPageTableEntry(Hardware->kernel->mmu, areaType, address);
 
         gckMMU_DumpRecentFreedAddress(Hardware->kernel->mmu);
     }
@@ -14517,9 +13412,6 @@ gckHARDWARE_HandleFault(
     gctUINT32 mmuStatusRegAddress;
     gctUINT32 mmuExceptionAddress;
 
-    gcuVIDMEM_NODE_PTR node;
-    gctUINT32 entryValue;
-
     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
 
     if (Hardware->options.secureMode == gcvSECURE_NONE)
@@ -14573,10 +13465,38 @@ gckHARDWARE_HandleFault(
 
     if (address != gcvINVALID_ADDRESS)
     {
+        gckVIDMEM_NODE nodeObject = gcvNULL;
+        gctUINT32 offset = 0;
+        gctPHYS_ADDR_T physicalAddress = 0;
+        gceAREA_TYPE areaType;
+        gctUINT32 pageMask;
+        gcePAGE_TYPE pageType;
+
+        gckMMU_GetAreaType(Hardware->kernel->mmu, address, &areaType);
+
+        pageMask = (areaType == gcvAREA_TYPE_4K) ? gcdMMU_PAGE_4K_MASK : gcdMMU_PAGE_1M_MASK;
+        pageType = (areaType == gcvAREA_TYPE_4K) ? gcvPAGE_TYPE_4K : gcvPAGE_TYPE_1M;
+
+#if gcdENABLE_TRUST_APPLICATION
         address &= ~gcdMMU_PAGE_4K_MASK;
+#else
+        address &= ~pageMask;
+#endif
 
         /* Try to allocate memory and setup map for exception address. */
-        gcmkONERROR(gckVIDMEM_FindVIDMEM(Hardware->kernel, address, &node, &entryValue));
+        gcmkONERROR(gckVIDMEM_NODE_Find(
+            Hardware->kernel,
+            address,
+            &nodeObject,
+            &offset
+            ));
+
+        gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+            Hardware->kernel,
+            nodeObject,
+            offset,
+            &physicalAddress
+            ));
 
 #if gcdENABLE_TRUST_APPLICATION
         if (Hardware->options.secureMode == gcvSECURE_IN_TA)
@@ -14584,7 +13504,7 @@ gckHARDWARE_HandleFault(
             gckKERNEL_HandleMMUException(
                 Hardware->kernel,
                 mmuStatus,
-                entryValue,
+                physicalAddress,
                 address
                 );
         }
@@ -14594,9 +13514,9 @@ gckHARDWARE_HandleFault(
             gctUINT32_PTR entry;
 
             /* Setup page table. */
-            gcmkONERROR(gckMMU_GetPageEntry(Hardware->kernel->mmu, address, &entry));
+            gcmkONERROR(gckMMU_GetPageEntry(Hardware->kernel->mmu, pageType, address, &entry));
 
-            gckMMU_SetPage(Hardware->kernel->mmu, entryValue, gcvTRUE, entry);
+            gckMMU_SetPage(Hardware->kernel->mmu, physicalAddress, pageType, gcvTRUE, entry);
 
             /* Resume hardware execution. */
             gcmkVERIFY_OK(gckOS_WriteRegisterEx(
@@ -14616,6 +13536,113 @@ OnError:
     return status;
 }
 
+static gceSTATUS
+_DumpMCFEState(
+    IN gckOS Os,
+    IN gceCORE Core
+    )
+{
+    gctUINT32 i, j, data = 0, array[8] = { 0 };
+    gceSTATUS status = gcvSTATUS_OK;
+
+    gcmkHEADER();
+
+    gcmkPRINT("**************************\n");
+    gcmkPRINT("*****   MCFE STATE   *****\n");
+    gcmkPRINT("**************************\n");
+
+    /* Fetch address of channels. */
+    gcmkPRINT("Channel fetch addresses:\n");
+    gcmkPRINT("     [00]        [01]        [02]        [03]\n");
+
+    for (i = 0; i < 4; i++)
+    {
+        gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x3 + 2 * i));
+    }
+
+    for (i = 0; i < 16; i++)
+    {
+        for (j = 0; j < 4; j++)
+        {
+            gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x2 + 2 * j));
+            gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &array[j]));
+        }
+
+        gcmkPRINT("  0x%08X  0x%08X  0x%08X  0x%08X\n", array[0], array[1], array[2], array[3]);
+    }
+
+    /* Command data of channels. */
+    gcmkPRINT_N(0, "Channel command data:\n");
+    gcmkPRINT_N(0, "           [00]                    [01]                    [02]                    [03]\n");
+    gcmkPRINT_N(0, "     [Low        High]       [Low        High]       [Low        High]       [Low        High]\n");
+
+
+    for (i = 0; i < 4; i++)
+    {
+        gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x11 + 4 * i));
+        gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x11 + 4 * i + 2));
+    }
+
+    for (i = 0; i < 32; i++)
+    {
+        for (j = 0; j < 4; j++)
+        {
+            gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x10 + 4 * j));
+            gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &array[j * 2]));
+
+            gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x10 + 4 * j + 2));
+            gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &array[j * 2 + 1]));
+        }
+
+        gcmkPRINT_N(0, "  0x%08X  0x%08X  0x%08X  0x%08X  0x%08X  0x%08X  0x%08X  0x%08X\n",
+                    array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7]);
+    }
+
+    gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x00));
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+    gcmkPRINT_N(0, "0x00: 0x%08X\n", data);
+
+    gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x01));
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+    gcmkPRINT_N(0, "0x01: 0x%08X\n", data);
+
+    gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x0A));
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+    gcmkPRINT_N(0, "WaitSemaphore: 0x%08X\n", data);
+
+    gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x0B));
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+    gcmkPRINT_N(0, "WaitEventID(channel 0 and 1): 0x%08X\n", data);
+
+    gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x0C));
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+    gcmkPRINT_N(0, "WaitEventID(channel 2 and 3): 0x%08X\n", data);
+
+    gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x0D));
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+    gcmkPRINT_N(0, "DecodeState: 0x%08X\n", data);
+
+    gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x0E));
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+    gcmkPRINT_N(0, "DebugSelect(0x0E): 0x%08X\n", data);
+
+    gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x0F));
+    gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+    gcmkPRINT_N(0, "DebugSelect(0x0F): 0x%08X\n", data);
+
+    for (i = 0; i < 9; i++)
+    {
+        gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x470, 0x20 + i));
+        gcmkONERROR(gckOS_ReadRegisterEx(Os, Core, 0x450, &data));
+        gcmkPRINT_N(0, "DebugSelect(0x%02X): 0x%08X\n", 0x20 + i, data);
+    }
+
+OnError:
+    gcmkFOOTER();
+
+    return status;
+}
+
 /*******************************************************************************
 **
 **  gckHARDWARE_DumpGPUState
@@ -14640,10 +13667,12 @@ gckHARDWARE_DumpGPUState(
     {
         "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"
+        "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", "INVALID_PAR_ST", "INVALID_PAR_ST",
+        "INVALID_PAR_ST", "INVALID_PAR_ST", "INVALID_PAR_ST", "INVALID_PAR_ST",
+        "INVALID_PAR_ST", "INVALID_PAR_ST", "INVALID_PAR_ST", "INVALID_PAR_ST"
     };
 
     static gctCONST_STRING _cmdDmaState[] =
@@ -14653,41 +13682,73 @@ gckHARDWARE_DumpGPUState(
 
     static gctCONST_STRING _cmdFetState[] =
     {
-        "FET_IDLE_ST", "FET_RAMVALID_ST", "FET_VALID_ST"
+        "FET_IDLE_ST", "FET_RAMVALID_ST", "FET_VALID_ST", "INVALID_FET_ST"
     };
 
     static gctCONST_STRING _reqDmaState[] =
     {
-        "REQ_IDLE_ST", "REQ_WAITIDX_ST", "REQ_CAL_ST"
+        "REQ_IDLE_ST", "REQ_WAITIDX_ST", "REQ_CAL_ST", "INVALID_REQ_ST"
     };
 
     static gctCONST_STRING _calState[] =
     {
-        "CAL_IDLE_ST", "CAL_LDADR_ST", "CAL_IDXCALC_ST"
+        "CAL_IDLE_ST", "CAL_LDADR_ST", "CAL_IDXCALC_ST", "INVALID_CAL_ST"
     };
 
     static gctCONST_STRING _veReqState[] =
     {
-        "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST"
+        "VER_IDLE_ST", "VER_CKCACHE_ST", "VER_MISS_ST", "INVALID_VER_ST"
     };
 
-    static gcsiDEBUG_REGISTERS _dbgRegs[] =
-    {
-        { "RA", 0x474, 16, 0x448, 256, 0x1, 0x00 },
-        { "TX", 0x474, 24, 0x44C, 128, 0x1, 0x00 },
-        { "FE", 0x470, 0, 0x450, 256, 0x1, 0x00 },
-        { "PE", 0x470, 16, 0x454, 256, 0x3, 0x00 },
-        { "DE", 0x470, 8, 0x458, 256, 0x1, 0x00 },
-        { "SH", 0x470, 24, 0x45C, 256, 0x1, 0x00 },
-        { "PA", 0x474, 0, 0x460, 256, 0x1, 0x00 },
-        { "SE", 0x474, 8, 0x464, 256, 0x1, 0x00 },
-        { "MC", 0x478, 0, 0x468, 256, 0x3, 0x00 },
-        { "HI", 0x478, 8, 0x46C, 256, 0x1, 0x00 },
-        { "TPG", 0x474, 24, 0x44C, 32, 0x2, 0x80 },
-        { "TFB", 0x474, 24, 0x44C, 32, 0x2, 0xA0 },
-        { "USC", 0x474, 24, 0x44C, 64, 0x2, 0xC0 },
-        { "L2", 0x478, 0, 0x564, 256, 0x1, 0x00 },
-        { "BLT", 0x478, 24, 0x1A4, 256, 0x1, 0x00 }
+    enum
+    {
+        RA_INDEX      = 0,
+        TX_INDEX      = 1,
+        FE_INDEX      = 2,
+        PE_INDEX      = 3,
+        DE_INDEX      = 4,
+        SH_INDEX      = 5,
+        PA_INDEX      = 6,
+        SE_INDEX      = 7,
+        MC_INDEX      = 8,
+        HI_INDEX      = 9,
+        TPG_INDEX     = 10,
+        TFB_INDEX     = 11,
+        USC_INDEX     = 12,
+        L2_INDEX      = 13,
+        BLT_INDEX     = 14,
+        WD_INDEX      = 15,
+        VTXDATA_INDEX = 16,
+        DIR_INDEX     = 17,
+        PPA_INDEX     = 18,
+        NN_INDEX      = 19,
+        MODULE_MAX_INDEX,
+    };
+
+    /* must keep order correctly for _dbgRegs, we need ajust some value base on the index */
+    static gcsiDEBUG_REGISTERS _dbgRegs[MODULE_MAX_INDEX] =
+    {
+        { "RA", 0x474, 16, 0x448, 256, 0x1, 0x00, gcvTRUE, gcvTRUE  },
+        { "TX", 0x474, 24, 0x44C, 128, 0x1, 0x00, gcvTRUE, gcvTRUE  },
+        { "FE", 0x470, 0, 0x450, 256, 0x1, 0x00, gcvTRUE, gcvFALSE },
+        { "PE", 0x470, 16, 0x454, 256, 0x3, 0x00, gcvTRUE, gcvTRUE  },
+        { "DE", 0x470, 8, 0x458, 256, 0x1, 0x00, gcvTRUE, gcvFALSE },
+        { "SH", 0x470, 24, 0x45C, 256, 0x1, 0x00, gcvTRUE, gcvTRUE  },
+        { "PA", 0x474, 0, 0x460, 256, 0x1, 0x00, gcvTRUE, gcvTRUE  },
+        { "SE", 0x474, 8, 0x464, 256, 0x1, 0x00, gcvTRUE, gcvTRUE  },
+        { "MC", 0x478, 0, 0x468, 256, 0x3, 0x00, gcvTRUE, gcvTRUE  },
+        { "HI", 0x478, 8, 0x46C, 256, 0x1, 0x00, gcvTRUE, gcvFALSE },
+        { "TPG", 0x474, 24, 0x44C, 32, 0x2, 0x80, gcvFALSE, gcvTRUE  },
+        { "TFB", 0x474, 24, 0x44C, 32, 0x2, 0xA0, gcvFALSE, gcvTRUE  },
+        { "USC", 0x474, 24, 0x44C, 64, 0x2, 0xC0, gcvFALSE, gcvTRUE  },
+        { "L2", 0x478, 0, 0x564, 256, 0x1, 0x00, gcvTRUE, gcvFALSE },
+        { "BLT", 0x478, 24, 0x1A4, 256, 0x1, 0x00, gcvFALSE, gcvTRUE  },
+        { "WD", 0xF0, 16, 0xF4, 256, 0x1, 0x00, gcvFALSE, gcvFALSE },
+        { "VTXDATA", 0x474, 24, 0x44C, 64, 0x1, 0x40, gcvFALSE, gcvTRUE  },
+        { "DIR", 0xF0, 24, 0xF8, 256, 0x1, 0x00, gcvFALSE, gcvTRUE  },
+        { "PPA", 0x474, 0, 0x598, 256, 0x1, 0x00, gcvFALSE, gcvTRUE  },
+        { "NN", 0x474, 24, 0x44C, 256, 0x2, 0x00, gcvFALSE, gcvTRUE  },
+
     };
 
     static gctUINT32 _otherRegs[] =
@@ -14697,7 +13758,6 @@ gckHARDWARE_DumpGPUState(
     };
 
     gceSTATUS status;
-    gckKERNEL kernel = gcvNULL;
     gctUINT32 idle = 0, axi = 0;
     gctUINT32 dmaAddress1 = 0, dmaAddress2 = 0;
     gctUINT32 dmaState1 = 0, dmaState2 = 0;
@@ -14705,30 +13765,42 @@ gckHARDWARE_DumpGPUState(
     gctUINT32 cmdState = 0, cmdDmaState = 0, cmdFetState = 0;
     gctUINT32 dmaReqState = 0, calState = 0, veReqState = 0;
     gctUINT i;
-    gctUINT pipe = 0, pixelPipes = 0;
+    gctUINT pipe = 0, pipeMask = 0x1;
+    static const gctUINT maxNumOfPipes = 4;
     gctUINT32 control = 0, oldControl = 0;
     gckOS os = Hardware->os;
     gceCORE core = Hardware->core;
+    gceSTATUS hwTFB = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HW_TFB);
+    gceSTATUS usc = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_USC);
+    gceSTATUS multiCluster = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MULTI_CLUSTER);
+    gceSTATUS bltEngine = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE);
+    gceSTATUS gsShader = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_GEOMETRY_SHADER);
+    gceSTATUS nnEngine = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_NN_ENGINE);
 
     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;
 
+    switch (Hardware->identity.pixelPipes)
+    {
+    case 2:
+        pipeMask = 0x3;
+        break;
+    case 1:
+        pipeMask = 0x1;
+        break;
+    default:
+        gcmkASSERT(0);
+    }
     /* Verify whether DMA is running. */
     gcmkONERROR(_VerifyDMA(
         os, core, &dmaAddress1, &dmaAddress2, &dmaState1, &dmaState2
@@ -14768,14 +13840,17 @@ gckHARDWARE_DumpGPUState(
     if ((idle & 0x00000400) == 0) gcmkPRINT_N(0, "    FP not idle\n");
     if ((idle & 0x00000800) == 0) gcmkPRINT_N(0, "    TS not idle\n");
     if ((idle & 0x00001000) == 0) gcmkPRINT_N(0, "    BL not idle\n");
-    if ((idle & 0x00002000) == 0) gcmkPRINT_N(0, "    BP not idle\n");
+    if ((idle & 0x00002000) == 0) gcmkPRINT_N(0, "    ASYNCFE not idle\n");
     if ((idle & 0x00004000) == 0) gcmkPRINT_N(0, "    MC not idle\n");
+    if ((idle & 0x00008000) == 0) gcmkPRINT_N(0, "    PPA not idle\n");
+    if ((idle & 0x00010000) == 0) gcmkPRINT_N(0, "    DC not idle\n");
+    if ((idle & 0x00020000) == 0) gcmkPRINT_N(0, "    WD not idle\n");
+    if ((idle & 0x00040000) == 0) gcmkPRINT_N(0, "    NN not idle\n");
+    if ((idle & 0x00080000) == 0) gcmkPRINT_N(0, "    TP not idle\n");
     if ((idle & 0x80000000) != 0) gcmkPRINT_N(0, "    AXI low power mode\n");
 
-    if (
-        (dmaAddress1 == dmaAddress2)
-     && (dmaState1 == dmaState2)
-    )
+    if ((dmaAddress1 == dmaAddress2)
+     && (dmaState1 == dmaState2))
     {
         gcmkPRINT_N(0, "  DMA appears to be stuck at this address:\n");
         gcmkPRINT_N(4, "    0x%08X\n", dmaAddress1);
@@ -14808,6 +13883,48 @@ gckHARDWARE_DumpGPUState(
 
     gcmkPRINT_N(0, "  Debug registers:\n");
 
+    if (bltEngine)
+    {
+        _dbgRegs[BLT_INDEX].avail = gcvTRUE;
+    }
+    if (hwTFB)
+    {
+        _dbgRegs[TFB_INDEX].avail = gcvTRUE;
+    }
+    if (usc)
+    {
+        _dbgRegs[USC_INDEX].avail = gcvTRUE;
+    }
+    if (gsShader)
+    {
+        _dbgRegs[TPG_INDEX].avail = gcvTRUE;
+    }
+    if (multiCluster)
+    {
+        _dbgRegs[WD_INDEX].avail = gcvTRUE;
+        _dbgRegs[DIR_INDEX].avail = gcvTRUE;
+        _dbgRegs[VTXDATA_INDEX].avail = gcvTRUE;
+        _dbgRegs[PPA_INDEX].avail = gcvTRUE;
+        _dbgRegs[FE_INDEX].index = 0xF0;
+        _dbgRegs[HI_INDEX].index = 0xF0;
+        /*spare 64 DWORDS debug values from TX for VTXDATA prefetch in USC */
+        _dbgRegs[TX_INDEX].count = 64;
+
+        for (i = 0; i < gcmCOUNTOF(_dbgRegs); i++)
+        {
+            if (_dbgRegs[i].inCluster)
+            {
+                _dbgRegs[i].pipeMask =
+                    Hardware->identity.clusterAvailMask & Hardware->options.userClusterMask;
+            }
+        }
+        pipeMask = Hardware->identity.clusterAvailMask & Hardware->options.userClusterMask;
+    }
+    if (nnEngine)
+    {
+        _dbgRegs[NN_INDEX].avail = gcvTRUE;
+    }
+
     for (i = 0; i < gcmCOUNTOF(_dbgRegs); i += 1)
     {
         gcmkONERROR(_DumpDebugRegisters(os, core, &_dbgRegs[i]));
@@ -14816,8 +13933,11 @@ gckHARDWARE_DumpGPUState(
     /* Record control. */
     gckOS_ReadRegisterEx(os, core, 0x0, &oldControl);
 
-    for (pipe = 0; pipe < pixelPipes; pipe++)
+    for (pipe = 0; pipe < maxNumOfPipes; pipe++)
     {
+        if (((1 << pipe) & pipeMask) == 0)
+            continue;
+
         gcmkPRINT_N(4, "    Other Registers[%d]:\n", pipe);
 
         /* Switch pipe. */
@@ -14833,17 +13953,23 @@ gckHARDWARE_DumpGPUState(
             gcmkPRINT_N(12, "      [0x%04X] 0x%08X\n", _otherRegs[i], read);
         }
 
-        if (Hardware->mmuVersion)
-        {
-            gcmkPRINT("    MMU status from MC[%d]:", pipe);
+         if (Hardware->mmuVersion)
+         {
+             gcmkPRINT("    MMU status from MC[%d]:", pipe);
+             gckHARDWARE_DumpMMUException(Hardware);
+         }
+    }
 
-            gckHARDWARE_DumpMMUException(Hardware);
-        }
+    /* MCFE state. */
+    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MCFE))
+    {
+        gcmkVERIFY_OK(_DumpMCFEState(os, core));
     }
 
     /* Restore control. */
     gcmkONERROR(gckOS_WriteRegisterEx(os, core, 0x0, oldControl));
 
+
     if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_HALTI0))
     {
         /* FE debug register. */
@@ -15616,7 +14742,7 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckHARDWARE_PrepareFunctions
+**  _PrepareFunctions
 **
 **  Generate command buffer snippets which will be used by gckHARDWARE, by which
 **  gckHARDWARE can manipulate GPU by FE command without using gckCOMMAND to avoid
@@ -15634,41 +14760,48 @@ OnError:
 **     For new MMU, after GPU is reset, FE execute this command sequence to enable MMU.
 */
 gceSTATUS
-gckHARDWARE_PrepareFunctions(
-    gckHARDWARE Hardware
+_PrepareFunctions(
+    IN gckHARDWARE Hardware
     )
 {
     gckOS os;
     gceSTATUS status;
+    gcePOOL pool;
     gctUINT32 offset = 0;
-    gctUINT32 endBytes;
+    gctUINT32 endBytes = 0;
     gctUINT32 flushBytes;
+    gctPHYS_ADDR_T physical;
     gctUINT8_PTR logical;
     gctUINT32 address;
     gcsHARDWARE_FUNCTION *function;
     gceDUMMY_DRAW_TYPE dummyDrawType = gcvDUMMY_DRAW_INVALID;
+    gctUINT32 allocFlag = 0;
 
     gcmkHEADER_ARG("%x", Hardware);
 
     os = Hardware->os;
 
-    gcmkVERIFY_OK(gckOS_GetPageSize(os, &Hardware->mmuFuncBytes));
-    Hardware->auxFuncBytes = Hardware->mmuFuncBytes;
+    Hardware->auxFuncBytes = Hardware->mmuFuncBytes = 1024;
 
-    gcmkONERROR(gckHARDWARE_End(
-        Hardware,
-        gcvNULL,
-        ~0U,
-        &endBytes
-        ));
+    if (Hardware->wlFE)
+    {
+        gcmkONERROR(gckWLFE_End(Hardware, gcvNULL, ~0U, &endBytes));
+    }
 
     if ((Hardware->mmuVersion > 0) &&
         Hardware->options.enableMMU &&
         (Hardware->options.secureMode != gcvSECURE_IN_TA))
     {
-        gctUINT32 mmuBytes;
-        gctPHYS_ADDR_T physical = 0;
+        gctUINT32 mmuBytes = 0;
+        gctUINT32 tailBytes;
         gctUINT32 flags = gcvALLOC_FLAG_CONTIGUOUS;
+        gceMMU_MODE mode;
+
+#if gcdENABLE_MMU_1KMODE
+        mode = gcvMMU_MODE_1K;
+#else
+        mode = gcvMMU_MODE_4K;
+#endif
 
 #if defined(CONFIG_ZONE_DMA32)
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
@@ -15680,22 +14813,37 @@ gckHARDWARE_PrepareFunctions(
         flags |= gcvALLOC_FLAG_CACHEABLE;
 #endif
 
+        pool = gcvPOOL_DEFAULT;
+
         /* Allocate mmu command buffer within 32bit space */
-        gcmkONERROR(gckOS_AllocateNonPagedMemory(
-            os,
-            gcvFALSE,
+        gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+            Hardware->kernel,
+            64,
+            gcvVIDMEM_TYPE_COMMAND,
             flags,
             &Hardware->mmuFuncBytes,
-            &Hardware->mmuFuncPhysical,
+            &pool,
+            &Hardware->mmuFuncVideoMem
+            ));
+
+        /* Lock for kernel side CPU access. */
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+            Hardware->kernel,
+            Hardware->mmuFuncVideoMem,
+            gcvFALSE,
+            gcvFALSE,
             &Hardware->mmuFuncLogical
             ));
 
-        gcmkONERROR(gckOS_GetPhysicalAddress(
-            os,
-            Hardware->mmuFuncLogical,
+        /* Get CPU physical address. */
+        gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+            Hardware->kernel,
+            Hardware->mmuFuncVideoMem,
+            0,
             &physical
             ));
 
+        /* Convert to GPU physical address. */
         gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
             os,
             physical,
@@ -15713,112 +14861,91 @@ gckHARDWARE_PrepareFunctions(
         function->logical = (gctUINT8_PTR)Hardware->mmuFuncLogical;
         gcmkSAFECASTPHYSADDRT(function->address, physical);
 
-        gcmkONERROR(gckHARDWARE_SetMMUStates(
-            Hardware,
-            Hardware->kernel->mmu->mtlbLogical,
-            gcvMMU_MODE_4K,
-            Hardware->kernel->mmu->safePageLogical,
-            function->logical,
-            &mmuBytes
-            ));
+        if (Hardware->mcFE)
+        {
+            gcmkONERROR(_ProgramMMUStatesMCFE(
+                Hardware,
+                Hardware->kernel->mmu,
+                mode,
+                function->logical,
+                &mmuBytes
+                ));
+        }
+        else
+        {
+            gcmkONERROR(_ProgramMMUStates(
+                Hardware,
+                Hardware->kernel->mmu,
+                mode,
+                function->logical,
+                &mmuBytes
+                ));
+        }
 
         function->endAddress = function->address + mmuBytes;
         function->endLogical = function->logical + mmuBytes;
 
-        gcmkONERROR(gckHARDWARE_End(
-            Hardware,
-            function->endLogical,
-            function->endAddress,
-            &endBytes
-            ));
+        if (Hardware->wlFE)
+        {
+            tailBytes = (gctUINT32)(Hardware->mmuFuncBytes - mmuBytes);
+            gcmkONERROR(gckWLFE_End(Hardware, function->endLogical, function->endAddress, &tailBytes));
+        }
+        else
+        {
+            tailBytes = 0;
+        }
 
-        function->bytes = mmuBytes + endBytes;
+        function->bytes = mmuBytes + tailBytes;
 
-        gcmkONERROR(gckOS_CacheClean(
-            Hardware->os,
-            0,
-            Hardware->mmuFuncPhysical,
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Hardware->kernel,
+            Hardware->mmuFuncVideoMem,
             0,
             Hardware->mmuFuncLogical,
             function->bytes
             ));
     }
 
-#if USE_KERNEL_VIRTUAL_BUFFERS
-    if (Hardware->kernel->virtualCommandBuffer)
-    {
-        gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer = gcvNULL;
-        gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
-            Hardware->kernel,
-            gcvFALSE,
-            &Hardware->auxFuncBytes,
-            &Hardware->auxFuncPhysical,
-            &Hardware->auxFuncLogical
-            ));
-
-        gcmkONERROR(gckKERNEL_GetGPUAddress(
-            Hardware->kernel,
-            Hardware->auxFuncLogical,
-            gcvFALSE,
-            Hardware->auxFuncPhysical,
-            &Hardware->auxFuncAddress
-            ));
-
-        commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR) Hardware->auxFuncPhysical;
-
-        Hardware->auxPhysHandle = commandBuffer->virtualBuffer.physical;
-    }
-    else
-#endif
-    {
-        gctPHYS_ADDR_T physical = 0;
-        gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+    pool = gcvPOOL_DEFAULT;
 
 #if gcdENABLE_CACHEABLE_COMMAND_BUFFER
-        allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+    allocFlag = gcvALLOC_FLAG_CACHEABLE;
 #endif
 
-        /* Allocate a command buffer. */
-        gcmkONERROR(gckOS_AllocateNonPagedMemory(
-            os,
-            gcvFALSE,
-            allocFlag,
-            &Hardware->auxFuncBytes,
-            &Hardware->auxFuncPhysical,
-            &Hardware->auxFuncLogical
-            ));
-
-        gcmkONERROR(gckOS_GetPhysicalAddress(
-            os,
-            Hardware->auxFuncLogical,
-            &physical
-            ));
-
-        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
-            os,
-            physical,
-            &physical
-            ));
-
-        gcmkSAFECASTPHYSADDRT(Hardware->auxFuncAddress, physical);
+    /* Allocate video memory node for aux functions. */
+    gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+        Hardware->kernel,
+        64,
+        gcvVIDMEM_TYPE_COMMAND,
+        allocFlag,
+        &Hardware->auxFuncBytes,
+        &pool,
+        &Hardware->auxFuncVideoMem
+        ));
 
-        gcmkONERROR(gckMMU_FillFlatMapping(
-            Hardware->kernel->mmu,
-            Hardware->auxFuncAddress,
-            Hardware->auxFuncBytes
-            ));
+    /* Lock for GPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_Lock(
+        Hardware->kernel,
+        Hardware->auxFuncVideoMem,
+        &Hardware->auxFuncAddress
+        ));
 
-        Hardware->auxPhysHandle = Hardware->auxFuncPhysical;
-    }
+    /* Lock for kernel side CPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+        Hardware->kernel,
+        Hardware->auxFuncVideoMem,
+        gcvFALSE,
+        gcvFALSE,
+        &Hardware->auxFuncLogical
+        ));
 
     /*
     ** All cache flush command sequence.
     */
     function = &Hardware->functions[gcvHARDWARE_FUNCTION_FLUSH];
 
-    function->logical = logical = (gctUINT8_PTR)Hardware->auxFuncLogical + offset;
-
-    function->address = Hardware->auxFuncAddress + offset;
+    function->logical = logical = (gctUINT8_PTR)Hardware->auxFuncLogical;
+    function->address = Hardware->auxFuncAddress;
 
     /* Get the size of the flush command. */
     gcmkONERROR(gckHARDWARE_Flush(Hardware, gcvFLUSH_ALL, gcvNULL, &flushBytes));
@@ -15831,20 +14958,10 @@ gckHARDWARE_PrepareFunctions(
     logical = (gctUINT8_PTR)Hardware->auxFuncLogical + offset;
     address = Hardware->auxFuncAddress + offset;
 
-    gcmkONERROR(gckHARDWARE_End(Hardware, logical, address, &endBytes));
-
-#if USE_KERNEL_VIRTUAL_BUFFERS
-    if (Hardware->kernel->virtualCommandBuffer)
+    if (Hardware->wlFE)
     {
-        gcmkONERROR(gckKERNEL_GetGPUAddress(
-            Hardware->kernel,
-            logical,
-            gcvFALSE,
-            Hardware->auxFuncPhysical,
-            &Hardware->lastEnd
-            ));
+        gcmkONERROR(gckWLFE_End(Hardware, logical, address, &endBytes));
     }
-#endif
 
     offset += endBytes;
 
@@ -15853,38 +14970,6 @@ gckHARDWARE_PrepareFunctions(
     function->endAddress = function->address + flushBytes;
     function->endLogical = function->logical + flushBytes;
 
-    /*
-    ** ASYNC-BLT Engine event command
-    */
-    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_ASYNC_BLIT))
-    {
-        gctUINT8 i;
-        gctUINT32 eventBytes;
-
-        function = &Hardware->functions[gcvHARDWARE_FUNCTION_BLT_EVENT];
-
-        function->logical = logical = (gctUINT8_PTR)Hardware->auxFuncLogical + offset;
-        function->address = Hardware->auxFuncAddress + offset;
-
-        gcmkONERROR(gckHARDWARE_Event(Hardware, gcvNULL, 0, gcvKERNEL_BLT, &eventBytes));
-
-        for (i = 0; i < 29; i++)
-        {
-            gcmkONERROR(gckHARDWARE_Event(
-                Hardware,
-                logical + i * eventBytes,
-                i,
-                gcvKERNEL_BLT,
-                &eventBytes
-                ));
-
-            offset += eventBytes;
-        }
-
-        function->bytes = eventBytes * 29;
-    }
-
-
     /************************************************************************************
     * Dummy draw.
     */
@@ -15916,9 +15001,12 @@ gckHARDWARE_PrepareFunctions(
         logical += dummyDrawBytes;
         address  = function->address + dummyDrawBytes;
 
-        gcmkONERROR(gckHARDWARE_End(Hardware, logical, address, &endBytes));
+        if (Hardware->wlFE)
+        {
+            gcmkONERROR(gckWLFE_End(Hardware, logical, address, &endBytes));
 
-        offset += endBytes;
+            offset += endBytes;
+        }
 
         function->endAddress = function->address + dummyDrawBytes;
         function->endLogical = function->logical + dummyDrawBytes;
@@ -15927,10 +15015,9 @@ gckHARDWARE_PrepareFunctions(
     }
     gcmkASSERT(offset < Hardware->auxFuncBytes);
 
-    gcmkONERROR(gckOS_CacheClean(
-        Hardware->os,
-        0,
-        Hardware->auxPhysHandle,
+    gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+        Hardware->kernel,
+        Hardware->auxFuncVideoMem,
         0,
         Hardware->auxFuncLogical,
         Hardware->auxFuncBytes
@@ -15944,50 +15031,6 @@ OnError:
     return status;
 }
 
-gceSTATUS
-gckHARDWARE_DestroyFunctions(
-    gckHARDWARE Hardware
-    )
-{
-    gcmkHEADER_ARG("%x", Hardware);
-
-    if (Hardware->auxFuncPhysical)
-    {
-#if USE_KERNEL_VIRTUAL_BUFFERS
-        if (Hardware->kernel->virtualCommandBuffer)
-        {
-            gcmkVERIFY_OK(gckKERNEL_FreeVirtualMemory(
-                Hardware->auxFuncPhysical,
-                Hardware->auxFuncLogical,
-                gcvFALSE
-                ));
-        }
-        else
-#endif
-        {
-            gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
-                Hardware->os,
-                Hardware->auxFuncBytes,
-                Hardware->auxFuncPhysical,
-                Hardware->auxFuncLogical
-                ));
-        }
-    }
-
-    if (Hardware->mmuFuncPhysical)
-    {
-        gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
-            Hardware->os,
-            Hardware->mmuFuncBytes,
-            Hardware->mmuFuncPhysical,
-            Hardware->mmuFuncLogical
-            ));
-    }
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
 gceSTATUS
 gckHARDWARE_ExecuteFunctions(
     IN gckHARDWARE Hardware,
@@ -16000,24 +15043,18 @@ gckHARDWARE_ExecuteFunctions(
     gcsHARDWARE_FUNCTION * function = &Hardware->functions[Function];
     gctUINT32 address;
 
-#if USE_KERNEL_VIRTUAL_BUFFERS
-    if (Hardware->kernel->virtualCommandBuffer)
+    address = function->address;
+
+    /* Execute prepared command sequence. */
+    if (Hardware->mcFE)
     {
-        address = function->address;
+        gcmkONERROR(gckMCFE_Execute(Hardware, gcvFALSE, 0, address, function->bytes));
     }
     else
-#endif
     {
-        address = function->address - Hardware->baseAddress;
+        gcmkONERROR(gckWLFE_Execute(Hardware, address, function->bytes));
     }
 
-    /* Execute prepared command sequence. */
-    gcmkONERROR(gckHARDWARE_Execute(
-        Hardware,
-        address,
-        function->bytes
-        ));
-
 #if gcdLINK_QUEUE_SIZE
     {
         gcuQUEUEDATA data;
@@ -16033,18 +15070,27 @@ gckHARDWARE_ExecuteFunctions(
     }
 #endif
 
-    gcmkDUMPCOMMAND(
+    {
+        static char *func[] =
+        {
+            "set mmu",
+            "flush",
+            "dummy draw",
+            ""
+        };
+
+        (void)func;
+        gcmkDUMP(Hardware->os, "#[function: %s]", func[Function]);
+    }
+
+    gcmkDUMP_BUFFER(
         Hardware->os,
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
         function->logical,
-        function->bytes,
-        gcvDUMP_BUFFER_KERNEL,
-        gcvTRUE
+        address,
+        function->bytes
         );
 
-#if gcdDUMP_COMMAND
-    gcmkPRINT("@[kernel.execute]");
-#endif
-
     /* Wait until GPU idle. */
     do
     {
@@ -16063,7 +15109,11 @@ gckHARDWARE_ExecuteFunctions(
         if (timer >= Hardware->kernel->timeOut)
         {
             gckHARDWARE_DumpGPUState(Hardware);
-            gckCOMMAND_DumpExecutingBuffer(Hardware->kernel->command);
+
+            if (Hardware->kernel->command)
+            {
+                gckCOMMAND_DumpExecutingBuffer(Hardware->kernel->command);
+            }
 
             /* Even if hardware is not reset correctly, let software
             ** continue to avoid software stuck. Software will timeout again
@@ -16081,30 +15131,9 @@ OnError:
     return status;
 }
 
-gceSTATUS
-gckHARDWARE_AddressInHardwareFuncions(
-    IN gckHARDWARE Hardware,
-    IN gctUINT32 Address,
-    OUT gctPOINTER *Pointer
-    )
-{
-    if (Address >= Hardware->auxFuncAddress && Address <= Hardware->auxFuncAddress - 1 + Hardware->auxFuncBytes)
-    {
-        *Pointer = (gctUINT8_PTR)Hardware->auxFuncLogical
-                 + (Address - Hardware->auxFuncAddress)
-                 ;
-
-        return gcvSTATUS_OK;
-    }
-
-    return gcvSTATUS_NOT_FOUND;
-}
-
 gceSTATUS
 gckHARDWARE_QueryStateTimer(
     IN gckHARDWARE Hardware,
-    OUT gctUINT64_PTR Start,
-    OUT gctUINT64_PTR End,
     OUT gctUINT64_PTR On,
     OUT gctUINT64_PTR Off,
     OUT gctUINT64_PTR Idle,
@@ -16114,7 +15143,9 @@ gckHARDWARE_QueryStateTimer(
     gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, gcvINFINITE);
 
     gckSTATETIMER_Query(
-        &Hardware->powerStateTimer, Hardware->chipPowerState, Start, End, On, Off, Idle, Suspend);
+        &Hardware->powerStateCounter,
+        Hardware->chipPowerState,
+        On, Off, Idle, Suspend);
 
     gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
 
@@ -16255,7 +15286,7 @@ gckHARDWARE_UpdateContextID(
     IN gckHARDWARE Hardware
     )
 {
-    static gcsiDEBUG_REGISTERS fe = { "FE", 0x470, 0, 0x450, 256, 0x1, 0x00 };
+    static gcsiDEBUG_REGISTERS fe = { "FE", 0x470, 0, 0x450, 256, 0x1, 0x00, gcvTRUE, gcvFALSE};
     gckOS os = Hardware->os;
     gceCORE core = Hardware->core;
     gctUINT32 contextIDLow, contextIDHigh;
@@ -16275,132 +15306,6 @@ OnError:
     return status;
 }
 
-gceSTATUS
-gckFE_Initialize(
-    IN gckHARDWARE Hardware,
-    OUT gckFE FE
-    )
-{
-    gceSTATUS status;
-    gctUINT32 data;
-
-    gcmkHEADER();
-
-    gckOS_ZeroMemory(FE, gcmSIZEOF(gcsFE));
-
-    gcmkVERIFY_OK(gckOS_ReadRegisterEx(
-        Hardware->os,
-        Hardware->core,
-        0x007E4,
-       &data
-        ));
-
-    gcmkONERROR(gckOS_AtomConstruct(Hardware->os, &FE->freeDscriptors));
-
-    data = (((((gctUINT32) (data)) >> (0 ? 6:0)) & ((gctUINT32) ((((1 ? 6:0) - (0 ? 6:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 6:0) - (0 ? 6:0) + 1)))))) );
-
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "free descriptor=%d", data);
-
-    gcmkONERROR(gckOS_AtomSet(Hardware->os, FE->freeDscriptors, data));
-
-    /* Enable interrupts. */
-    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x000D8, ~0U);
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-
-    if (FE->freeDscriptors)
-    {
-        gckOS_AtomDestroy(Hardware->os, FE->freeDscriptors);
-    }
-
-    gcmkFOOTER();
-    return status;
-}
-
-void
-gckFE_UpdateAvaiable(
-    IN gckHARDWARE Hardware,
-    OUT gckFE FE
-    )
-{
-    gceSTATUS status;
-    gctUINT32 data;
-    gctINT32 oldValue;
-
-    status = gckOS_ReadRegisterEx(
-        Hardware->os,
-        Hardware->core,
-        0x007E4,
-        &data
-        );
-
-    if (gcmIS_SUCCESS(status))
-    {
-        data = (((((gctUINT32) (data)) >> (0 ? 6:0)) & ((gctUINT32) ((((1 ? 6:0) - (0 ? 6:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 6:0) - (0 ? 6:0) + 1)))))) );
-
-        while (data--)
-        {
-            gckOS_AtomIncrement(Hardware->os, FE->freeDscriptors, &oldValue);
-        }
-    }
-}
-
-gceSTATUS
-gckFE_ReserveSlot(
-    IN gckHARDWARE Hardware,
-    IN gckFE FE,
-    OUT gctBOOL * Available
-    )
-{
-    gctINT32 oldValue;
-
-    gckOS_AtomDecrement(Hardware->os, FE->freeDscriptors, &oldValue);
-
-    if (oldValue > 0)
-    {
-        /* Get one slot. */
-        *Available = gcvTRUE;
-    }
-    else
-    {
-        /* No available slot, restore decreased one.*/
-        gckOS_AtomIncrement(Hardware->os, FE->freeDscriptors, &oldValue);
-        *Available = gcvFALSE;
-    }
-
-    return gcvSTATUS_OK;
-}
-
-void
-gckFE_Execute(
-    IN gckHARDWARE Hardware,
-    IN gckFE FE,
-    IN gcsFEDescriptor * Desc
-    )
-{
-    gckOS_WriteRegisterEx(
-        Hardware->os,
-        Hardware->core,
-        0x007DC,
-        Desc->start
-        );
-
-    gckOS_MemoryBarrier(
-        Hardware->os,
-        gcvNULL
-        );
-
-    gckOS_WriteRegisterEx(
-        Hardware->os,
-        Hardware->core,
-        0x007E0,
-        Desc->end
-        );
-}
-
 gceSTATUS
 gckHARDWARE_DummyDraw(
     IN gckHARDWARE Hardware,
@@ -18312,6 +17217,58 @@ gckHARDWARE_DummyDraw(
  4:4) - (0 ?
  4:4) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))),
+
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+        /* SubmitJob. */
+        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE))),
+        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE))),
+        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE))),
+        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE))),
+#  endif
     };
 
     gctUINT32 bytes = 0;
@@ -18328,6 +17285,45 @@ gckHARDWARE_DummyDraw(
     case gcvDUMMY_DRAW_V60:
         dummyDraw = dummyDraw_v60;
         bytes = gcmSIZEOF(dummyDraw_v60);
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+        if (_QueryFeatureDatabase(Hardware, gcvFEATURE_MCFE))
+        {
+            gctUINT32 submitJob;
+
+            submitJob = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+                      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_SUBMIT_JOB & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)));
+
+            if (bytes & 8)
+            {
+                /* To keep 16 byte alignment. */
+                bytes -= 8;
+            }
+
+            dummyDraw[(bytes >> 2) - 2] = submitJob;
+        }
+#  endif
         break;
     default:
         /* other chip no need dummy draw.*/
@@ -18448,13 +17444,13 @@ gckHARDWARE_QueryFrequency(
     gctUINT64 mcStart, shStart;
     gctUINT32 mcClk, shClk;
     gceSTATUS status;
-    gctUINT32 powerManagement = 0;
+    gctUINT64 powerManagement = 0;
     gctBOOL globalAcquired = gcvFALSE;
     gceCHIPPOWERSTATE statesStored, state;
 
     gcmkHEADER_ARG("Hardware=0x%p", Hardware);
 
-    gcmkVERIFY_ARGUMENT(Hardware != NULL);
+    gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
 
     mcStart = shStart = 0;
     mcClk   = shClk   = 0;
@@ -18463,16 +17459,16 @@ gckHARDWARE_QueryFrequency(
 
     if (powerManagement)
     {
-        gcmkONERROR(gckHARDWARE_SetPowerManagement(
+        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
             Hardware, gcvFALSE
             ));
     }
 
-    gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+    gcmkONERROR(gckHARDWARE_QueryPowerState(
         Hardware, &statesStored
         ));
 
-    gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+    gcmkONERROR(gckHARDWARE_SetPowerState(
         Hardware, gcvPOWER_ON_AUTO
         ));
 
@@ -18525,12 +17521,12 @@ gckHARDWARE_QueryFrequency(
 
     if (powerManagement)
     {
-        gcmkONERROR(gckHARDWARE_SetPowerManagement(
+        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
             Hardware, gcvTRUE
             ));
     }
 
-    gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+    gcmkONERROR(gckHARDWARE_SetPowerState(
         Hardware, state
         ));
 
index 5c08ace..e7a1915 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 extern "C" {
 #endif
 
+#define EVENT_ID_INVALIDATE_PIPE    29
+
 typedef enum {
     gcvHARDWARE_FUNCTION_MMU,
     gcvHARDWARE_FUNCTION_FLUSH,
 
-    /* BLT engine command sequence. */
-    gcvHARDWARE_FUNCTION_BLT_EVENT,
     gcvHARDWARE_FUNCTION_DUMMY_DRAW,
     gcvHARDWARE_FUNCTION_NUM,
 }
 gceHARDWARE_FUNCTION;
 
+typedef struct _gckASYNC_FE *   gckASYNC_FE;
+typedef struct _gckWLFE *       gckWLFE;
+typedef struct _gckMCFE *       gckMCFE;
 
 typedef struct _gcsHARWARE_FUNCTION
 {
@@ -139,15 +142,15 @@ typedef struct _gcsHARDWARE_PAGETABLE_ARRAY
     /* Number of entries in page table array. */
     gctUINT                     num;
 
+    /* Video memory node. */
+    gckVIDMEM_NODE              videoMem;
+
     /* Size in bytes of array. */
     gctSIZE_T                   size;
 
     /* Physical address of array. */
     gctPHYS_ADDR_T              address;
 
-    /* Memory descriptor. */
-    gctPHYS_ADDR                physical;
-
     /* Logical address of array. */
     gctPOINTER                  logical;
 }
@@ -168,6 +171,9 @@ struct _gckHARDWARE
     /* Core */
     gceCORE                     core;
 
+    /* Type */
+    gceHARDWARE_TYPE            type;
+
     /* Chip characteristics. */
     gcsHAL_QUERY_CHIP_IDENTITY  identity;
     gcsHAL_QUERY_CHIP_OPTIONS   options;
@@ -180,27 +186,26 @@ struct _gckHARDWARE
     /* Base address. */
     gctUINT32                   baseAddress;
 
+    /* FE modules. */
+    gckWLFE                     wlFE;
+    gckASYNC_FE                 asyncFE;
+    gckMCFE                     mcFE;
+
     /* Chip status */
     gctPOINTER                  powerMutex;
-    gctUINT32                   powerProcess;
-    gctUINT32                   powerThread;
     gceCHIPPOWERSTATE           chipPowerState;
-    gctUINT32                   lastWaitLink;
-    gctUINT32                   lastEnd;
     gctBOOL                     clockState;
     gctBOOL                     powerState;
     gctPOINTER                  globalSemaphore;
 
-    gctUINT32                   mmuVersion;
+    /* Wait Link FE only. */
+    gctUINT32                   lastWaitLink;
+    gctUINT32                   lastEnd;
 
-    /* Type */
-    gceHARDWARE_TYPE            type;
+    gctUINT32                   mmuVersion;
 
-#if gcdPOWEROFF_TIMEOUT
-    gctUINT32                   powerOffTime;
-    gctUINT32                   powerOffTimeout;
-    gctPOINTER                  powerOffTimer;
-#endif
+    gceCHIPPOWERSTATE           nextPowerState;
+    gctPOINTER                  powerStateTimer;
 
 #if gcdENABLE_FSCALE_VAL_ADJUST
     gctUINT32                   powerOnFscaleVal;
@@ -221,29 +226,37 @@ struct _gckHARDWARE
     gctPOINTER                  pendingEvent;
 
     /* Function used by gckHARDWARE. */
-    gctPHYS_ADDR                mmuFuncPhysical;
+    gckVIDMEM_NODE              mmuFuncVideoMem;
     gctPOINTER                  mmuFuncLogical;
     gctSIZE_T                   mmuFuncBytes;
 
-    gctPHYS_ADDR                auxFuncPhysical;
-    gctPHYS_ADDR                auxPhysHandle;
+    gckVIDMEM_NODE              auxFuncVideoMem;
     gctPOINTER                  auxFuncLogical;
     gctUINT32                   auxFuncAddress;
     gctSIZE_T                   auxFuncBytes;
 
     gcsHARDWARE_FUNCTION        functions[gcvHARDWARE_FUNCTION_NUM];
 
-    gcsSTATETIMER               powerStateTimer;
+    gcsSTATETIMER               powerStateCounter;
     gctUINT32                   executeCount;
     gctUINT32                   lastExecuteAddress;
 
     /* Head for hardware list in gckMMU. */
     gcsLISTHEAD                 mmuHead;
 
+    /* SRAM mode. */
+    gctUINT32                   sRAMNonExclusive;
+    gckVIDMEM                   sRAMVideoMem[gcvSRAM_COUNT];
+    gctPHYS_ADDR                sRAMPhysical[gcvSRAM_COUNT];
+    gctPOINTER                  sRAMLogical[gcvSRAM_COUNT];
+
     gctPOINTER                  featureDatabase;
-    gctBOOL                     hasAsyncFe;
     gctBOOL                     hasL2Cache;
 
+    /* MCFE channel bindings, temporary. */
+    gceMCFE_CHANNEL_TYPE        mcfeChannels[64];
+    gctUINT32                   mcfeChannelCount;
+
     gcsHARDWARE_SIGNATURE       signature;
 
     gctUINT32                   maxOutstandingReads;
@@ -253,49 +266,6 @@ struct _gckHARDWARE
     gctUINT64                   contextID;
 };
 
-typedef struct _gcsFEDescriptor
-{
-    gctUINT32                   start;
-    gctUINT32                   end;
-}
-gcsFEDescriptor;
-
-typedef struct _gcsFE *         gckFE;
-typedef struct _gcsFE
-{
-    gckOS                       os;
-
-    /* Number of free descriptors. */
-    gctPOINTER                  freeDscriptors;
-}
-gcsFE;
-
-gceSTATUS
-gckFE_Initialize(
-    IN gckHARDWARE Hardware,
-    OUT gckFE FE
-    );
-
-gceSTATUS
-gckFE_ReserveSlot(
-    IN gckHARDWARE Hardware,
-    IN gckFE FE,
-    OUT gctBOOL * Available
-    );
-
-void
-gckFE_UpdateAvaiable(
-    IN gckHARDWARE Hardware,
-    OUT gckFE FE
-    );
-
-void
-gckFE_Execute(
-    IN gckHARDWARE Hardware,
-    IN gckFE FE,
-    IN gcsFEDescriptor * Desc
-    );
-
 gceSTATUS
 gckHARDWARE_GetBaseAddress(
     IN gckHARDWARE Hardware,
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_async_fe.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_async_fe.c
new file mode 100644 (file)
index 0000000..bfebefd
--- /dev/null
@@ -0,0 +1,656 @@
+/****************************************************************************
+*
+*    The MIT License (MIT)
+*
+*    Copyright (c) 2014 - 2019 Vivante Corporation
+*
+*    Permission is hereby granted, free of charge, to any person obtaining a
+*    copy of this software and associated documentation files (the "Software"),
+*    to deal in the Software without restriction, including without limitation
+*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+*    and/or sell copies of the Software, and to permit persons to whom the
+*    Software is furnished to do so, subject to the following conditions:
+*
+*    The above copyright notice and this permission notice shall be included in
+*    all copies or substantial portions of the Software.
+*
+*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+*    DEALINGS IN THE SOFTWARE.
+*
+*****************************************************************************
+*
+*    The GPL License (GPL)
+*
+*    Copyright (C) 2014 - 2019 Vivante Corporation
+*
+*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+*    Note: This software is released under dual MIT and GPL licenses. A
+*    recipient may use this file under the terms of either the MIT license or
+*    GPL License. If you wish to use only one license not the other, you can
+*    indicate your decision by deleting one of the above license notices in your
+*    version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+
+#define _GC_OBJ_ZONE    gcvZONE_HARDWARE
+
+struct _gckASYNC_FE
+{
+    /* Number of free descriptors. */
+    gctPOINTER                  freeDscriptors;
+};
+
+gceSTATUS
+gckASYNC_FE_Construct(
+    IN gckHARDWARE Hardware,
+    OUT gckASYNC_FE * FE
+    )
+{
+    gceSTATUS status;
+    gctUINT32 data;
+    gckASYNC_FE fe;
+
+    gcmkHEADER();
+
+    gcmkONERROR(gckOS_Allocate(Hardware->os,
+                               gcmSIZEOF(struct _gckASYNC_FE),
+                               (gctPOINTER *)&fe));
+    gckOS_ZeroMemory(fe, gcmSIZEOF(struct _gckASYNC_FE));
+
+    gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+        Hardware->os,
+        Hardware->core,
+        0x007E4,
+       &data
+        ));
+
+    gcmkONERROR(gckOS_AtomConstruct(Hardware->os, &fe->freeDscriptors));
+
+    data = (((((gctUINT32) (data)) >> (0 ? 6:0)) & ((gctUINT32) ((((1 ? 6:0) - (0 ? 6:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 6:0) - (0 ? 6:0) + 1)))))) );
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "free descriptor=%d", data);
+
+    gcmkONERROR(gckOS_AtomSet(Hardware->os, fe->freeDscriptors, data));
+
+    /* Enable interrupts. */
+    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x000D8, ~0U);
+
+    *FE = fe;
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    if (fe->freeDscriptors)
+    {
+        gckOS_AtomDestroy(Hardware->os, fe->freeDscriptors);
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+void
+gckASYNC_FE_Destroy(
+    IN gckHARDWARE Hardware,
+    IN gckASYNC_FE FE
+    )
+{
+    if (FE->freeDscriptors)
+    {
+        gcmkOS_SAFE_FREE(Hardware->os, FE->freeDscriptors);
+    }
+
+    gcmkOS_SAFE_FREE(Hardware->os, FE);
+}
+
+gceSTATUS
+gckASYNC_FE_Initialize(
+    IN gckHARDWARE Hardware,
+    IN gckASYNC_FE FE
+    )
+{
+    return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckASYNC_FE_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) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((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;
+}
+
+gceSTATUS
+gckASYNC_FE_Event(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT8 Event,
+    IN gceKERNEL_WHERE FromWhere,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+    gctUINT size;
+    gctUINT32 destination = 0;
+    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+    gceSTATUS status;
+    gctBOOL blt;
+    gctBOOL extraEventStates;
+    gctBOOL multiCluster;
+
+    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);
+
+    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE))
+    {
+        /* Send all event from blt. */
+        if (FromWhere == gcvKERNEL_PIXEL)
+        {
+            FromWhere = gcvKERNEL_BLT;
+        }
+    }
+
+    blt = FromWhere == gcvKERNEL_BLT ? gcvTRUE : gcvFALSE;
+
+    multiCluster = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MULTI_CLUSTER);
+
+    /* Determine the size of the command. */
+
+    extraEventStates = Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL);
+
+    size = extraEventStates
+         ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
+         : 8;
+
+    if (blt)
+    {
+        size += 16;
+        if (multiCluster)
+            size += 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) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((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) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+            break;
+
+        case gcvKERNEL_BLT:
+            destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
+            break;
+
+        default:
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+        }
+
+        if (blt)
+        {
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+            if (multiCluster)
+            {
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x50CE) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.clusterAvailMask & Hardware->options.userClusterMask) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
+            }
+        }
+
+        /* Append EVENT(Event, destination). */
+        *logical++
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+        *logical++
+            = ((((gctUINT32) (destination)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (Event) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+
+        if (blt)
+        {
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0: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)
+        {
+            gctPHYS_ADDR_T phys;
+            gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
+            gckOS_CPUPhysicalToGPUPhysical(Hardware->os, phys, &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 (extraEventStates)
+        {
+            *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0100) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+        }
+
+#if gcdINTERRUPT_STATISTIC
+        if (Event < gcmCOUNTOF(Hardware->kernel->eventObj->queues))
+        {
+            gckOS_AtomSetMask(Hardware->pendingEvent, 1 << Event);
+        }
+#endif
+    }
+
+    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;
+}
+
+
+void
+gckASYNC_FE_UpdateAvaiable(
+    IN gckHARDWARE Hardware
+    )
+{
+    gceSTATUS status;
+    gctUINT32 data;
+    gctINT32 oldValue;
+    gckASYNC_FE fe = Hardware->asyncFE;
+
+    status = gckOS_ReadRegisterEx(
+        Hardware->os,
+        Hardware->core,
+        0x007E4,
+        &data
+        );
+
+    if (gcmIS_SUCCESS(status))
+    {
+        data = (((((gctUINT32) (data)) >> (0 ? 6:0)) & ((gctUINT32) ((((1 ? 6:0) - (0 ? 6:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 6:0) - (0 ? 6:0) + 1)))))) );
+
+        while (data--)
+        {
+            gckOS_AtomIncrement(Hardware->os, fe->freeDscriptors, &oldValue);
+        }
+    }
+}
+
+gceSTATUS
+gckASYNC_FE_ReserveSlot(
+    IN gckHARDWARE Hardware,
+    OUT gctBOOL * Available
+    )
+{
+    gctINT32 oldValue;
+    gckASYNC_FE fe = Hardware->asyncFE;
+
+    gckOS_AtomDecrement(Hardware->os, fe->freeDscriptors, &oldValue);
+
+    if (oldValue > 0)
+    {
+        /* Get one slot. */
+        *Available = gcvTRUE;
+    }
+    else
+    {
+        /* No available slot, restore decreased one.*/
+        gckOS_AtomIncrement(Hardware->os, fe->freeDscriptors, &oldValue);
+        *Available = gcvFALSE;
+    }
+
+    return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckASYNC_FE_Execute(
+    IN gckHARDWARE Hardware,
+    IN gctUINT32 Address,
+    IN gctUINT32 Bytes
+    )
+{
+    gckOS_WriteRegisterEx(
+        Hardware->os,
+        Hardware->core,
+        0x007DC,
+        Address
+        );
+
+    gckOS_MemoryBarrier(
+        Hardware->os,
+        gcvNULL
+        );
+
+    gckOS_WriteRegisterEx(
+        Hardware->os,
+        Hardware->core,
+        0x007E0,
+        Address + Bytes
+        );
+
+    return gcvSTATUS_OK;
+}
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_fe.h b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_fe.h
new file mode 100644 (file)
index 0000000..b673e63
--- /dev/null
@@ -0,0 +1,290 @@
+/****************************************************************************
+*
+*    The MIT License (MIT)
+*
+*    Copyright (c) 2014 - 2019 Vivante Corporation
+*
+*    Permission is hereby granted, free of charge, to any person obtaining a
+*    copy of this software and associated documentation files (the "Software"),
+*    to deal in the Software without restriction, including without limitation
+*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+*    and/or sell copies of the Software, and to permit persons to whom the
+*    Software is furnished to do so, subject to the following conditions:
+*
+*    The above copyright notice and this permission notice shall be included in
+*    all copies or substantial portions of the Software.
+*
+*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+*    DEALINGS IN THE SOFTWARE.
+*
+*****************************************************************************
+*
+*    The GPL License (GPL)
+*
+*    Copyright (C) 2014 - 2019 Vivante Corporation
+*
+*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+*    Note: This software is released under dual MIT and GPL licenses. A
+*    recipient may use this file under the terms of either the MIT license or
+*    GPL License. If you wish to use only one license not the other, you can
+*    indicate your decision by deleting one of the above license notices in your
+*    version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_kernel_hardware_fe_h_
+#define __gc_hal_kernel_hardware_fe_h_
+
+#include "gc_hal.h"
+
+/******************************************************************************/
+/* Wait-Link FE commands. */
+
+/* Construct Wait-Link FE. */
+gceSTATUS
+gckWLFE_Construct(
+    IN gckHARDWARE Hardware,
+    OUT gckWLFE * FE
+    );
+
+void
+gckWLFE_Destroy(
+    IN gckHARDWARE Hardware,
+    IN gckWLFE FE
+    );
+
+/* Initialize Wait-Link FE, when hardware reset. */
+gceSTATUS
+gckWLFE_Initialize(
+    IN gckHARDWARE Hardware,
+    IN gckWLFE FE
+    );
+
+
+/* Add a WAIT/LINK pair in the command queue. */
+gceSTATUS
+gckWLFE_WaitLink(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Address,
+    IN gctUINT32 Offset,
+    IN OUT gctUINT32 * Bytes,
+    OUT gctUINT32 * WaitOffset,
+    OUT gctUINT32 * WaitBytes
+    );
+
+/* Add a LINK command in the command queue. */
+gceSTATUS
+gckWLFE_Link(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 FetchAddress,
+    IN gctUINT32 FetchSize,
+    IN OUT gctUINT32 * Bytes,
+    OUT gctUINT32 * Low,
+    OUT gctUINT32 * High
+    );
+
+/* Add an END command in the command queue. */
+gceSTATUS
+gckWLFE_End(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Address,
+    IN OUT gctUINT32 * Bytes
+    );
+
+/* Add a NOP command in the command queue. */
+gceSTATUS
+gckWLFE_Nop(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN OUT gctSIZE_T * Bytes
+    );
+
+/* Add an EVENT command in the command queue. */
+gceSTATUS
+gckWLFE_Event(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT8 Event,
+    IN gceKERNEL_WHERE FromWhere,
+    IN OUT gctUINT32 * Bytes
+    );
+
+gceSTATUS
+gckWLFE_ChipEnable(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gceCORE_3D_MASK ChipEnable,
+    IN OUT gctSIZE_T * Bytes
+    );
+
+/* Kickstart the command processor. */
+gceSTATUS
+gckWLFE_Execute(
+    IN gckHARDWARE Hardware,
+    IN gctUINT32 Address,
+    IN gctUINT32 Bytes
+    );
+
+/* Atomic version or IRQ routine. */
+gceSTATUS
+gckWLFE_AtomicExecute(
+    IN gckHARDWARE Hardware,
+    IN gctUINT32 Address,
+    IN gctUINT32 Bytes
+    );
+
+/******************************************************************************/
+/* ASync FE commands. */
+
+gceSTATUS
+gckASYNC_FE_Construct(
+    IN gckHARDWARE Hardware,
+    OUT gckASYNC_FE * FE
+    );
+
+void
+gckASYNC_FE_Destroy(
+    IN gckHARDWARE Hardware,
+    IN gckASYNC_FE FE
+    );
+
+/* Initialize Async FE, when hardware reset. */
+gceSTATUS
+gckASYNC_FE_Initialize(
+    IN gckHARDWARE Hardware,
+    IN gckASYNC_FE FE
+    );
+
+/* Add a NOP command in the command queue. */
+gceSTATUS
+gckASYNC_FE_Nop(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN OUT gctSIZE_T * Bytes
+    );
+
+/* Add an EVENT command in the command queue. */
+gceSTATUS
+gckASYNC_FE_Event(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT8 Event,
+    IN gceKERNEL_WHERE FromWhere,
+    IN OUT gctUINT32 * Bytes
+    );
+
+/* Kickstart the command processor. */
+gceSTATUS
+gckASYNC_FE_Execute(
+    IN gckHARDWARE Hardware,
+    IN gctUINT32 Address,
+    IN gctUINT32 Bytes
+    );
+
+gceSTATUS
+gckASYNC_FE_ReserveSlot(
+    IN gckHARDWARE Hardware,
+    OUT gctBOOL * Available
+    );
+
+void
+gckASYNC_FE_UpdateAvaiable(
+    IN gckHARDWARE Hardware
+    );
+
+/******************************************************************************/
+/* MC FE commands. */
+
+/* One MCFE includes max 64 engine, each engine contains 2 channels. */
+gceSTATUS
+gckMCFE_Construct(
+    IN gckHARDWARE Hardware,
+    OUT gckMCFE * FE
+    );
+
+void
+gckMCFE_Destroy(
+    IN gckHARDWARE Hardware,
+    IN gckMCFE FE
+    );
+
+/* Initialize MC FE, when hardware reset. */
+gceSTATUS
+gckMCFE_Initialize(
+    IN gckHARDWARE Hardware,
+    IN gctBOOL MMUEnabled,
+    IN gckMCFE FE
+    );
+
+/* Add a NOP command in the command queue. */
+gceSTATUS
+gckMCFE_Nop(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN OUT gctSIZE_T * Bytes
+    );
+
+/* Add an EVENT command in the command queue. */
+gceSTATUS
+gckMCFE_Event(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT8 Event,
+    IN gceKERNEL_WHERE FromWhere,
+    IN OUT gctUINT32 * Bytes
+    );
+
+/* Add a SendSemaphore command in the command queue. */
+gceSTATUS
+gckMCFE_SendSemaphore(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 SemaId,
+    IN OUT gctUINT32 * Bytes
+    );
+
+/* Add a WaitSemaphore command in the command queue. */
+gceSTATUS
+gckMCFE_WaitSemaphore(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 SemaId,
+    IN OUT gctUINT32 * Bytes
+    );
+
+/* Kickstart the command processor. */
+gceSTATUS
+gckMCFE_Execute(
+    IN gckHARDWARE Hardware,
+    IN gctBOOL Priority,
+    IN gctUINT32 ChannelId,
+    IN gctUINT32 Address,
+    IN gctUINT32 Bytes
+    );
+
+#endif
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_mc_fe.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_mc_fe.c
new file mode 100644 (file)
index 0000000..f652204
--- /dev/null
@@ -0,0 +1,883 @@
+/****************************************************************************
+*
+*    The MIT License (MIT)
+*
+*    Copyright (c) 2014 - 2019 Vivante Corporation
+*
+*    Permission is hereby granted, free of charge, to any person obtaining a
+*    copy of this software and associated documentation files (the "Software"),
+*    to deal in the Software without restriction, including without limitation
+*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+*    and/or sell copies of the Software, and to permit persons to whom the
+*    Software is furnished to do so, subject to the following conditions:
+*
+*    The above copyright notice and this permission notice shall be included in
+*    all copies or substantial portions of the Software.
+*
+*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+*    DEALINGS IN THE SOFTWARE.
+*
+*****************************************************************************
+*
+*    The GPL License (GPL)
+*
+*    Copyright (C) 2014 - 2019 Vivante Corporation
+*
+*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+*    Note: This software is released under dual MIT and GPL licenses. A
+*    recipient may use this file under the terms of either the MIT license or
+*    GPL License. If you wish to use only one license not the other, you can
+*    indicate your decision by deleting one of the above license notices in your
+*    version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+
+#define _GC_OBJ_ZONE    gcvZONE_HARDWARE
+
+typedef struct _gcsMCFE_DESCRIPTOR
+{
+    gctUINT32       start;
+    gctUINT32       end;
+}
+gcsMCFE_DESCRIPTOR;
+
+/* 2^DepthExp = Depth. */
+#define MCFE_RINGBUF_DEPTH_EXP         9
+/* Depth. */
+#define MCFE_RINGBUF_DEPTH             (1 << MCFE_RINGBUF_DEPTH_EXP)
+/* MCFE descriptor size in bytes, fixed 8. */
+#define MCFE_COMMAND_DESC_SIZE         8
+/* FIFO size in bytes. */
+#define MCFE_RINGBUF_SIZE              (MCFE_RINGBUF_DEPTH * MCFE_COMMAND_DESC_SIZE)
+
+typedef struct _gcsMCFE_RING_BUF
+{
+    gckVIDMEM_NODE  ringBufVideoMem;
+    gctUINT32       ringBufAddress;
+    gctUINT32 *     ringBufLogical;
+    gctSIZE_T       ringBufBytes;
+
+    gctUINT32       gpuAddress;
+    gctPHYS_ADDR_T  physical;
+
+    /* Read ptr should be often out-of-date. */
+    gctUINT32       readPtr;
+    gctUINT32       writePtr;
+}
+gcsMCFE_RING_BUF;
+
+typedef struct _gcsMCFE_CHANNEL
+{
+    gceMCFE_CHANNEL_TYPE binding;
+    gcsMCFE_RING_BUF stdRingBuf;
+    gcsMCFE_RING_BUF priRingBuf;
+}
+gcsMCFE_CHANNEL;
+
+struct _gckMCFE
+{
+    gctUINT32 channelCount;
+    gctBOOL   mmuEnabled;
+
+    /*
+     * Channels must be the last field.
+     * Will allocate struct size according to channel count.
+     */
+    gcsMCFE_CHANNEL channels[1];
+};
+
+static gcmINLINE gctUINT32
+_NextPtr(
+    gctUINT32 Ptr
+    )
+{
+    return (Ptr + 1) & (MCFE_RINGBUF_DEPTH - 1);
+}
+
+static gceSTATUS
+_AllocateDescRingBuf(
+    gckHARDWARE Hardware,
+    gcsMCFE_RING_BUF * Channel
+    )
+{
+    gceSTATUS status;
+    gcePOOL pool = gcvPOOL_DEFAULT;
+    gckKERNEL kernel = Hardware->kernel;
+    gctUINT32 allocFlag = 0;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+    allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
+    Channel->ringBufBytes = MCFE_RINGBUF_SIZE;
+
+    /* Allocate video memory node for mcfe ring buffer. */
+    gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+        kernel,
+        64,
+        gcvVIDMEM_TYPE_COMMAND,
+        allocFlag,
+        &Channel->ringBufBytes,
+        &pool,
+        &Channel->ringBufVideoMem
+        ));
+
+    /* Lock for GPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_Lock(
+        kernel,
+        Channel->ringBufVideoMem,
+        &Channel->gpuAddress
+        ));
+
+    /* Lock for kernel side CPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+        kernel,
+        Channel->ringBufVideoMem,
+        gcvFALSE,
+        gcvFALSE,
+        (gctPOINTER *)&Channel->ringBufLogical
+        ));
+
+    /* Get CPU physical address. */
+    gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+        kernel,
+        Channel->ringBufVideoMem,
+        0,
+        &Channel->physical
+        ));
+
+    gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+        Hardware->os, Channel->physical, &Channel->physical));
+
+    if (Channel->physical > 0xffffffffull)
+    {
+        gcmkPRINT("%s(%d): MCFE ring buffer physical over 4G: 0x%llx",
+            __FUNCTION__, __LINE__, (unsigned long long)Channel->physical);
+    }
+
+    /* Default to use physical. */
+    Channel->ringBufAddress = (gctUINT32)Channel->physical;
+
+    return gcvSTATUS_OK;
+
+OnError:
+    return status;
+}
+
+static void
+_DestroyDescRingBuf(
+    gckHARDWARE Hardware,
+    gcsMCFE_RING_BUF * Channel
+    )
+{
+    gckKERNEL kernel = Hardware->kernel;
+
+    if (Channel->ringBufVideoMem)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+            kernel,
+            Channel->ringBufVideoMem,
+            0,
+            gcvFALSE
+            ));
+
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+            kernel,
+            Channel->ringBufVideoMem
+            ));
+
+        Channel->ringBufVideoMem = gcvNULL;
+        Channel->ringBufLogical  = gcvNULL;
+    }
+}
+
+static gcmINLINE void
+_DestroyMCFE(
+    IN gckHARDWARE Hardware,
+    IN gckMCFE FE
+    )
+{
+    if (FE)
+    {
+        gctUINT i;
+
+        for (i = 0; i < FE->channelCount; i++)
+        {
+            if (FE->channels[i].binding)
+            {
+                _DestroyDescRingBuf(Hardware, &FE->channels[i].stdRingBuf);
+                _DestroyDescRingBuf(Hardware, &FE->channels[i].priRingBuf);
+            }
+        }
+
+        gcmkOS_SAFE_FREE(Hardware->os, FE);
+    }
+}
+
+
+static gceSTATUS
+_ConstructChannel(
+    IN gckHARDWARE Hardware,
+    IN gceMCFE_CHANNEL_TYPE ChannelType,
+    IN gcsMCFE_CHANNEL * Channel
+    )
+{
+    Channel->binding = ChannelType;
+
+    return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckMCFE_Construct(
+    IN gckHARDWARE Hardware,
+    OUT gckMCFE *FE
+    )
+{
+    gceSTATUS status;
+    gckMCFE fe = gcvNULL;
+    gctUINT32 i;
+    gctSIZE_T size = sizeof(struct _gckMCFE);
+
+    if (Hardware->mcfeChannelCount > 1)
+    {
+        size += sizeof(gcsMCFE_CHANNEL) * (Hardware->mcfeChannelCount - 1);
+    }
+
+    gcmkONERROR(gckOS_Allocate(Hardware->os,
+                               size,
+                               (gctPOINTER *)&fe));
+
+    gckOS_ZeroMemory(fe, size);
+
+    fe->channelCount = Hardware->mcfeChannelCount;
+
+    for (i = 0; i < fe->channelCount; i++)
+    {
+        gcmkONERROR(
+            _ConstructChannel(Hardware,
+                              Hardware->mcfeChannels[i],
+                              &fe->channels[i]));
+    }
+
+    /* Enable all events. */
+    gcmkONERROR(
+        gckOS_WriteRegisterEx(Hardware->os,
+                              Hardware->core,
+                              0x00014,
+                              0xFFFFFFFF));
+
+    *FE = fe;
+    return gcvSTATUS_OK;
+
+OnError:
+    _DestroyMCFE(Hardware, fe);
+    return status;
+}
+
+void
+gckMCFE_Destroy(
+    IN gckHARDWARE Hardware,
+    IN gckMCFE FE
+    )
+{
+    _DestroyMCFE(Hardware, FE);
+}
+
+static gceSTATUS
+_ProgramDescRingBuf(
+    IN gckHARDWARE Hardware,
+    IN gctBOOL MMUEnabled,
+    IN gcsMCFE_RING_BUF * Channel,
+    IN gctUINT32 Index,
+    IN gctBOOL Priority
+    )
+{
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+    gctUINT32 ringBufStartReg;
+    gctUINT32 depthExpReg;
+    gctUINT32 readPtrReg;
+    gctUINT32 writePtrReg;
+    gctUINT32 data = 0;
+
+    if (Priority)
+    {
+        ringBufStartReg = GCREG_MCFE_PRI_DESC_RING_BUF_START_ADDR_Address;
+        depthExpReg     = GCREG_MCFE_PRI_DESC_FIFO_DEPTH_EXP_Address;
+        readPtrReg      = GCREG_MCFE_PRI_DESC_FIFO_RD_PTR_Address;
+        writePtrReg     = GCREG_MCFE_PRI_DESC_FIFO_WR_PTR_Address;
+    }
+    else
+    {
+        ringBufStartReg = GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address;
+        depthExpReg     = GCREG_MCFE_STD_DESC_FIFO_DEPTH_EXP_Address;
+        readPtrReg      = GCREG_MCFE_STD_DESC_FIFO_RD_PTR_Address;
+        writePtrReg     = GCREG_MCFE_STD_DESC_FIFO_WR_PTR_Address;
+    }
+
+    ringBufStartReg += Index << 2;
+    depthExpReg     += Index << 2;
+    readPtrReg      += Index << 2;
+    writePtrReg     += Index << 2;
+
+    Channel->ringBufAddress = MMUEnabled ? Channel->gpuAddress
+                            : (gctUINT32)Channel->physical;
+
+    /* Channel ringBuf start address. */
+    gcmkVERIFY_OK(gckOS_WriteRegisterEx(
+        Hardware->os, Hardware->core, ringBufStartReg, Channel->ringBufAddress));
+
+    /* Channel ringBuf depth (exponent of 2). */
+    gcmkVERIFY_OK(gckOS_WriteRegisterEx(
+        Hardware->os, Hardware->core, depthExpReg, MCFE_RINGBUF_DEPTH_EXP));
+
+    /* The RD ptr could keep unchanged, read and compute WR ptr. */
+    gcmkVERIFY_OK(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, readPtrReg, &data));
+
+    /* Priority ring buffer write ptr. */
+    /* gcmkVERIFY_OK(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, writePtrReg, data)); */
+
+    /* No valid descriptor initially. */
+    Channel->readPtr = Channel->writePtr = data;
+
+    return gcvSTATUS_OK;
+#else
+    return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+static gceSTATUS
+_InitializeChannel(
+    IN gckHARDWARE Hardware,
+    IN gctBOOL MMUEnabled,
+    IN gcsMCFE_CHANNEL * Channel,
+    IN gctUINT32 Index
+    )
+{
+    gceSTATUS status;
+
+    /* Allocate ring buffer descriptor memory. */
+    if (!Channel->stdRingBuf.ringBufVideoMem)
+    {
+        gcmkONERROR(_AllocateDescRingBuf(Hardware, &Channel->stdRingBuf));
+    }
+
+    /* No priority channel in system engine. */
+    if (!Channel->priRingBuf.ringBufVideoMem && Index != 0)
+    {
+        gcmkONERROR(_AllocateDescRingBuf(Hardware, &Channel->priRingBuf));
+    }
+
+    gcmkONERROR(_ProgramDescRingBuf(Hardware, MMUEnabled, &Channel->stdRingBuf, Index, gcvFALSE));
+
+    /* No priority channel in system engine. */
+    if (Channel->binding != gcvMCFE_CHANNEL_SYSTEM)
+    {
+        gcmkONERROR(_ProgramDescRingBuf(Hardware, MMUEnabled, &Channel->priRingBuf, Index, gcvTRUE));
+    }
+
+    return gcvSTATUS_OK;
+
+OnError:
+    /* It's OK to leave ringBuf memory not free'd here. */
+    return status;
+}
+
+gceSTATUS
+gckMCFE_Initialize(
+    IN gckHARDWARE Hardware,
+    IN gctBOOL MMUEnabled,
+    IN gckMCFE FE
+    )
+{
+    gctUINT32 i;
+    gceSTATUS status;
+
+    for (i = 0; i < FE->channelCount; i++)
+    {
+        if (FE->channels[i].binding)
+        {
+            gcmkONERROR(_InitializeChannel(Hardware, MMUEnabled, &FE->channels[i], i));
+        }
+    }
+
+    FE->mmuEnabled = MMUEnabled;
+    return gcvSTATUS_OK;
+
+OnError:
+    return status;
+}
+
+gceSTATUS
+gckMCFE_Nop(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN OUT gctSIZE_T * Bytes
+    )
+{
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+    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 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+        logical[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+
+        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;
+#else
+    return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+
+gceSTATUS
+gckMCFE_Event(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT8 Event,
+    IN gceKERNEL_WHERE FromWhere,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+    gctUINT size;
+    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);
+
+    /* Ignored. */
+    (void)FromWhere;
+
+    size = 8;
+
+    if (Logical != gcvNULL)
+    {
+        if (*Bytes < size)
+        {
+            /* Command queue too small. */
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+        }
+
+        /* Append EVENT(Event). */
+        logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_INTERRUPT_EVENT & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)))
+                   | Event;
+
+        logical[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+        {
+            gctPHYS_ADDR_T phys;
+            gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
+            gckOS_CPUPhysicalToGPUPhysical(Hardware->os, phys, &phys);
+            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+                           "0x%08x: EVENT %d", phys, Event);
+        }
+#endif
+
+#if gcdINTERRUPT_STATISTIC
+        if (Event < gcmCOUNTOF(Hardware->kernel->eventObj->queues))
+        {
+            gckOS_AtomSetMask(Hardware->pendingEvent, 1 << Event);
+        }
+#endif
+    }
+
+    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;
+#else
+    return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+gceSTATUS
+gckMCFE_SendSemaphore(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 SemaId,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+    gceSTATUS status;
+
+    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x SemaId=%u *Bytes=%lu",
+                   Hardware, Logical, SemaId, gcmOPT_VALUE(Bytes));
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+    gcmkVERIFY_ARGUMENT(SemaId < 0xFFFF);
+
+    if (Logical != gcvNULL)
+    {
+        if (*Bytes < 8)
+        {
+            /* Command queue too small. */
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+        }
+
+        /* Append SEND_SEMAPHORE(SemaId). */
+        logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_SEND_SEMAPHORE & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)))
+                   | SemaId;
+
+        logical[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+    }
+
+    if (Bytes != gcvNULL)
+    {
+        *Bytes = 8;
+    }
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+#else
+    return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+gceSTATUS
+gckMCFE_WaitSemaphore(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 SemaId,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+    gceSTATUS status;
+
+    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x SemaId=%u *Bytes=%lu",
+                   Hardware, Logical, SemaId, gcmOPT_VALUE(Bytes));
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+    gcmkVERIFY_ARGUMENT(SemaId < 0xFFFF);
+
+    if (Logical != gcvNULL)
+    {
+        if (*Bytes < 8)
+        {
+            /* Command queue too small. */
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+        }
+
+        /* Append WAIT_SEMAPHORE(SemaId). */
+        logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_SUB_COMMAND & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)))
+                   | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_SUB_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_SUB_OPCODE_WAIT_SEMAPHORE & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_SUB_OPCODE) - (0 ?
+ MCFE_COMMAND_SUB_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_SUB_OPCODE)))
+                   | SemaId;
+
+        logical[1] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ?
+ MCFE_COMMAND_OPCODE))) | (((gctUINT32) (MCFE_COMMAND_OPCODE_NOP & ((gctUINT32) ((((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ MCFE_COMMAND_OPCODE) - (0 ?
+ MCFE_COMMAND_OPCODE) + 1))))))) << (0 ? MCFE_COMMAND_OPCODE)));
+    }
+
+    if (Bytes != gcvNULL)
+    {
+        *Bytes = 8;
+    }
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+#else
+    return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+gceSTATUS
+gckMCFE_Execute(
+    IN gckHARDWARE Hardware,
+    IN gctBOOL Priority,
+    IN gctUINT32 ChannelId,
+    IN gctUINT32 Address,
+    IN gctUINT32 Bytes
+    )
+{
+#ifdef GCREG_MCFE_STD_DESC_RING_BUF_START_ADDR_Address
+    gctUINT32 regBase;
+    gcsMCFE_DESCRIPTOR *desc;
+    gcsMCFE_CHANNEL * channel  = &Hardware->mcFE->channels[ChannelId];
+    gcsMCFE_RING_BUF * ringBuf = Priority ? &channel->priRingBuf
+                              : &channel->stdRingBuf;
+
+    /* No priority channel in system channel by design. */
+    gcmkASSERT(!(channel->binding == gcvMCFE_CHANNEL_SYSTEM && Priority == 1));
+
+    while (_NextPtr(ringBuf->writePtr) == ringBuf->readPtr)
+    {
+        gctUINT32 data;
+        regBase = Priority ? GCREG_MCFE_PRI_DESC_FIFO_RD_PTR_Address
+                : GCREG_MCFE_STD_DESC_FIFO_RD_PTR_Address;
+
+        gcmkVERIFY_OK(gckOS_ReadRegisterEx(Hardware->os,
+                                           Hardware->core,
+                                           regBase + ChannelId * 4,
+                                           &data));
+
+        ringBuf->readPtr = data;
+
+        if (_NextPtr(ringBuf->writePtr) == ringBuf->readPtr)
+        {
+            gcmkPRINT("%s: MCFE channel %s-%d ringBuf is full!",
+                      __FUNCTION__,
+                      Priority ? "Pri" : "Std",
+                      ChannelId);
+
+            gckOS_Delay(Hardware->os, 100);
+        }
+    }
+
+    regBase = Priority ? GCREG_MCFE_PRI_DESC_FIFO_WR_PTR_Address
+            : GCREG_MCFE_STD_DESC_FIFO_WR_PTR_Address;
+
+    /* ringBufLogical is in uint32, 2 uint32 contributes 1 descriptr. */
+    desc = (gcsMCFE_DESCRIPTOR *)&ringBuf->ringBufLogical[ringBuf->writePtr * 2];
+    desc->start = Address;
+    desc->end   = Address + Bytes;
+
+    gcmkDUMP(Hardware->os,
+             "#[descriptor %d: channel %s-%d]",
+             ringBuf->writePtr,
+             Priority ? "Pri" : "Std",
+             ChannelId);
+
+    gcmkDUMP_BUFFER(Hardware->os,
+                    gcvDUMP_BUFFER_KERNEL_COMMAND,
+                    desc,
+                    ringBuf->ringBufAddress + ringBuf->writePtr * 8,
+                    8);
+
+    gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(Hardware->kernel,
+                                            ringBuf->ringBufVideoMem,
+                                            0,
+                                            desc,
+                                            8));
+
+    ringBuf->writePtr = _NextPtr(ringBuf->writePtr);
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+                   "0x%08X - 0x%08X: %06d bytes, Channel=%s-%d",
+                   desc->start, desc->end, Bytes,
+                   Priority ? "Pri" : "Std", ChannelId);
+
+    gcmkVERIFY_OK(gckOS_WriteRegisterEx(Hardware->os,
+                                        Hardware->core,
+                                        regBase + ChannelId * 4,
+                                        ringBuf->writePtr));
+
+    return gcvSTATUS_OK;
+#else
+    return gcvSTATUS_NOT_SUPPORTED;
+#endif
+}
+
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_waitlink_fe.c b/drivers/mxc/gpu-viv/hal/kernel/arch/gc_hal_kernel_hardware_waitlink_fe.c
new file mode 100644 (file)
index 0000000..87f5f35
--- /dev/null
@@ -0,0 +1,1753 @@
+/****************************************************************************
+*
+*    The MIT License (MIT)
+*
+*    Copyright (c) 2014 - 2019 Vivante Corporation
+*
+*    Permission is hereby granted, free of charge, to any person obtaining a
+*    copy of this software and associated documentation files (the "Software"),
+*    to deal in the Software without restriction, including without limitation
+*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+*    and/or sell copies of the Software, and to permit persons to whom the
+*    Software is furnished to do so, subject to the following conditions:
+*
+*    The above copyright notice and this permission notice shall be included in
+*    all copies or substantial portions of the Software.
+*
+*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+*    DEALINGS IN THE SOFTWARE.
+*
+*****************************************************************************
+*
+*    The GPL License (GPL)
+*
+*    Copyright (C) 2014 - 2019 Vivante Corporation
+*
+*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+*    Note: This software is released under dual MIT and GPL licenses. A
+*    recipient may use this file under the terms of either the MIT license or
+*    GPL License. If you wish to use only one license not the other, you can
+*    indicate your decision by deleting one of the above license notices in your
+*    version of this file.
+*
+*****************************************************************************/
+
+
+#include "gc_hal.h"
+#include "gc_hal_kernel.h"
+#include "gc_hal_kernel_context.h"
+
+#define _GC_OBJ_ZONE    gcvZONE_HARDWARE
+
+gceSTATUS
+gckWLFE_Construct(
+    IN gckHARDWARE Hardware,
+    OUT gckWLFE * FE
+    )
+{
+    /* Just a non-null value. */
+    *FE = (gckWLFE)(gctUINTPTR_T)1;
+    return gcvSTATUS_OK;
+}
+
+void
+gckWLFE_Destroy(
+    IN gckHARDWARE Hardware,
+    IN gckWLFE FE
+    )
+{
+    gcmkASSERT(FE);
+}
+
+gceSTATUS
+gckWLFE_Initialize(
+    IN gckHARDWARE Hardware,
+    IN gckWLFE FE
+    )
+{
+    gcmkASSERT(FE);
+    return gcvSTATUS_OK;
+}
+
+/*******************************************************************************
+**
+**  gckWLFE_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 Address
+**          GPU address of current location inside the command queue.
+**
+**      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
+gckWLFE_WaitLink(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Address,
+    IN gctUINT32 Offset,
+    IN OUT gctUINT32 * Bytes,
+    OUT gctUINT32 * WaitOffset,
+    OUT gctUINT32 * WaitSize
+    )
+{
+    gceSTATUS status;
+    gctUINT32_PTR logical;
+    gctUINT32 bytes;
+    gctBOOL useL2;
+
+    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));
+
+    gcmkASSERT(Hardware->wlFE);
+    useL2 = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_64K_L2_CACHE);
+
+    /* Compute number of bytes required. */
+    if (useL2)
+    {
+        bytes = gcmALIGN(Offset + 24, 8) - Offset;
+    }
+    else
+    {
+        bytes = gcmALIGN(Offset + 16, 8) - Offset;
+    }
+
+    /* 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);
+        }
+
+        gcmkASSERT(Address != ~0U);
+
+        /* Store the WAIT/LINK address. */
+        Hardware->lastWaitLink = Address;
+
+        /* Append WAIT(count). */
+        *logical++
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (Hardware->waitCount) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+        logical++;
+
+        if (useL2)
+        {
+            /* LoadState(AQFlush, 1), flush. */
+            *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+            *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+        }
+
+        /* Append LINK(2, address). */
+        *logical++
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+        *logical++ = Address;
+
+        gcmkTRACE_ZONE(
+            gcvLEVEL_INFO, gcvZONE_HARDWARE,
+            "0x%08x: WAIT %u", Address, Hardware->waitCount
+            );
+
+        gcmkTRACE_ZONE(
+            gcvLEVEL_INFO, gcvZONE_HARDWARE,
+            "0x%08x: LINK 0x%08x, #%lu",
+            Address + 8, Address, bytes
+            );
+
+        if (WaitOffset != gcvNULL)
+        {
+            /* Return the offset pointer to WAIT command. */
+            *WaitOffset = 0;
+        }
+
+        if (WaitSize != gcvNULL)
+        {
+            /* Return number of bytes used by the WAIT command. */
+            if (useL2)
+            {
+                *WaitSize = 16;
+            }
+            else
+            {
+                *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;
+}
+
+gceSTATUS
+gckWLFE_InvalidatePipe(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Address,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+    gctUINT size;
+    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+    gceSTATUS status;
+    gctBOOL blt = gcvFALSE;
+    gctBOOL multiCluster = gcvFALSE;
+
+    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));
+
+    gcmkASSERT(Hardware->wlFE);
+
+    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE))
+    {
+        /* Send all event from blt. */
+        blt = gcvTRUE;
+        multiCluster = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MULTI_CLUSTER);
+    }
+
+    /* Determine the size of the command. */
+    size = Hardware->extraEventStates
+         ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
+         : 8;
+
+    if (blt)
+    {
+        size += 16;
+        if (multiCluster)
+            size += 8;
+    }
+
+    /* END. */
+    size += 8;
+
+    if (Logical != gcvNULL)
+    {
+        if (*Bytes < size)
+        {
+            /* Command queue too small. */
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+        }
+
+        if (blt)
+        {
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+            if (multiCluster)
+            {
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x50CE) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.clusterAvailMask & Hardware->options.userClusterMask) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
+            }
+        }
+
+        /* Append EVENT(Event, PE_SRC). */
+        *logical++
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+        *logical++
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (EVENT_ID_INVALIDATE_PIPE) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+
+        if (blt)
+        {
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+        }
+
+#if gcmIS_DEBUG(gcdDEBUG_TRACE)
+        {
+            gctPHYS_ADDR_T phys;
+            gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
+            gckOS_CPUPhysicalToGPUPhysical(Hardware->os, phys, &phys);
+            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
+                           "0x%08x: EVENT %d", phys, EVENT_ID_INVALIDATE_PIPE);
+        }
+#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 (Hardware->extraEventStates)
+        {
+            *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0100) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+        }
+
+#if gcdINTERRUPT_STATISTIC
+        if (EVENT_ID_INVALIDATE_PIPE < gcmCOUNTOF(Hardware->kernel->eventObj->queues))
+        {
+            gckOS_AtomSetMask(Hardware->pendingEvent, 1 << EVENT_ID_INVALIDATE_PIPE);
+        }
+#endif
+
+        /* Append END. */
+        *logical++ =
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+        /* Record the count of execution which is finised by this END. */
+        *logical++ =
+            Hardware->executeCount;
+
+        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));
+
+        Hardware->lastEnd = Address + size - 8;
+    }
+
+    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;
+}
+
+void
+gckWLFE_DoneInvalidatePipe(
+    gckHARDWARE Hardware
+    )
+{
+    gctUINT32 resume;
+    gctUINT32 bytes;
+    gctUINT32 idle;
+    gctUINT32 pageSize = Hardware->kernel->command->pageSize;
+
+    gcmkASSERT(Hardware->wlFE);
+
+    /* Make sure FE is idle. */
+    do
+    {
+        gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+            Hardware->os,
+            Hardware->core,
+            0x00004,
+            &idle));
+    }
+    while (idle != 0x7FFFFFFF);
+
+    gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+            Hardware->os,
+            Hardware->core,
+            0x00664,
+            &resume));
+
+    gcmkVERIFY_OK(gckOS_ReadRegisterEx(
+            Hardware->os,
+            Hardware->core,
+            0x00664,
+            &resume));
+
+    gcmkVERIFY_OK(gckWLFE_WaitLink(
+            Hardware,
+            gcvNULL,
+            ~0U,
+            resume & (pageSize - 1),
+            &bytes,
+            gcvNULL,
+            gcvNULL
+            ));
+
+    /* Start Command Parser. */
+    gcmkVERIFY_OK(gckWLFE_Execute(
+        Hardware,
+        resume,
+        bytes
+        ));
+}
+
+/*******************************************************************************
+**
+**  gckWLFE_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.
+**
+**      gctUINT32 FetchAddress
+**          Hardware 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
+gckWLFE_Link(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 FetchAddress,
+    IN gctUINT32 FetchSize,
+    IN OUT gctUINT32 * Bytes,
+    OUT gctUINT32 * Low,
+    OUT gctUINT32 * High
+    )
+{
+    gceSTATUS status;
+    gctSIZE_T bytes;
+    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));
+
+    gcmkASSERT(Hardware->wlFE);
+
+    if (Logical != gcvNULL)
+    {
+        if (*Bytes < 8)
+        {
+            /* Command queue too small. */
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+        }
+
+        gcmkONERROR(
+            gckOS_WriteMemory(Hardware->os, logical + 1, FetchAddress));
+
+        if (High)
+        {
+            *High = FetchAddress;
+        }
+
+        /* 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(FetchAddress + FetchSize, 64) - FetchAddress;
+
+        /* Append LINK(bytes / 8), FetchAddress. */
+        link = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+             | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+        gcmkONERROR(
+            gckOS_WriteMemory(Hardware->os, logical, link));
+
+        if (Low)
+        {
+            *Low = link;
+        }
+
+        /* Memory barrier. */
+        gcmkONERROR(
+            gckOS_MemoryBarrier(Hardware->os, logical));
+    }
+
+    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;
+}
+
+/*******************************************************************************
+**
+**  gckWLFE_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.
+**
+**      gctUINT32 Address
+**          GPU address of current location inside the command queue.
+**
+**      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
+gckWLFE_End(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT32 Address,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+    gctUINT32 address;
+    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));
+
+    gcmkASSERT(Hardware->wlFE);
+
+    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) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));
+
+        /* Record the count of execution which is finised by this END. */
+        logical[1] =
+            Hardware->executeCount;
+
+        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));
+
+        gcmkASSERT(Address != ~0U);
+        address = Address;
+
+        Hardware->lastEnd = address;
+    }
+
+    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;
+}
+
+/*******************************************************************************
+**
+**  gckWLFE_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
+gckWLFE_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));
+
+    gcmkASSERT(Hardware->wlFE);
+
+    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) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((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;
+}
+
+/*******************************************************************************
+**
+**  gckWLFE_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
+gckWLFE_Event(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gctUINT8 Event,
+    IN gceKERNEL_WHERE FromWhere,
+    IN OUT gctUINT32 * Bytes
+    )
+{
+    gctUINT size;
+    gctUINT32 destination = 0;
+    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+    gceSTATUS status;
+    gctBOOL blt;
+    gctBOOL extraEventStates;
+    gctBOOL multiCluster;
+
+    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);
+
+    gcmkASSERT(Hardware->wlFE);
+
+    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_BLT_ENGINE))
+    {
+        /* Send all event from blt. */
+        if (FromWhere == gcvKERNEL_PIXEL)
+        {
+            FromWhere = gcvKERNEL_BLT;
+        }
+    }
+
+    blt = FromWhere == gcvKERNEL_BLT ? gcvTRUE : gcvFALSE;
+
+    multiCluster = gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_MULTI_CLUSTER);
+
+    /* Determine the size of the command. */
+
+    extraEventStates = Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL);
+
+    size = extraEventStates
+         ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */
+         : 8;
+
+    if (blt)
+    {
+        size += 16;
+        if (multiCluster)
+            size += 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) ?
+ ~0U : (~(~0U << ((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1))))))) << (0 ?
+ 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 5:5) - (0 ?
+ 5:5) + 1) == 32) ?
+ ~0U : (~(~0U << ((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) ?
+ ~0U : (~(~0U << ((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1))))))) << (0 ?
+ 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 6:6) - (0 ?
+ 6:6) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6)));
+            break;
+
+        case gcvKERNEL_BLT:
+            destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1))))))) << (0 ?
+ 7:7))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 7:7) - (0 ?
+ 7:7) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7)));
+            break;
+
+        default:
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+        }
+
+        if (blt)
+        {
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));
+
+            if (multiCluster)
+            {
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                    | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x50CE) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+                *logical++
+                    = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1))))))) << (0 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) (Hardware->identity.clusterAvailMask & Hardware->options.userClusterMask) & ((gctUINT32) ((((1 ?
+ 7:0) - (0 ?
+ 7:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)));
+            }
+        }
+
+        /* Append EVENT(Event, destination). */
+        *logical++
+            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+
+        *logical++
+            = ((((gctUINT32) (destination)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1))))))) << (0 ?
+ 4:0))) | (((gctUINT32) ((gctUINT32) (Event) & ((gctUINT32) ((((1 ?
+ 4:0) - (0 ?
+ 4:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0)));
+
+        if (blt)
+        {
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
+                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x502E) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));
+
+            *logical++
+                = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1))))))) << (0 ?
+ 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
+ 0:0) - (0 ?
+ 0:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0: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)
+        {
+            gctPHYS_ADDR_T phys;
+            gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys);
+            gckOS_CPUPhysicalToGPUPhysical(Hardware->os, phys, &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 (extraEventStates)
+        {
+            *logical++ = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
+                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) (0x0100) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
+                       | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1))))))) << (0 ?
+ 25:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ?
+ 25:16) - (0 ?
+ 25:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+            *logical++ = 0;
+        }
+
+#if gcdINTERRUPT_STATISTIC
+        if (Event < gcmCOUNTOF(Hardware->kernel->eventObj->queues))
+        {
+            gckOS_AtomSetMask(Hardware->pendingEvent, 1 << Event);
+        }
+#endif
+    }
+
+    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;
+}
+
+gceSTATUS
+gckWLFE_ChipEnable(
+    IN gckHARDWARE Hardware,
+    IN gctPOINTER Logical,
+    IN gceCORE_3D_MASK ChipEnable,
+    IN OUT gctSIZE_T * Bytes
+    )
+{
+    gckOS os = Hardware->os;
+    gctUINT32_PTR logical = (gctUINT32_PTR) Logical;
+    gceSTATUS status;
+
+    gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x ChipEnable=0x%x *Bytes=%lu",
+                   Hardware, Logical, ChipEnable, gcmOPT_VALUE(Bytes));
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+    gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL));
+
+    gcmkASSERT(Hardware->wlFE);
+
+    if (Logical != gcvNULL)
+    {
+        if (*Bytes < 8)
+        {
+            /* Command queue too small. */
+            gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL);
+        }
+
+        /* Append CHIPENABLE. */
+        gcmkWRITE_MEMORY(
+            logical,
+            ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1))))))) << (0 ?
+ 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ?
+ 31:27) - (0 ?
+ 31:27) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | ChipEnable
+            );
+
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: CHIPENABLE 0x%x", Logical, ChipEnable);
+    }
+
+    if (Bytes != gcvNULL)
+    {
+        /* Return number of bytes required by the CHIPENABLE command. */
+        *Bytes = 8;
+    }
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes));
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+/*******************************************************************************
+**
+**  gckWLFE_Execute
+**
+**  Kickstart the hardware's command processor with an initialized command
+**  buffer.
+**
+**  INPUT:
+**
+**      gckHARDWARE Hardware
+**          Pointer to the gckHARDWARE object.
+**
+**      gctUINT32 Address
+**          Hardware address of command buffer.
+**
+**      gctUINT32 Bytes
+**          Number of bytes for the prefetch unit (until after the first LINK).
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gckWLFE_Execute(
+    IN gckHARDWARE Hardware,
+    IN gctUINT32 Address,
+    IN gctUINT32 Bytes
+    )
+{
+    gceSTATUS status;
+    gctUINT32 control;
+
+    gcmkHEADER_ARG("Hardware=0x%x Address=0x%x Bytes=%lu",
+                   Hardware, Address, Bytes);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
+
+    gcmkASSERT(Hardware->wlFE);
+
+    /* 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) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((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) ?
+ ~0U : (~(~0U << ((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1))))))) << (0 ?
+ 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20)));
+    }
+
+    /* Make sure writing to command buffer and previous AHB register is done. */
+    gcmkONERROR(gckOS_MemoryBarrier(Hardware->os, gcvNULL));
+
+    /* Write control register. */
+    switch (Hardware->options.secureMode)
+    {
+    case gcvSECURE_NONE:
+        gcmkONERROR(
+            gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
+        break;
+    case gcvSECURE_IN_NORMAL:
+
+#if defined(__KERNEL__)
+        gcmkONERROR(
+            gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control));
+#endif
+        gcmkONERROR(
+            gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x003A4, control));
+        break;
+#if gcdENABLE_TRUST_APPLICATION
+    case gcvSECURE_IN_TA:
+        /* Send message to TA. */
+        gcmkONERROR(gckKERNEL_SecurityStartCommand(Hardware->kernel, Address, (gctUINT32)Bytes));
+        break;
+#endif
+    default:
+        break;
+    }
+
+    /* Increase execute count. */
+    Hardware->executeCount++;
+
+    /* Record last execute address. */
+    Hardware->lastExecuteAddress = Address;
+
+    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;
+}
+
+gceSTATUS
+gckWLFE_AtomicExecute(
+    IN gckHARDWARE Hardware,
+    IN gctUINT32 Address,
+    IN gctUINT32 Bytes
+    )
+{
+    gctUINT32 control;
+
+    /* Enable all events. */
+    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U);
+
+    /* Write address register. */
+    gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, Address);
+
+    /* Build control register. */
+    control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1))))))) << (0 ?
+ 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
+ 16:16) - (0 ?
+ 16:16) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
+            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1))))))) << (0 ?
+ 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ?
+ 15:0) - (0 ?
+ 15:0) + 1) == 32) ?
+ ~0U : (~(~0U << ((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) ?
+ ~0U : (~(~0U << ((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1))))))) << (0 ?
+ 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ?
+ 21:20) - (0 ?
+ 21:20) + 1) == 32) ?
+ ~0U : (~(~0U << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20)));
+    }
+
+    /* Make sure writing to command buffer and previous AHB register is done. */
+    gckOS_MemoryBarrier(Hardware->os, gcvNULL);
+
+    /* Write control register. */
+    switch (Hardware->options.secureMode)
+    {
+    case gcvSECURE_NONE:
+        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control);
+        break;
+    case gcvSECURE_IN_NORMAL:
+
+#if defined(__KERNEL__)
+        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control);
+#endif
+        gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x003A4, control);
+        break;
+#if gcdENABLE_TRUST_APPLICATION
+    case gcvSECURE_IN_TA:
+        /* Send message to TA. */
+        gckKERNEL_SecurityStartCommand(Hardware->kernel, Address, (gctUINT32)Bytes);
+        break;
+#endif
+    default:
+        break;
+    }
+
+    /* Increase execute count. */
+    Hardware->executeCount++;
+
+    /* Record last execute address. */
+    Hardware->lastExecuteAddress = Address;
+
+    /* Success. */
+    return gcvSTATUS_OK;
+}
+
+
index b6c2ce0..0cdfe23 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -486,16 +486,9 @@ gckRECORDER_Construct(
     gckRECORDER recorder = gcvNULL;
     gctSIZE_T mapSize;
     gctUINT i;
-    gctBOOL virtualCommandBuffer = Hardware->kernel->virtualCommandBuffer;
-
-    /* MMU is not ready now. */
-    Hardware->kernel->virtualCommandBuffer = gcvFALSE;
 
     gcmkONERROR(gckCONTEXT_Construct(Os, Hardware, 0, &context));
 
-    /* Restore. */
-    Hardware->kernel->virtualCommandBuffer = virtualCommandBuffer;
-
     gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsRECORDER), (gctPOINTER *)&recorder));
 
     gckOS_ZeroMemory(recorder, gcmSIZEOF(gcsRECORDER));
@@ -708,18 +701,18 @@ gckRECORDER_Dump(
             previous = _Previous(last);
 
             gcmkPRINT("#[mirror]");
-            gckOS_DumpBuffer(os, mirror->logical[previous], mirror->bytes, gcvDUMP_BUFFER_CONTEXT, gcvTRUE);
-            gcmkPRINT("@[kernel.execute]");
+            gckOS_DumpBuffer(os, gcvDUMP_BUFFER_KERNEL_CONTEXT, mirror->logical[previous], ~0U, mirror->bytes);
+            gcmkPRINT("#[kernel.execute]");
         }
 
         if (delta->contextBytes)
         {
-            gckOS_DumpBuffer(os, delta->context, delta->contextBytes, gcvDUMP_BUFFER_CONTEXT, gcvTRUE);
-            gcmkPRINT("@[kernel.execute]");
+            gckOS_DumpBuffer(os, gcvDUMP_BUFFER_KERNEL_CONTEXT, delta->context, ~0U, delta->contextBytes);
+            gcmkPRINT("#[kernel.execute]");
         }
 
-        gckOS_DumpBuffer(os, delta->command, delta->commandBytes, gcvDUMP_BUFFER_USER, gcvTRUE);
-        gcmkPRINT("@[kernel.execute]");
+        gckOS_DumpBuffer(os, gcvDUMP_BUFFER_KERNEL_COMMAND, delta->command, ~0U, delta->commandBytes);
+        gcmkPRINT("#[kernel.execute]");
 
         last = _Next(last);
     }
index f510b30..bb800a6 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -566,7 +566,7 @@ gckVGCOMMAND_FetchCommand(
  ~0U : (~(~0U << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0)))
                 );
 
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[1],
                 gcmkFIXADDRESS(FetchAddress)
@@ -589,7 +589,7 @@ gckVGCOMMAND_FetchCommand(
             buffer = (gctUINT32_PTR) Logical;
 
             /* Append LINK. */
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[0],
                   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -614,7 +614,7 @@ gckVGCOMMAND_FetchCommand(
  ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
                 );
 
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[1],
                 gcmkFIXADDRESS(FetchAddress)
@@ -691,7 +691,7 @@ gckVGCOMMAND_CallCommand(
             buffer = (gctUINT32_PTR) Logical;
 
             /* Append CALL. */
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[0],
                   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -716,7 +716,7 @@ gckVGCOMMAND_CallCommand(
  ~0U : (~(~0U << ((1 ? 20:0) - (0 ? 20:0) + 1))))))) << (0 ? 20:0)))
                 );
 
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[1],
                 gcmkFIXADDRESS(FetchAddress)
@@ -787,7 +787,7 @@ gckVGCOMMAND_ReturnCommand(
             buffer = (gctUINT32_PTR) Logical;
 
             /* Append RETURN. */
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[0],
                 ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -960,7 +960,7 @@ gckVGCOMMAND_EventCommand(
             buffer = (gctUINT32_PTR) Logical;
 
             /* Append EVENT. */
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[0],
                   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -1114,7 +1114,7 @@ gckVGCOMMAND_EventCommand(
             buffer = (gctUINT32_PTR) Logical;
 
             /* Append EVENT. */
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[0],
                   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -1152,7 +1152,7 @@ gckVGCOMMAND_EventCommand(
             /* Determine event source. */
             if (Block == gcvBLOCK_COMMAND)
             {
-                gckOS_WriteMemory(
+               gckOS_WriteMemory(
                     Command->os,
                     &buffer[1],
                       ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -1179,7 +1179,7 @@ gckVGCOMMAND_EventCommand(
             }
             else
             {
-                gckOS_WriteMemory(
+               gckOS_WriteMemory(
                     Command->os,
                     &buffer[1],
                       ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -1273,7 +1273,7 @@ gckVGCOMMAND_EndCommand(
             buffer = (gctUINT32_PTR) Logical;
 
             /* Append END. */
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &buffer[0],
                   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -1318,7 +1318,7 @@ gckVGCOMMAND_EndCommand(
             memory = (gctUINT32_PTR) Logical;
 
             /* Append EVENT. */
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &memory[0],
                   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -1353,7 +1353,7 @@ gckVGCOMMAND_EndCommand(
  ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)))
                 );
 
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &memory[1],
                   ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
@@ -1379,7 +1379,7 @@ gckVGCOMMAND_EndCommand(
                 );
 
             /* Append END. */
-            gckOS_WriteMemory(
+           gckOS_WriteMemory(
                 Command->os,
                 &memory[2],
                 ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
index ab495f5..f1ef960 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 3b96bc0..07569d8 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -318,7 +318,7 @@ _VGPowerTimerFunction(
 {
     gckVGHARDWARE hardware = (gckVGHARDWARE)Data;
     gcmkVERIFY_OK(
-        gckVGHARDWARE_SetPowerManagementState(hardware, gcvPOWER_OFF_TIMEOUT));
+        gckVGHARDWARE_SetPowerState(hardware, gcvPOWER_OFF_TIMEOUT));
 }
 #endif
 
@@ -923,6 +923,9 @@ gckVGHARDWARE_ConvertFormat(
     case gcvSURF_A8L8:
     case gcvSURF_YUY2:
     case gcvSURF_UYVY:
+#if gcdVG_ONLY
+    case gcvSURF_YV16:
+#endif
     case gcvSURF_D16:
         /* 16-bpp format. */
         bitsPerPixel  = 16;
@@ -1173,74 +1176,6 @@ gckVGHARDWARE_Execute(
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckVGHARDWARE_AlignToTile
-**
-**  Align the specified width and height to tile boundaries.
-**
-**  INPUT:
-**
-**      gckVGHARDWARE Hardware
-**          Pointer to an gckVGHARDWARE object.
-**
-**      gceSURF_TYPE Type
-**          Type of alignment.
-**
-**      gctUINT32 * Width
-**          Pointer to the width to be aligned.  If 'Width' is gcvNULL, no width
-**          will be aligned.
-**
-**      gctUINT32 * Height
-**          Pointer to the height to be aligned.  If 'Height' is gcvNULL, no height
-**          will be aligned.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * Width
-**          Pointer to a variable that will receive the aligned width.
-**
-**      gctUINT32 * Height
-**          Pointer to a variable that will receive the aligned height.
-*/
-gceSTATUS
-gckVGHARDWARE_AlignToTile(
-    IN gckVGHARDWARE Hardware,
-    IN gceSURF_TYPE Type,
-    IN OUT gctUINT32 * Width,
-    IN OUT gctUINT32 * Height
-    )
-{
-    gcmkHEADER_ARG("Hardware=0x%x Type=0x%x Width=0x%x Height=0x%x",
-                   Hardware, Type, Width, Height);
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
-
-    if (Width != gcvNULL)
-    {
-        /* Align the width. */
-        *Width = gcmALIGN(*Width, (Type == gcvSURF_TEXTURE) ? 4 : 16);
-    }
-
-    if (Height != gcvNULL)
-    {
-        /* Special case for VG images. */
-        if ((*Height == 0) && (Type == gcvSURF_IMAGE))
-        {
-            *Height = 4;
-        }
-        else
-        {
-            /* Align the height. */
-            *Height = gcmALIGN(*Height, 4);
-        }
-    }
-
-    gcmkFOOTER_NO();
-    /* Success. */
-    return gcvSTATUS_OK;
-}
-
 /*******************************************************************************
 **
 **  gckVGHARDWARE_ConvertLogical
@@ -1813,7 +1748,7 @@ static gceSTATUS _CommandStall(
 
 /*******************************************************************************
 **
-**  gckHARDWARE_SetPowerManagementState
+**  gckVGHARDWARE_SetPowerState
 **
 **  Set GPU to a specified power state.
 **
@@ -1827,7 +1762,7 @@ static gceSTATUS _CommandStall(
 **
 */
 gceSTATUS
-gckVGHARDWARE_SetPowerManagementState(
+gckVGHARDWARE_SetPowerState(
     IN gckVGHARDWARE Hardware,
     IN gceCHIPPOWERSTATE State
     )
@@ -1838,7 +1773,6 @@ gckVGHARDWARE_SetPowerManagementState(
     gctUINT flag/*, clock*/;
 
     gctBOOL acquired        = gcvFALSE;
-    gctBOOL stall           = gcvTRUE;
     gctBOOL commitMutex     = gcvFALSE;
     gctBOOL mutexAcquired   = gcvFALSE;
 
@@ -1862,42 +1796,28 @@ gckVGHARDWARE_SetPowerManagementState(
     {
         /* 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_NOP,
             /* 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_RELEASE    |
-                                    gcvPOWER_FLAG_DELAY,
-            /* SUSPEND           */ gcvPOWER_FLAG_INITIALIZE |
+            /* OFF               */ gcvPOWER_FLAG_ACQUIRE   |
+                                    gcvPOWER_FLAG_STALL     |
+                                    gcvPOWER_FLAG_STOP      |
+                                    gcvPOWER_FLAG_POWER_OFF |
                                     gcvPOWER_FLAG_CLOCK_OFF,
         },
 
         /* gcvPOWER_IDLE         */
         {   /* ON                */ gcvPOWER_FLAG_NOP,
-            /* OFF               */ gcvPOWER_FLAG_ACQUIRE   |
-                                    gcvPOWER_FLAG_STOP      |
-                                    gcvPOWER_FLAG_POWER_OFF |
-                                    gcvPOWER_FLAG_CLOCK_OFF,
             /* IDLE              */ 0,
             /* SUSPEND           */ gcvPOWER_FLAG_ACQUIRE   |
                                     gcvPOWER_FLAG_STOP      |
                                     gcvPOWER_FLAG_CLOCK_OFF,
+            /* OFF               */ gcvPOWER_FLAG_ACQUIRE   |
+                                    gcvPOWER_FLAG_STOP      |
+                                    gcvPOWER_FLAG_POWER_OFF |
+                                    gcvPOWER_FLAG_CLOCK_OFF,
         },
 
         /* gcvPOWER_SUSPEND      */
@@ -1905,14 +1825,28 @@ gckVGHARDWARE_SetPowerManagementState(
                                     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_RELEASE   |
                                     gcvPOWER_FLAG_CLOCK_ON,
             /* SUSPEND           */ 0,
+            /* OFF               */ gcvPOWER_FLAG_SAVE      |
+                                    gcvPOWER_FLAG_POWER_OFF |
+                                    gcvPOWER_FLAG_CLOCK_OFF,
+        },
+
+        /* gcvPOWER_OFF          */
+        {   /* ON                */ gcvPOWER_FLAG_INITIALIZE |
+                                    gcvPOWER_FLAG_START      |
+                                    gcvPOWER_FLAG_RELEASE    |
+                                    gcvPOWER_FLAG_DELAY,
+            /* IDLE              */ gcvPOWER_FLAG_INITIALIZE |
+                                    gcvPOWER_FLAG_START      |
+                                    gcvPOWER_FLAG_RELEASE    |
+                                    gcvPOWER_FLAG_DELAY,
+            /* SUSPEND           */ gcvPOWER_FLAG_INITIALIZE |
+                                    gcvPOWER_FLAG_CLOCK_OFF,
+            /* OFF               */ 0,
         },
     };
 
@@ -2120,7 +2054,7 @@ gckVGHARDWARE_SetPowerManagementState(
     /* Get time until powered on. */
     gcmkPROFILE_QUERY(time, onTime);
 
-    if ((flag & gcvPOWER_FLAG_STALL) && stall)
+    if (flag & gcvPOWER_FLAG_STALL)
     {
         /* Acquire the mutex. */
         gcmkONERROR(gckOS_AcquireMutex(
@@ -2294,7 +2228,7 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckHARDWARE_QueryPowerManagementState
+**  gckHARDWARE_QueryPowerState
 **
 **  Get GPU power state.
 **
@@ -2329,7 +2263,7 @@ gckVGHARDWARE_QueryPowerManagementState(
 
 /*******************************************************************************
 **
-**  gckVGHARDWARE_SetPowerManagement
+**  gckVGHARDWARE_EnablePowerManagement
 **
 **  Configure GPU power management function.
 **  Only used in driver initialization stage.
@@ -2339,14 +2273,14 @@ gckVGHARDWARE_QueryPowerManagementState(
 **      gckVGHARDWARE Harwdare
 **          Pointer to an gckHARDWARE object.
 **
-**      gctBOOL PowerManagement
-**          Power Mangement State.
+**      gctBOOL Enable
+**          Power Mangement Enabling State.
 **
 */
 gceSTATUS
-gckVGHARDWARE_SetPowerManagement(
+gckVGHARDWARE_EnablePowerManagement(
     IN gckVGHARDWARE Hardware,
-    IN gctBOOL PowerManagement
+    IN gctBOOL Enable
     )
 {
     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
@@ -2354,7 +2288,7 @@ gckVGHARDWARE_SetPowerManagement(
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
 
-    Hardware->options.powerManagement = PowerManagement;
+    Hardware->options.powerManagement = Enable;
 
     /* Success. */
     gcmkFOOTER_NO();
index 236c0af..04d417a 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 5260aef..71e6799 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -80,86 +80,78 @@ const char * _VERSION = "\n\0$VERSION$"
 #define gcmDEFINE2TEXT(d) #d
 gctCONST_STRING _DispatchText[] =
 {
+    gcmDEFINE2TEXT(gcvHAL_CHIP_INFO),
+    gcmDEFINE2TEXT(gcvHAL_VERSION),
+    gcmDEFINE2TEXT(gcvHAL_SET_TIMEOUT),
     gcmDEFINE2TEXT(gcvHAL_QUERY_VIDEO_MEMORY),
     gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_IDENTITY),
+    gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_OPTION),
     gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_FREQUENCY),
     gcmDEFINE2TEXT(gcvHAL_ALLOCATE_NON_PAGED_MEMORY),
     gcmDEFINE2TEXT(gcvHAL_FREE_NON_PAGED_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_FREE_CONTIGUOUS_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIDEO_MEMORY),
     gcmDEFINE2TEXT(gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_WRAP_USER_MEMORY),
     gcmDEFINE2TEXT(gcvHAL_RELEASE_VIDEO_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_MAP_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_UNMAP_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_MAP_USER_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_UNMAP_USER_MEMORY),
     gcmDEFINE2TEXT(gcvHAL_LOCK_VIDEO_MEMORY),
     gcmDEFINE2TEXT(gcvHAL_UNLOCK_VIDEO_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_EXPORT_VIDEO_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_NAME_VIDEO_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_IMPORT_VIDEO_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_MAP_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_UNMAP_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_CACHE),
+    gcmDEFINE2TEXT(gcvHAL_ATTACH),
+    gcmDEFINE2TEXT(gcvHAL_DETACH),
     gcmDEFINE2TEXT(gcvHAL_EVENT_COMMIT),
+    gcmDEFINE2TEXT(gcvHAL_COMMIT),
+    gcmDEFINE2TEXT(gcvHAL_COMMIT_DONE),
     gcmDEFINE2TEXT(gcvHAL_USER_SIGNAL),
     gcmDEFINE2TEXT(gcvHAL_SIGNAL),
     gcmDEFINE2TEXT(gcvHAL_WRITE_DATA),
-    gcmDEFINE2TEXT(gcvHAL_COMMIT),
-    gcmDEFINE2TEXT(gcvHAL_STALL),
     gcmDEFINE2TEXT(gcvHAL_READ_REGISTER),
     gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER),
+    gcmDEFINE2TEXT(gcvHAL_READ_REGISTER_EX),
+    gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER_EX),
     gcmDEFINE2TEXT(gcvHAL_GET_PROFILE_SETTING),
     gcmDEFINE2TEXT(gcvHAL_SET_PROFILE_SETTING),
-    gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D),
+    gcmDEFINE2TEXT(gcvHAL_READ_PROFILER_REGISTER_SETTING),
     gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS_PART1),
     gcmDEFINE2TEXT(gcvHAL_READ_ALL_PROFILE_REGISTERS_PART2),
-    gcmDEFINE2TEXT(gcvHAL_READ_PROFILER_REGISTER_SETTING),
+    gcmDEFINE2TEXT(gcvHAL_PROFILE_REGISTERS_2D),
     gcmDEFINE2TEXT(gcvHAL_SET_POWER_MANAGEMENT_STATE),
     gcmDEFINE2TEXT(gcvHAL_QUERY_POWER_MANAGEMENT_STATE),
+    gcmDEFINE2TEXT(gcvHAL_CONFIG_POWER_MANAGEMENT),
     gcmDEFINE2TEXT(gcvHAL_GET_BASE_ADDRESS),
     gcmDEFINE2TEXT(gcvHAL_SET_IDLE),
-    gcmDEFINE2TEXT(gcvHAL_QUERY_KERNEL_SETTINGS),
     gcmDEFINE2TEXT(gcvHAL_RESET),
-    gcmDEFINE2TEXT(gcvHAL_MAP_PHYSICAL),
-    gcmDEFINE2TEXT(gcvHAL_DEBUG),
-    gcmDEFINE2TEXT(gcvHAL_CACHE),
+    gcmDEFINE2TEXT(gcvHAL_SET_DEBUG_LEVEL_ZONE),
+    gcmDEFINE2TEXT(gcvHAL_DEBUG_DUMP),
+    gcmDEFINE2TEXT(gcvHAL_UPDATE_DEBUG_CALLBACK),
+    gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_STATE),
+    gcmDEFINE2TEXT(gcvHAL_DUMP_EVENT),
+    gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_PROFILE),
     gcmDEFINE2TEXT(gcvHAL_TIMESTAMP),
     gcmDEFINE2TEXT(gcvHAL_DATABASE),
-    gcmDEFINE2TEXT(gcvHAL_VERSION),
-    gcmDEFINE2TEXT(gcvHAL_CHIP_INFO),
-    gcmDEFINE2TEXT(gcvHAL_ATTACH),
-    gcmDEFINE2TEXT(gcvHAL_DETACH),
-    gcmDEFINE2TEXT(gcvHAL_SET_TIMEOUT),
     gcmDEFINE2TEXT(gcvHAL_GET_FRAME_INFO),
-    gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_PROFILE),
     gcmDEFINE2TEXT(gcvHAL_QUERY_COMMAND_BUFFER),
-    gcmDEFINE2TEXT(gcvHAL_COMMIT_DONE),
-    gcmDEFINE2TEXT(gcvHAL_DUMP_GPU_STATE),
-    gcmDEFINE2TEXT(gcvHAL_DUMP_EVENT),
-    gcmDEFINE2TEXT(gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER),
-    gcmDEFINE2TEXT(gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER),
     gcmDEFINE2TEXT(gcvHAL_SET_FSCALE_VALUE),
     gcmDEFINE2TEXT(gcvHAL_GET_FSCALE_VALUE),
-    gcmDEFINE2TEXT(gcvHAL_EXPORT_VIDEO_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_NAME_VIDEO_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_IMPORT_VIDEO_MEMORY),
     gcmDEFINE2TEXT(gcvHAL_QUERY_RESET_TIME_STAMP),
-    gcmDEFINE2TEXT(gcvHAL_READ_REGISTER_EX),
-    gcmDEFINE2TEXT(gcvHAL_WRITE_REGISTER_EX),
     gcmDEFINE2TEXT(gcvHAL_CREATE_NATIVE_FENCE),
     gcmDEFINE2TEXT(gcvHAL_WAIT_NATIVE_FENCE),
-    gcmDEFINE2TEXT(gcvHAL_DESTROY_MMU),
     gcmDEFINE2TEXT(gcvHAL_SHBUF),
     gcmDEFINE2TEXT(gcvHAL_GET_GRAPHIC_BUFFER_FD),
     gcmDEFINE2TEXT(gcvHAL_SET_VIDEO_MEMORY_METADATA),
     gcmDEFINE2TEXT(gcvHAL_GET_VIDEO_MEMORY_FD),
-    gcmDEFINE2TEXT(gcvHAL_CONFIG_POWER_MANAGEMENT),
-    gcmDEFINE2TEXT(gcvHAL_WRAP_USER_MEMORY),
+    gcmDEFINE2TEXT(gcvHAL_DESTROY_MMU),
     gcmDEFINE2TEXT(gcvHAL_WAIT_FENCE),
-#if gcdDEC_ENABLE_AHB
+    gcmDEFINE2TEXT(gcvHAL_DEVICE_MUTEX),
+    gcmDEFINE2TEXT(gcvHAL_DEC200_TEST),
     gcmDEFINE2TEXT(gcvHAL_DEC300_READ),
     gcmDEFINE2TEXT(gcvHAL_DEC300_WRITE),
     gcmDEFINE2TEXT(gcvHAL_DEC300_FLUSH),
     gcmDEFINE2TEXT(gcvHAL_DEC300_FLUSH_WAIT),
-#endif
-    gcmDEFINE2TEXT(gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY),
-    gcmDEFINE2TEXT(gcvHAL_QUERY_CHIP_OPTION),
 };
 #endif
 
@@ -282,42 +274,6 @@ _MonitorTimerFunction(
 }
 #endif
 
-#if gcdPROCESS_ADDRESS_SPACE
-gceSTATUS
-_MapCommandBuffer(
-    IN gckKERNEL Kernel
-    )
-{
-    gceSTATUS status;
-    gctUINT32 i;
-    gctPHYS_ADDR_T physical;
-    gctUINT32 address;
-    gckMMU mmu;
-
-    gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
-
-    for (i = 0; i < gcdCOMMAND_QUEUES; i++)
-    {
-        gcmkONERROR(gckOS_GetPhysicalAddress(
-            Kernel->os,
-            Kernel->command->queues[i].logical,
-            &physical
-            ));
-
-        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, physical, &physical));
-
-        gcmkSAFECASTPHYSADDRT(address, physical);
-
-        gcmkONERROR(gckMMU_FlatMapping(mmu, address, 1));
-    }
-
-    return gcvSTATUS_OK;
-
-OnError:
-    return status;
-}
-#endif
-
 void
 _DumpDriverConfigure(
     IN gckKERNEL Kernel
@@ -341,8 +297,6 @@ _DumpState(
     /* Dump GPU Debug registers. */
     gcmkVERIFY_OK(gckHARDWARE_DumpGPUState(Kernel->hardware));
 
-    gcmkVERIFY_OK(gckCOMMAND_DumpExecutingBuffer(Kernel->command));
-
     /* Dump Pending event. */
     gcmkVERIFY_OK(gckEVENT_Dump(Kernel->eventObj));
 
@@ -353,11 +307,17 @@ _DumpState(
     /* Dump record. */
     gckRECORDER_Dump(Kernel->command->recorder);
 #endif
+
+    if (Kernel->command)
+    {
+        gcmkVERIFY_OK(gckCOMMAND_DumpExecutingBuffer(Kernel->command));
+    }
 }
 
-static gceHARDWARE_TYPE
-_GetHardwareType(
-    IN gckKERNEL Kernel
+gceSTATUS
+gckKERNEL_GetHardwareType(
+    IN gckKERNEL Kernel,
+    OUT gceHARDWARE_TYPE *Type
     )
 {
     gceHARDWARE_TYPE type;
@@ -375,8 +335,10 @@ _GetHardwareType(
         type = Kernel->hardware->type;
     }
 
+    *Type = type;
+
     gcmkFOOTER_ARG("type=%d", type);
-    return type;
+    return gcvSTATUS_OK;
 }
 
 gceSTATUS
@@ -439,10 +401,11 @@ gckKERNEL_Construct(
     gceSTATUS status;
     gctSIZE_T i;
     gctPOINTER pointer = gcvNULL;
+    gctUINT64 data;
     gctUINT32 recovery;
     gctUINT32 stuckDump;
 
-    gcmkHEADER_ARG("Os=0x%x Context=0x%x", Os, Context);
+    gcmkHEADER_ARG("Os=%p Context=%p", Os, Context);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -495,19 +458,26 @@ gckKERNEL_Construct(
         gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->dbMutex));
 
         /* Construct a video memory name database. */
-        gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->nameDatabase));
+        gcmkONERROR(gckKERNEL_CreateIntegerDatabase(
+            kernel,
+            512,
+            &kernel->db->nameDatabase
+            ));
 
         /* Construct a video memory name database mutex. */
         gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->nameDatabaseMutex));
 
         /* Construct a pointer name database. */
-        gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->pointerDatabase));
+        gcmkONERROR(gckKERNEL_CreateIntegerDatabase(
+            kernel,
+            512,
+            &kernel->db->pointerDatabase
+            ));
 
-        /* Construct a pointer name database mutex. */
-        gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->pointerDatabaseMutex));
+        /* Initialize video memory node list. */
+        gcsLIST_Init(&kernel->db->videoMemList);
 
-        /* Initialize on fault vidmem list. */
-        gcsLIST_Init(&kernel->db->onFaultVidmemList);
+        gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->videoMemListMutex));
     }
     else
     {
@@ -521,6 +491,8 @@ gckKERNEL_Construct(
         kernel->timers[i].stopTime = 0;
     }
 
+    gcmkONERROR(gckOS_CreateMutex(Os, &kernel->vidMemBlockMutex));
+
     /* Save context. */
     kernel->context = Context;
 
@@ -532,11 +504,13 @@ gckKERNEL_Construct(
     kernel->stuckDump = gcvSTUCK_DUMP_NONE;
 
     /* Override default recovery and stuckDump setting. */
-    status = gckOS_QueryOption(Os, "recovery", &recovery);
+    status = gckOS_QueryOption(Os, "recovery", &data);
+    recovery = (gctUINT32)data;
 
     if (gcmIS_SUCCESS(status))
     {
-        status = gckOS_QueryOption(Os, "stuckDump", &stuckDump);
+        status = gckOS_QueryOption(Os, "stuckDump", &data);
+        stuckDump = (gctUINT32)data;
 
         gcmkASSERT(status == gcvSTATUS_OK);
 
@@ -547,19 +521,13 @@ gckKERNEL_Construct(
        gckOS_MapPagesEx() is called to map kernel virtual command buffers. */
     *Kernel = kernel;
 
-    kernel->virtualBufferHead =
-        kernel->virtualBufferTail = gcvNULL;
-
-    gcmkONERROR(
-        gckOS_CreateMutex(Os, (gctPOINTER)&kernel->virtualBufferLock));
-
 #if gcdENABLE_VG
     kernel->vg = gcvNULL;
 
     if (Core == gcvCORE_VG)
     {
-        gctUINT32 contiguousBase;
-        gctUINT32 contiguousSize = 0;
+        gctPHYS_ADDR_T contiguousBase;
+        gctSIZE_T contiguousSize = 0;
 
         /* Construct the gckMMU object. */
         gcmkONERROR(
@@ -571,7 +539,8 @@ gckKERNEL_Construct(
 
         if (gcmIS_SUCCESS(status))
         {
-            status = gckOS_QueryOption(Os, "contiguousSize", &contiguousSize);
+            status = gckOS_QueryOption(Os, "contiguousSize", &data);
+            contiguousSize = (gctSIZE_T)data;
         }
 
         if (gcmIS_SUCCESS(status) && contiguousSize)
@@ -588,23 +557,24 @@ gckKERNEL_Construct(
     {
         /* Construct the gckHARDWARE object. */
         gcmkONERROR(
-            gckHARDWARE_Construct(Os, kernel->core, &kernel->hardware));
+            gckHARDWARE_Construct(Os, kernel->device, kernel->core, &kernel->hardware));
 
         /* Set pointer to gckKERNEL object in gckHARDWARE object. */
         kernel->hardware->kernel = kernel;
 
+        kernel->sRAMNonExclusive = kernel->hardware->sRAMNonExclusive;
+
+        for (i = gcvSRAM_EXTERNAL0; i < gcvSRAM_COUNT; i++)
+        {
+            kernel->sRAMVideoMem[i] = kernel->hardware->sRAMVideoMem[i];
+            kernel->sRAMPhysical[i] = kernel->hardware->sRAMPhysical[i];
+        }
+
         kernel->timeOut = kernel->hardware->type == gcvHARDWARE_2D
                         ? gcdGPU_2D_TIMEOUT
                         : gcdGPU_TIMEOUT
                         ;
 
-        /* Initialize virtual command buffer. */
-#if gcdALLOC_CMD_FROM_RESERVE || gcdSECURITY || gcdDISABLE_GPU_VIRTUAL_ADDRESS || !USE_KERNEL_VIRTUAL_BUFFERS
-        kernel->virtualCommandBuffer = gcvFALSE;
-#else
-        kernel->virtualCommandBuffer = kernel->hardware->options.enableMMU;
-#endif
-
 #if gcdSHARED_PAGETABLE
         /* Construct the gckMMU object. */
         gcmkONERROR(
@@ -630,38 +600,66 @@ gckKERNEL_Construct(
             }
         }
 
-        gcmkVERIFY_OK(gckMMU_AttachHardware(kernel->mmu, kernel->hardware));
+        gcmkONERROR(
+            gckMMU_SetupPerHardware(kernel->mmu, kernel->hardware, kernel->device));
+
+        if (kernel->hardware->mmuVersion && !kernel->mmu->dynamicAreaSetuped)
+        {
+            gcmkONERROR(
+                gckMMU_SetupDynamicSpace(kernel->mmu));
+
+            kernel->mmu->dynamicAreaSetuped = gcvTRUE;
+        }
+
+        if (kernel->hardware->mmuVersion > 0)
+        {
+            /* Flush MTLB table. */
+            gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+                kernel,
+                kernel->mmu->mtlbVideoMem,
+                0,
+                kernel->mmu->mtlbLogical,
+                kernel->mmu->mtlbSize
+                ));
+        }
 #endif
 
         kernel->contiguousBaseAddress = kernel->mmu->contiguousBaseAddress;
         kernel->externalBaseAddress   = kernel->mmu->externalBaseAddress;
 
-        /* Construct the gckCOMMAND object. */
-        gcmkONERROR(
-            gckCOMMAND_Construct(kernel, &kernel->command));
+        /* Construct the gckCOMMAND object, either MCFE or wait-link FE can exist. */
+        if (gckHARDWARE_IsFeatureAvailable(kernel->hardware, gcvFEATURE_MCFE))
+        {
+            /* Construct the gckCOMMAND object for multi-channel FE. */
+            gcmkONERROR(gckCOMMAND_Construct(kernel, gcvHW_FE_MULTI_CHANNEL, &kernel->command));
 
-        if (gckHARDWARE_IsFeatureAvailable(kernel->hardware, gcvFEATURE_ASYNC_BLIT))
+            /* Construct gckEVENT for multi-channel FE. */
+            gcmkONERROR(gckEVENT_Construct(kernel, kernel->command, &kernel->eventObj));
+        }
+        else
         {
-            /* Construct the gckASYNC_COMMAND object for BLT engine. */
-            gcmkONERROR(gckASYNC_COMMAND_Construct(kernel, &kernel->asyncCommand));
+            /* Construct the gckCOMMAND object for legacy wait-link FE. */
+            gcmkONERROR(gckCOMMAND_Construct(kernel, gcvHW_FE_WAIT_LINK, &kernel->command));
 
-            /* Construct gckEVENT for BLT. */
-            gcmkONERROR(gckEVENT_Construct(kernel, &kernel->asyncEvent));
+            /* Construct the gckEVENT object. */
+            gcmkONERROR(gckEVENT_Construct(kernel, kernel->command, &kernel->eventObj));
+        }
 
-            kernel->asyncEvent->asyncCommand = kernel->asyncCommand;
+        if (gckHARDWARE_IsFeatureAvailable(kernel->hardware, gcvFEATURE_ASYNC_BLIT))
+        {
+            /* Construct the gckCOMMAND object for BLT engine. */
+            gcmkONERROR(gckCOMMAND_Construct(kernel, gcvHW_FE_ASYNC, &kernel->asyncCommand));
 
-            kernel->command->asyncCommand = kernel->asyncCommand;
+            /* Construct gckEVENT for BLT. */
+            gcmkONERROR(gckEVENT_Construct(kernel, kernel->asyncCommand, &kernel->asyncEvent));
         }
 
-        /* Construct the gckEVENT object. */
-        gcmkONERROR(
-            gckEVENT_Construct(kernel, &kernel->eventObj));
-
         gcmkVERIFY_OK(gckOS_GetTime(&kernel->resetTimeStamp));
 
-        gcmkONERROR(gckHARDWARE_PrepareFunctions(kernel->hardware));
+        /* Post construct hardware elements after MMU settle. */
+        gcmkONERROR(gckHARDWARE_PostConstruct(kernel->hardware));
 
-        /* Initialize the hardware. */
+        /* Initialize the GPU. */
         gcmkONERROR(
             gckHARDWARE_InitializeHardware(kernel->hardware));
 
@@ -675,8 +673,17 @@ gckKERNEL_Construct(
 #endif
 
 #if COMMAND_PROCESSOR_VERSION == 1
-        /* Start the command queue. */
-        gcmkONERROR(gckCOMMAND_Start(kernel->command));
+        if (kernel->command)
+        {
+            /* Start the command queue. */
+            gcmkONERROR(gckCOMMAND_Start(kernel->command));
+        }
+
+        if (kernel->asyncCommand)
+        {
+            /* Start the async command queue. */
+            gcmkONERROR(gckCOMMAND_Start(kernel->asyncCommand));
+        }
 #endif
     }
 
@@ -721,7 +728,7 @@ gckKERNEL_Construct(
     *Kernel = kernel;
 
     /* Success. */
-    gcmkFOOTER_ARG("*Kernel=0x%x", *Kernel);
+    gcmkFOOTER_ARG("*Kernel=%p", *Kernel);
     return gcvSTATUS_OK;
 
 OnError:
@@ -761,7 +768,7 @@ gckKERNEL_Destroy(
     gcsDATABASE_PTR database, databaseNext;
     gcsDATABASE_RECORD_PTR record, recordNext;
 
-    gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+    gcmkHEADER_ARG("Kernel=%p", Kernel);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -769,6 +776,72 @@ gckKERNEL_Destroy(
     gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->debugMutex));
 #endif
 
+    if (Kernel->monitorTimer)
+    {
+        /* Stop and destroy monitor timer. */
+        gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->monitorTimer));
+        gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->monitorTimer));
+    }
+
+#if gcdENABLE_VG
+    if (Kernel->vg)
+    {
+        gcmkVERIFY_OK(gckVGKERNEL_Destroy(Kernel->vg));
+    }
+    else
+#endif
+    {
+        if (Kernel->command)
+        {
+            /* Destroy the gckCOMMNAND object. */
+            gcmkVERIFY_OK(gckCOMMAND_Destroy(Kernel->command));
+        }
+
+        if (Kernel->asyncCommand)
+        {
+            gcmkVERIFY_OK(gckCOMMAND_Destroy(Kernel->asyncCommand));
+        }
+
+        if (Kernel->asyncEvent)
+        {
+            gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->asyncEvent));
+        }
+
+        if (Kernel->eventObj)
+        {
+            /* Destroy the gckEVENT object. */
+            gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->eventObj));
+        }
+
+        /* Destroy hardware resources before destroying MMU. */
+        gcmkVERIFY_OK(gckHARDWARE_PreDestroy(Kernel->hardware));
+
+        if (Kernel->mmu)
+        {
+#if gcdSHARED_PAGETABLE
+            /* Destroy the gckMMU object. */
+            gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
+#else
+            if (Kernel->mmu->hardware == Kernel->hardware)
+            {
+                /* Destroy the gckMMU object. */
+                gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
+            }
+#endif
+        }
+
+        /* Destroy the gckHARDWARE object. */
+        gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
+    }
+
+    if (Kernel->atomClients)
+    {
+        /* Detsroy the client atom. */
+        gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
+    }
+
+    gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->vidMemBlockMutex));
+
     /* Destroy the database. */
     if (Kernel->dbCreated)
     {
@@ -837,93 +910,19 @@ gckKERNEL_Destroy(
             gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->pointerDatabase));
         }
 
-        if (Kernel->db->pointerDatabaseMutex)
+        if (Kernel->db->videoMemListMutex)
         {
-            /* Destroy id-pointer database mutex. */
-            gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
+            /* Destroy video memory list mutex. */
+            gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->videoMemListMutex));
         }
 
-        if (Kernel->db)
-        {
-            /* Destroy the database. */
-            gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db));
-        }
+        /* Destroy the database. */
+        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, Kernel->db));
 
         /* Notify stuck timer to quit. */
         Kernel->monitorTimerStop = gcvTRUE;
     }
 
-    if (Kernel->monitorTimer)
-    {
-        /* Stop and destroy monitor timer. */
-        gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->monitorTimer));
-        gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->monitorTimer));
-    }
-
-#if gcdENABLE_VG
-    if (Kernel->vg)
-    {
-        gcmkVERIFY_OK(gckVGKERNEL_Destroy(Kernel->vg));
-    }
-    else
-#endif
-    {
-        if (Kernel->command)
-        {
-            /* Destroy the gckCOMMNAND object. */
-            gcmkVERIFY_OK(gckCOMMAND_Destroy(Kernel->command));
-        }
-
-        if (Kernel->asyncCommand)
-        {
-            gcmkVERIFY_OK(gckASYNC_COMMAND_Destroy(Kernel->asyncCommand));
-        }
-
-        if (Kernel->asyncEvent)
-        {
-            gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->asyncEvent));
-        }
-
-        if (Kernel->eventObj)
-        {
-            /* Destroy the gckEVENT object. */
-            gcmkVERIFY_OK(gckEVENT_Destroy(Kernel->eventObj));
-        }
-
-        gcmkVERIFY_OK(gckHARDWARE_DestroyFunctions(Kernel->hardware));
-
-        if (Kernel->mmu)
-        {
-#if gcdSHARED_PAGETABLE
-            /* Destroy the gckMMU object. */
-            gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
-#else
-            if (Kernel->mmu->hardware == Kernel->hardware)
-            {
-                /* Destroy the gckMMU object. */
-                gcmkVERIFY_OK(gckMMU_Destroy(Kernel->mmu));
-            }
-#endif
-        }
-
-        if (Kernel->hardware)
-        {
-            /* Destroy the gckHARDWARE object. */
-            gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
-        }
-    }
-
-    if (Kernel->atomClients)
-    {
-        /* Detsroy the client atom. */
-        gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->atomClients));
-    }
-
-    if (Kernel->virtualBufferLock)
-    {
-        gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock));
-    }
-
 #if gcdDVFS
     if (Kernel->dvfs)
     {
@@ -959,74 +958,69 @@ gckKERNEL_Destroy(
 
 /*******************************************************************************
 **
-**  _AllocateMemory
+**  gckKERNEL_AllocateVideoMemory
 **
-**  Private function to walk all required memory pools to allocate the requested
-**  amount of video memory.
+**  Walk requested pools to allocate video memory.
 **
 **  INPUT:
 **
 **      gckKERNEL Kernel
 **          Pointer to an gckKERNEL object.
 **
-**      gcsHAL_INTERFACE * Interface
-**          Pointer to a gcsHAL_INTERFACE structure that defines the command to
-**          be dispatched.
-**
 **  OUTPUT:
 **
-**      gcsHAL_INTERFACE * Interface
-**          Pointer to a gcsHAL_INTERFACE structure that receives any data to be
-**          returned.
+**      gckVIDMEM_NODE * NodeObject
+**          Pointer to a variable receiving video memory represetation.
 */
 gceSTATUS
-gckKERNEL_AllocateLinearMemory(
+gckKERNEL_AllocateVideoMemory(
     IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    IN OUT gcePOOL * Pool,
-    IN gctSIZE_T Bytes,
     IN gctUINT32 Alignment,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     IN gctUINT32 Flag,
-    OUT gctUINT32 * Node
+    IN OUT gctSIZE_T * Bytes,
+    IN OUT gcePOOL * Pool,
+    OUT gckVIDMEM_NODE * NodeObject
     )
 {
-    gcePOOL pool;
     gceSTATUS status;
+    gcePOOL pool;
     gckVIDMEM videoMemory;
     gctINT loopCount;
-    gcuVIDMEM_NODE_PTR node = gcvNULL;
-    gctBOOL tileStatusInVirtual;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
     gctBOOL contiguous = gcvFALSE;
     gctBOOL cacheable = gcvFALSE;
     gctBOOL secure = gcvFALSE;
     gctBOOL fastPools = gcvFALSE;
+    gctBOOL virtualPool4K = gcvFALSE;
     gctBOOL hasFastPools = gcvFALSE;
-    gctSIZE_T bytes = Bytes;
-    gctUINT32 handle = 0;
-    gceDATABASE_TYPE type;
+    gctSIZE_T bytes = *Bytes;
+    gctUINT32 sRAMIndex = 1;
 
-    gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d",
-                   Kernel, *Pool, Bytes, Alignment, Type);
+    gcmkHEADER_ARG("Kernel=%p *Pool=%d *Bytes=%lu Alignment=%lu Type=%d",
+                   Kernel, *Pool, *Bytes, Alignment, Type);
 
-    gcmkVERIFY_ARGUMENT(Pool != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Bytes != 0);
-
-    /* Get basic type. */
-    Type &= 0xFF;
+    *NodeObject = gcvNULL;
 
     /* Check flags. */
     contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
     cacheable  = Flag & gcvALLOC_FLAG_CACHEABLE;
     secure     = Flag & gcvALLOC_FLAG_SECURITY;
+
     if (Flag & gcvALLOC_FLAG_FAST_POOLS)
     {
         fastPools = gcvTRUE;
         Flag &= ~gcvALLOC_FLAG_FAST_POOLS;
     }
 
+    if (Flag & gcvALLOC_FLAG_4K_PAGES)
+    {
+        virtualPool4K = gcvTRUE;
+        Flag &= ~gcvALLOC_FLAG_4K_PAGES;
+    }
+
 #if gcdALLOC_ON_FAULT
-    if (Type == gcvSURF_RENDER_TARGET)
+    if (Type == gcvVIDMEM_COLOR_BUFFER)
     {
         Flag |= gcvALLOC_FLAG_ALLOC_ON_FAULT;
     }
@@ -1045,7 +1039,37 @@ gckKERNEL_AllocateLinearMemory(
         /* Usually, the exported dmabuf might be later imported to DRM,
         ** while DRM requires input size to be page aligned.
         */
-        Bytes = gcmALIGN(Bytes, pageSize);
+        bytes = gcmALIGN(bytes, pageSize);
+    }
+
+    if (Type == gcvVIDMEM_TYPE_COMMAND)
+    {
+#if gcdALLOC_CMD_FROM_RESERVE || gcdSECURITY || gcdDISABLE_GPU_VIRTUAL_ADDRESS || !USE_KERNEL_VIRTUAL_BUFFERS
+        Flag |= gcvALLOC_FLAG_CONTIGUOUS;
+#endif
+    }
+
+    if (Type == gcvVIDMEM_TYPE_TILE_STATUS)
+    {
+        gctBOOL tileStatusInVirtual;
+
+#if gcdENABLE_VG
+        if (Kernel->vg)
+        {
+            tileStatusInVirtual = gcvFALSE;
+        }
+        else
+#endif
+        {
+            tileStatusInVirtual =
+                gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_MC20);
+        }
+
+        if (!tileStatusInVirtual)
+        {
+            /* Must be contiguous if not support virtual tile status. */
+            Flag |= gcvALLOC_FLAG_CONTIGUOUS;
+        }
     }
 
 AllocateMemory:
@@ -1064,10 +1088,6 @@ AllocateMemory:
         loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
         break;
 
-    case gcvPOOL_CONTIGUOUS:
-        loopCount = (gctINT) gcvPOOL_NUMBER_OF_POOLS;
-        break;
-
     default:
         loopCount = 1;
         break;
@@ -1077,80 +1097,126 @@ AllocateMemory:
     {
         if (pool == gcvPOOL_VIRTUAL)
         {
-            /* Create a gcuVIDMEM_NODE for virtual memory. */
-            gcmkONERROR(
-                gckVIDMEM_ConstructVirtual(Kernel, Flag | gcvALLOC_FLAG_NON_CONTIGUOUS, Bytes, &node));
-
-            bytes = node->Virtual.bytes;
-            node->Virtual.type = Type;
-
-            /* Success. */
-            break;
-        }
-
-        else
-        if (pool == gcvPOOL_CONTIGUOUS)
-        {
+            /* Try contiguous virtual first. */
 #if gcdCONTIGUOUS_SIZE_LIMIT
-            if (Bytes > gcdCONTIGUOUS_SIZE_LIMIT && contiguous == gcvFALSE)
+            if (bytes > gcdCONTIGUOUS_SIZE_LIMIT && contiguous == gcvFALSE)
             {
                 status = gcvSTATUS_OUT_OF_MEMORY;
             }
             else
 #endif
+#if gcdENABLE_GPU_1M_PAGE
+            if (!virtualPool4K && Kernel->core != gcvCORE_VG && Kernel->hardware->mmuVersion)
             {
-                /* Create a gcuVIDMEM_NODE from contiguous memory. */
-                status = gckVIDMEM_ConstructVirtual(
+                /* Create a gckVIDMEM_NODE from contiguous memory. */
+                status = gckVIDMEM_NODE_AllocateVirtualChunk(
                             Kernel,
+                            pool,
+                            Type,
                             Flag | gcvALLOC_FLAG_CONTIGUOUS,
-                            Bytes,
-                            &node);
+                            &bytes,
+                            &nodeObject);
+
+                if (gcmIS_SUCCESS(status))
+                {
+                    /* Memory allocated. */
+                    break;
+                }
+            }
+#endif
+            {
+                /* Create a gckVIDMEM_NODE from contiguous memory. */
+                status = gckVIDMEM_NODE_AllocateVirtual(
+                            Kernel,
+                            pool,
+                            Type,
+                            Flag | gcvALLOC_FLAG_CONTIGUOUS,
+                            &bytes,
+                            &nodeObject);
             }
 
             if (gcmIS_SUCCESS(status))
             {
-                bytes = node->Virtual.bytes;
-                node->Virtual.type = Type;
-
                 /* Memory allocated. */
                 break;
             }
-        }
 
-        else
-        /* gcvPOOL_SYSTEM can't be cacheable. */
-        if (cacheable == gcvFALSE && secure == gcvFALSE)
+            if (contiguous)
+            {
+                break;
+            }
+
+#if gcdENABLE_GPU_1M_PAGE
+            /* Try non-contiguous virtual chunk. */
+            if (!virtualPool4K && Kernel->hardware->mmuVersion && Kernel->core != gcvCORE_VG)
+            {
+                /* Create a gckVIDMEM_NODE from contiguous memory. */
+                status = gckVIDMEM_NODE_AllocateVirtualChunk(
+                            Kernel,
+                            pool,
+                            Type,
+                            Flag | gcvALLOC_FLAG_NON_CONTIGUOUS,
+                            &bytes,
+                            &nodeObject);
+
+                if (gcmIS_SUCCESS(status))
+                {
+                    /* Memory allocated. */
+                    break;
+                }
+            }
+#endif
+            /* Try non-contiguous virtual. */
+            /* Create a gckVIDMEM_NODE for virtual memory. */
+            gcmkONERROR(
+                gckVIDMEM_NODE_AllocateVirtual(Kernel,
+                                               pool,
+                                               Type,
+                                               Flag | gcvALLOC_FLAG_NON_CONTIGUOUS,
+                                               &bytes, &nodeObject));
+
+            /* Success. */
+            break;
+        }
+        /* gcvPOOL_SYSTEM/gcvPOOL_SRAM can't be cacheable. */
+        else if (cacheable == gcvFALSE && secure == gcvFALSE)
         {
             /* Get pointer to gckVIDMEM object for pool. */
+            Kernel->sRAMIndex = sRAMIndex;
+
             status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory);
 
             if (gcmIS_SUCCESS(status))
             {
                 /* Allocate memory. */
+                if ((Flag & videoMemory->capability) != Flag)
+                {
+                    status = gcvSTATUS_NOT_SUPPORTED;
+
+                }
 #if defined(gcdLINEAR_SIZE_LIMIT)
                 /* 512 KB */
-                if (Bytes > gcdLINEAR_SIZE_LIMIT)
+                else if (bytes > gcdLINEAR_SIZE_LIMIT)
                 {
                     status = gcvSTATUS_OUT_OF_MEMORY;
                 }
-                else
 #endif
+                else
                 {
                     hasFastPools = gcvTRUE;
-                    status = gckVIDMEM_AllocateLinear(Kernel,
-                                                      videoMemory,
-                                                      Bytes,
-                                                      Alignment,
-                                                      Type,
-                                                      (*Pool == gcvPOOL_SYSTEM),
-                                                      &node);
+                    status = gckVIDMEM_NODE_AllocateLinear(Kernel,
+                                                           videoMemory,
+                                                           pool,
+                                                           Type,
+                                                           Alignment,
+                                                           (pool == gcvPOOL_SYSTEM || pool == gcvPOOL_SRAM),
+                                                           &bytes,
+                                                           &nodeObject);
                 }
 
                 if (gcmIS_SUCCESS(status))
                 {
                     /* Memory allocated. */
-                    node->VidMem.pool = pool;
-                    bytes = node->VidMem.bytes;
                     break;
                 }
             }
@@ -1165,47 +1231,40 @@ AllocateMemory:
         else
         if (pool == gcvPOOL_LOCAL_EXTERNAL)
         {
-            /* Advance to contiguous system memory. */
-            pool = gcvPOOL_SYSTEM;
-        }
-
-        else
-        if (pool == gcvPOOL_SYSTEM)
-        {
-            /* Do not go ahead to try relative slow pools */
-            if (fastPools && hasFastPools)
+            if (Kernel->sRAMNonExclusive)
             {
-                status = gcvSTATUS_OUT_OF_MEMORY;
-                break;
+                /* Advance to SRAM memory. */
+                pool = gcvPOOL_SRAM;
+            }
+            else
+            {
+                /* Advance to contiguous reserved memory. */
+                pool = gcvPOOL_SYSTEM;
             }
-
-            /* Advance to contiguous memory. */
-            pool = gcvPOOL_CONTIGUOUS;
         }
 
         else
-        if (pool == gcvPOOL_CONTIGUOUS)
+        if (pool == gcvPOOL_SRAM)
         {
-#if gcdENABLE_VG
-            if (Kernel->vg)
+            if (sRAMIndex < gcvSRAM_COUNT - 1)
             {
-                tileStatusInVirtual = gcvFALSE;
+                sRAMIndex++;
+                loopCount++;
             }
             else
-#endif
-            {
-                tileStatusInVirtual =
-                    gckHARDWARE_IsFeatureAvailable(Kernel->hardware,
-                                                   gcvFEATURE_MC20);
-            }
-
-            if (Type == gcvSURF_TILE_STATUS && tileStatusInVirtual != gcvTRUE)
             {
-                gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+                /* Advance to contiguous reserved memory. */
+                pool = gcvPOOL_SYSTEM;
             }
+        }
 
-            if (contiguous)
+        else
+        if (pool == gcvPOOL_SYSTEM)
+        {
+            /* Do not go ahead to try relative slow pools */
+            if (fastPools && hasFastPools)
             {
+                status = gcvSTATUS_OUT_OF_MEMORY;
                 break;
             }
 
@@ -1220,7 +1279,7 @@ AllocateMemory:
         }
     }
 
-    if (node == gcvNULL)
+    if (nodeObject == gcvNULL)
     {
         if (contiguous)
         {
@@ -1239,31 +1298,86 @@ AllocateMemory:
         gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
     }
 
+    /* Return node and pool used for allocation. */
+    *Pool  = pool;
+    *Bytes = bytes;
+    *NodeObject  = nodeObject;
+
+    /* Return status. */
+    gcmkFOOTER_ARG("*Pool=%d *NodeObject=%p", *Pool, *NodeObject);
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+
+/*******************************************************************************
+**
+**  _AllocateLinearMemory
+**
+**  Private function to allocate the requested amount of video memory, output
+**  video memory handle.
+*/
+gceSTATUS
+_AllocateLinearMemory(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
+    IN gcsHAL_INTERFACE * Interface
+    )
+{
+    gceSTATUS status;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+    gctUINT32 handle = 0;
+    gceDATABASE_TYPE dbType;
+    gcePOOL pool = (gcePOOL)Interface->u.AllocateLinearVideoMemory.pool;
+    gctSIZE_T bytes = (gctSIZE_T)Interface->u.AllocateLinearVideoMemory.bytes;
+    gctUINT32 alignment = Interface->u.AllocateLinearVideoMemory.alignment;
+    gceVIDMEM_TYPE type = (Interface->u.AllocateLinearVideoMemory.type & 0xFF);
+    gctUINT32 flag = Interface->u.AllocateLinearVideoMemory.flag;
+
+    gcmkHEADER_ARG("Kernel=%p pool=%d bytes=%lu alignment=%lu type=%d",
+                   Kernel, pool, bytes, alignment, type);
+
+    gcmkVERIFY_ARGUMENT(bytes != 0);
+
+    /* Allocate video memory node. */
+    gcmkONERROR(
+        gckKERNEL_AllocateVideoMemory(Kernel,
+                                      alignment,
+                                      type,
+                                      flag,
+                                      &bytes,
+                                      &pool,
+                                      &nodeObject));
+
     /* Allocate handle for this video memory. */
     gcmkONERROR(
-        gckVIDMEM_NODE_Allocate(Kernel, node, Type, pool, &handle));
+        gckVIDMEM_HANDLE_Allocate(Kernel, nodeObject, &handle));
 
     /* Return node and pool used for allocation. */
-    *Node = handle;
-    *Pool = pool;
+    Interface->u.AllocateLinearVideoMemory.node = handle;
+    Interface->u.AllocateLinearVideoMemory.pool = pool;
+    Interface->u.AllocateLinearVideoMemory.bytes = bytes;
 
     /* Encode surface type and pool to database type. */
-    type = gcvDB_VIDEO_MEMORY
-         | (Type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
-         | (pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
+    dbType = gcvDB_VIDEO_MEMORY
+           | (type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
+           | (pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
 
     /* Record in process db. */
     gcmkONERROR(
             gckKERNEL_AddProcessDB(Kernel,
                                    ProcessID,
-                                   type,
+                                   dbType,
                                    gcmINT2PTR(handle),
                                    gcvNULL,
                                    bytes));
 
-
     /* Return status. */
-    gcmkFOOTER_ARG("*Pool=%d *Node=0x%x", *Pool, *Node);
+    gcmkFOOTER_ARG("pool=%d node=0x%x", pool, handle);
     return gcvSTATUS_OK;
 
 OnError:
@@ -1273,10 +1387,10 @@ OnError:
         gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, handle));
     }
 
-    if (node)
+    if (nodeObject)
     {
         /* Free video memory allocated. */
-        gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, node));
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, nodeObject));
     }
 
     /* Return the status. */
@@ -1286,7 +1400,7 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckKERNEL_ReleaseVideoMemory
+**  _ReleaseVideoMemory
 **
 **  Release handle of a video memory.
 **
@@ -1306,7 +1420,7 @@ OnError:
 **          Nothing.
 */
 gceSTATUS
-gckKERNEL_ReleaseVideoMemory(
+_ReleaseVideoMemory(
     IN gckKERNEL Kernel,
     IN gctUINT32 ProcessID,
     IN gctUINT32 Handle
@@ -1316,7 +1430,7 @@ gckKERNEL_ReleaseVideoMemory(
     gckVIDMEM_NODE nodeObject;
     gceDATABASE_TYPE type;
 
-    gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d Handle=%d",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d Handle=%d",
                    Kernel, ProcessID, Handle);
 
     gcmkONERROR(
@@ -1346,7 +1460,7 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckKERNEL_LockVideoMemory
+**  _LockVideoMemory
 **
 **      Lock a video memory node. It will generate a cpu virtual address used
 **      by software and a GPU address used by GPU.
@@ -1369,131 +1483,87 @@ OnError:
 **          Pointer to a gcsHAL_INTERFACE structure that receives any data to be
 **          returned.
 */
-gceSTATUS
-gckKERNEL_LockVideoMemory(
+static gceSTATUS
+_LockVideoMemory(
     IN gckKERNEL Kernel,
     IN gceCORE Core,
     IN gctUINT32 ProcessID,
-    IN gctBOOL FromUser,
     IN OUT gcsHAL_INTERFACE * Interface
     )
 {
     gceSTATUS status;
+    gctUINT32 handle;
     gckVIDMEM_NODE nodeObject = gcvNULL;
-    gcuVIDMEM_NODE_PTR node   = gcvNULL;
-    gctBOOL locked            = gcvFALSE;
-    gctBOOL asynchronous      = gcvFALSE;
-#ifndef __QNXNTO__
-    gctPOINTER pointer        = gcvNULL;
-#endif
+    gctBOOL referenced = gcvFALSE;
+    gctUINT32 address = gcvINVALID_ADDRESS;
+    gctPOINTER logical = gcvNULL;
+    gctPHYS_ADDR_T physical = gcvINVALID_PHYSICAL_ADDRESS;
+    gctUINT32 gid = 0;
+    gctBOOL asynchronous = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d",
                    Kernel, ProcessID);
 
-    gcmkONERROR(
-        gckVIDMEM_HANDLE_LookupAndReference(Kernel,
-                Interface->u.LockVideoMemory.node,
-                &nodeObject));
-
-    node = nodeObject->node;
-
-    Interface->u.LockVideoMemory.gid = 0;
+    handle = Interface->u.LockVideoMemory.node;
 
-    /* Lock video memory. */
     gcmkONERROR(
-            gckVIDMEM_Lock(Kernel,
-                nodeObject,
-                Interface->u.LockVideoMemory.cacheable,
-                &Interface->u.LockVideoMemory.address,
-                &Interface->u.LockVideoMemory.gid,
-                &Interface->u.LockVideoMemory.physicalAddress));
-
-    locked = gcvTRUE;
+        gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, handle, &nodeObject));
 
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
-    {
-        /* Map video memory address into user space. */
-#ifdef __QNXNTO__
-        if (node->VidMem.logical == gcvNULL)
-        {
-            gcmkONERROR(
-                    gckKERNEL_MapVideoMemory(Kernel,
-                        FromUser,
-                        Interface->u.LockVideoMemory.address,
-                        ProcessID,
-                        node->VidMem.bytes,
-                        &node->VidMem.logical));
-        }
-        gcmkASSERT(node->VidMem.logical != gcvNULL);
+    /* Ref node. */
+    gcmkONERROR(gckVIDMEM_NODE_Reference(Kernel, nodeObject));
+    referenced = gcvTRUE;
 
-        Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical);
-#else
-        gcmkONERROR(
-                gckKERNEL_MapVideoMemoryEx(Kernel,
-                    Core,
-                    FromUser,
-                    Interface->u.LockVideoMemory.address,
-                    node->VidMem.pool,
-                    &pointer));
-
-        Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(pointer);
-#endif
-    }
-    else
-    {
-        Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical);
+    /* Lock for userspace CPU userspace. */
+    gcmkONERROR(
+        gckVIDMEM_NODE_LockCPU(Kernel,
+                               nodeObject,
+                               Interface->u.LockVideoMemory.cacheable,
+                               gcvTRUE,
+                               &logical));
 
-        /* Success. */
-        status = gcvSTATUS_OK;
-    }
+    /* Lock for GPU address. */
+    gcmkONERROR(gckVIDMEM_NODE_Lock(Kernel, nodeObject, &address));
 
-#if gcdPROCESS_ADDRESS_SPACE
-    gcmkONERROR(gckVIDMEM_Node_Lock(
-        Kernel,
-        nodeObject,
-        &Interface->u.LockVideoMemory.address
-        ));
-#endif
+    /* Get CPU physical address. */
+    gcmkONERROR(gckVIDMEM_NODE_GetPhysical(Kernel, nodeObject, 0, &physical));
+    gcmkONERROR(gckVIDMEM_NODE_GetGid(Kernel, nodeObject, &gid));
 
+    Interface->u.LockVideoMemory.address = address;
+    Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical);
+    Interface->u.LockVideoMemory.physicalAddress = physical;
+    Interface->u.LockVideoMemory.gid = gid;
 
-#if gcdSECURE_USER
-    /* Return logical address as physical address. */
-    Interface->u.LockVideoMemory.address =
-        (gctUINT32)(Interface->u.LockVideoMemory.memory);
-#endif
     gcmkONERROR(
         gckKERNEL_AddProcessDB(Kernel,
-            ProcessID, gcvDB_VIDEO_MEMORY_LOCKED,
-            gcmINT2PTR(Interface->u.LockVideoMemory.node),
-            gcvNULL,
-            0));
+                               ProcessID,
+                               gcvDB_VIDEO_MEMORY_LOCKED,
+                               gcmINT2PTR(handle),
+                               logical,
+                               0));
 
-    gckVIDMEM_HANDLE_Reference(
-        Kernel, ProcessID, (gctUINT32)Interface->u.LockVideoMemory.node);
+    /* Ref handle. */
+    gckVIDMEM_HANDLE_Reference(Kernel, ProcessID, handle);
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if (locked)
+    if (logical)
+    {
+        gckVIDMEM_NODE_UnlockCPU(Kernel, nodeObject, ProcessID, gcvTRUE);
+    }
+
+    if (address)
     {
-        /* Roll back the lock. */
-        gcmkVERIFY_OK(gckVIDMEM_Unlock(Kernel,
-                    nodeObject,
-                    gcvSURF_TYPE_UNKNOWN,
-                    &asynchronous));
+        gckVIDMEM_NODE_Unlock(Kernel, nodeObject, ProcessID, &asynchronous);
 
-        if (gcvTRUE == asynchronous)
+        if (asynchronous)
         {
-            /* Bottom Half */
-            gcmkVERIFY_OK(gckVIDMEM_Unlock(Kernel,
-                        nodeObject,
-                        gcvSURF_TYPE_UNKNOWN,
-                        gcvNULL));
+            gckVIDMEM_NODE_Unlock(Kernel, nodeObject, ProcessID, gcvNULL);
         }
     }
 
-    if (nodeObject != gcvNULL)
+    if (referenced)
     {
         gckVIDMEM_NODE_Dereference(Kernel, nodeObject);
     }
@@ -1504,7 +1574,7 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckKERNEL_UnlockVideoMemory
+**  _UnlockVideoMemory
 **
 **      Unlock a video memory node.
 **
@@ -1526,8 +1596,8 @@ OnError:
 **          Pointer to a gcsHAL_INTERFACE structure that receives any data to be
 **          returned.
 */
-gceSTATUS
-gckKERNEL_UnlockVideoMemory(
+static gceSTATUS
+_UnlockVideoMemory(
     IN gckKERNEL Kernel,
     IN gctUINT32 ProcessID,
     IN OUT gcsHAL_INTERFACE * Interface
@@ -1536,9 +1606,10 @@ gckKERNEL_UnlockVideoMemory(
     gceSTATUS status;
     gckVIDMEM_NODE nodeObject;
     gcuVIDMEM_NODE_PTR node;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
     gctSIZE_T bytes;
 
-    gcmkHEADER_ARG("Kernel=0x%08X ProcessID=%d",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d",
                    Kernel, ProcessID);
 
     Interface->u.UnlockVideoMemory.pool = gcvPOOL_UNKNOWN;
@@ -1548,45 +1619,58 @@ gckKERNEL_UnlockVideoMemory(
         Kernel,
         ProcessID,
         (gctUINT32)Interface->u.UnlockVideoMemory.node,
-        &nodeObject));
+        &nodeObject
+        ));
 
-    node = nodeObject->node;
-    bytes = (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
-          ? node->VidMem.bytes
-          : node->Virtual.bytes;
+    /* Unlock CPU. */
+    gcmkONERROR(gckVIDMEM_NODE_UnlockCPU(
+        Kernel, nodeObject, ProcessID, gcvTRUE));
 
     /* Unlock video memory. */
-    gcmkONERROR(gckVIDMEM_Unlock(
+    gcmkONERROR(gckVIDMEM_NODE_Unlock(
         Kernel,
         nodeObject,
-        Interface->u.UnlockVideoMemory.type,
-        &Interface->u.UnlockVideoMemory.asynchroneous));
+        ProcessID,
+        &Interface->u.UnlockVideoMemory.asynchroneous
+        ));
+
+    /* Leave deref handle and deref node in later operation. */
+
+    node = nodeObject->node;
+
+    vidMemBlock = node->VirtualChunk.parent;
 
-#if gcdSECURE_USER
-    /* Flush the translation cache for virtual surfaces. */
-    if (node->VidMem.memory->object.type != gcvOBJ_VIDMEM)
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
-        gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(Kernel,
-                    cache,
-                    node->Virtual.logical,
-                    bytes));
+        bytes = node->VidMem.bytes;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        bytes = node->VirtualChunk.bytes;
+    }
+    else
+    {
+        bytes = node->Virtual.bytes;
     }
-#endif
 
-    Interface->u.UnlockVideoMemory.pool = nodeObject->pool;
-    Interface->u.UnlockVideoMemory.bytes = (gctUINT)bytes;
+    Interface->u.UnlockVideoMemory.pool  = nodeObject->pool;
+    Interface->u.UnlockVideoMemory.bytes = bytes;
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
+    /*
+     * Unlikely to fail expect error node or unlocked, there's no error roll
+     * back requried for those two conditions.
+     */
     gcmkFOOTER();
     return status;
 }
 
 /*******************************************************************************
 **
-**  gckKERNEL_BottomHalfUnlockVideoMemory
+**  _BottomHalfUnlockVideoMemory
 **
 **  Unlock video memory from gpu.
 **
@@ -1598,13 +1682,17 @@ OnError:
 **      gctUINT32 ProcessID
 **          Process ID owning this memory.
 **
+**      gceVIDMEM_TYPE
+**          Video memory allocation type.
+**
 **      gctPOINTER Pointer
 **          Video memory to be unlock.
 */
-gceSTATUS
-gckKERNEL_BottomHalfUnlockVideoMemory(
+static gceSTATUS
+_BottomHalfUnlockVideoMemory(
     IN gckKERNEL Kernel,
     IN gctUINT32 ProcessID,
+    IN gceVIDMEM_TYPE Type,
     IN gctUINT32 Node
     )
 {
@@ -1616,26 +1704,24 @@ gckKERNEL_BottomHalfUnlockVideoMemory(
         Kernel,
         ProcessID,
         gcvDB_VIDEO_MEMORY_LOCKED,
-        gcmINT2PTR(Node)));
+        gcmINT2PTR(Node)
+        ));
 
     gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
         Kernel,
         ProcessID,
         Node,
-        &nodeObject));
+        &nodeObject
+        ));
 
+    /* Deref handle. */
     gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, Node);
 
-    /* Unlock video memory. */
-    gcmkONERROR(gckVIDMEM_Unlock(
-        Kernel,
-        nodeObject,
-        gcvSURF_TYPE_UNKNOWN,
-        gcvNULL));
+    /* Unlock video memory, synced. */
+    gcmkONERROR(gckVIDMEM_NODE_Unlock(Kernel, nodeObject, ProcessID, gcvNULL));
 
-    gcmkONERROR(gckVIDMEM_NODE_Dereference(
-        Kernel,
-        nodeObject));
+    /* Deref node. */
+    gcmkONERROR(gckVIDMEM_NODE_Dereference(Kernel, nodeObject));
 
     return gcvSTATUS_OK;
 
@@ -1643,73 +1729,217 @@ OnError:
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckKERNEL_SetVidMemMetadata
-**
-**  Set/Get metadata to/from gckVIDMEM_NODE object.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gctUINT32 ProcessID
-**          ProcessID of current process.
-**
-**  INOUT:
-**
-**      gcsHAL_INTERFACE * Interface
-**          Pointer to a interface structure
-*/
-#if defined(CONFIG_DMA_SHARED_BUFFER)
-#include <linux/dma-buf.h>
-
-gceSTATUS
-gckKERNEL_SetVidMemMetadata(
+static gceSTATUS
+_WrapUserMemory(
     IN gckKERNEL Kernel,
     IN gctUINT32 ProcessID,
-    INOUT gcsHAL_INTERFACE * Interface
+    IN gcsHAL_INTERFACE * Interface
     )
 {
-    gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
-    gckVIDMEM_NODE nodeObj = gcvNULL;
+    gceSTATUS status;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+    gceDATABASE_TYPE type;
+    gctUINT32 handle = 0;
 
-    gcmkHEADER_ARG("Kernel=0x%X ProcessID=%d", Kernel, ProcessID);
+    gcmkONERROR(
+        gckVIDMEM_NODE_WrapUserMemory(Kernel,
+                                      &Interface->u.WrapUserMemory.desc,
+                                      Interface->u.WrapUserMemory.type,
+                                      &nodeObject,
+                                      &Interface->u.WrapUserMemory.bytes));
 
-    gcmkONERROR(gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Interface->u.SetVidMemMetadata.node, &nodeObj));
+    /* Create handle representation for userspace. */
+    gcmkONERROR(
+        gckVIDMEM_HANDLE_Allocate(Kernel,
+                                  nodeObject,
+                                  &handle));
 
-    if (Interface->u.SetVidMemMetadata.readback)
+    type = gcvDB_VIDEO_MEMORY
+         | (nodeObject->type << gcdDB_VIDEO_MEMORY_TYPE_SHIFT)
+         | (nodeObject->pool << gcdDB_VIDEO_MEMORY_POOL_SHIFT);
+
+    gcmkONERROR(
+        gckKERNEL_AddProcessDB(Kernel,
+                               ProcessID,
+                               type,
+                               gcmINT2PTR(handle),
+                               gcvNULL,
+                               (gctSIZE_T)Interface->u.WrapUserMemory.bytes));
+
+    Interface->u.WrapUserMemory.node = handle;
+    return gcvSTATUS_OK;
+
+OnError:
+    if (handle)
     {
-        Interface->u.SetVidMemMetadata.ts_fd            = nodeObj->metadata.ts_fd;
-        Interface->u.SetVidMemMetadata.fc_enabled       = nodeObj->metadata.fc_enabled;
-        Interface->u.SetVidMemMetadata.fc_value         = nodeObj->metadata.fc_value;
-        Interface->u.SetVidMemMetadata.fc_value_upper   = nodeObj->metadata.fc_value_upper;
-        Interface->u.SetVidMemMetadata.compressed       = nodeObj->metadata.compressed;
-        Interface->u.SetVidMemMetadata.compress_format  = nodeObj->metadata.compress_format;
+        gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, handle);
     }
-    else
+
+    if (nodeObject)
     {
-#ifdef gcdANDROID
+        gckVIDMEM_NODE_Dereference(Kernel, nodeObject);
+    }
+
+    return status;
+}
+
+static gceSTATUS
+_ExportVideoMemory(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
+    IN gcsHAL_INTERFACE * Interface
+    )
+{
+    gceSTATUS status;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+
+    gcmkONERROR(
+        gckVIDMEM_HANDLE_Lookup(Kernel,
+                                ProcessID,
+                                Interface->u.ExportVideoMemory.node,
+                                &nodeObject));
+
+    gcmkONERROR(
+        gckVIDMEM_NODE_Export(Kernel,
+                              nodeObject,
+                              Interface->u.ExportVideoMemory.flags,
+                              gcvNULL,
+                              &Interface->u.ExportVideoMemory.fd));
+
+OnError:
+    return status;
+}
+
+static gceSTATUS
+_NameVideoMemory(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
+    IN gcsHAL_INTERFACE * Interface
+    )
+{
+    gceSTATUS status;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+
+    gcmkONERROR(
+        gckVIDMEM_HANDLE_Lookup(Kernel,
+                                ProcessID,
+                                Interface->u.NameVideoMemory.handle,
+                                &nodeObject));
+
+    gcmkONERROR(
+        gckVIDMEM_NODE_Name(Kernel,
+                            nodeObject,
+                            &Interface->u.NameVideoMemory.name));
+OnError:
+    return status;
+}
+
+static gceSTATUS
+_ImportVideoMemory(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
+    IN gcsHAL_INTERFACE * Interface
+    )
+{
+    gceSTATUS status;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+    gctUINT32 handle = 0;
+
+    gcmkONERROR(
+        gckVIDMEM_NODE_Import(Kernel,
+                              Interface->u.ImportVideoMemory.name,
+                              &nodeObject));
+
+    /* Create handle representation for userspace. */
+    gcmkONERROR(
+        gckVIDMEM_HANDLE_Allocate(Kernel,
+                                  nodeObject,
+                                  &handle));
+
+    gcmkONERROR(
+        gckKERNEL_AddProcessDB(Kernel,
+                               ProcessID,
+                               gcvDB_VIDEO_MEMORY,
+                               gcmINT2PTR(handle),
+                               gcvNULL,
+                               0));
+
+    Interface->u.ImportVideoMemory.handle = handle;
+    return gcvSTATUS_OK;
+
+OnError:
+    if (handle)
+    {
+        gckVIDMEM_HANDLE_Dereference(Kernel, ProcessID, handle);
+    }
+
+    if (nodeObject)
+    {
+        gckVIDMEM_NODE_Dereference(Kernel, nodeObject);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+**
+**  gckKERNEL_SetVidMemMetadata
+**
+**  Set/Get metadata to/from gckVIDMEM_NODE object.
+**
+**  INPUT:
+**
+**      gckKERNEL Kernel
+**          Pointer to an gckKERNEL object.
+**
+**      gctUINT32 ProcessID
+**          ProcessID of current process.
+**
+**  INOUT:
+**
+**      gcsHAL_INTERFACE * Interface
+**          Pointer to a interface structure
+*/
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include <linux/dma-buf.h>
+
+gceSTATUS
+_SetVidMemMetadata(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
+    INOUT gcsHAL_INTERFACE * Interface
+    )
+{
+    gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+    gckVIDMEM_NODE nodeObj = gcvNULL;
+
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d", Kernel, ProcessID);
+
+    gcmkONERROR(gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Interface->u.SetVidMemMetadata.node, &nodeObj));
+
+    if (Interface->u.SetVidMemMetadata.readback)
+    {
+        Interface->u.SetVidMemMetadata.ts_fd            = nodeObj->metadata.ts_fd;
+        Interface->u.SetVidMemMetadata.fc_enabled       = nodeObj->metadata.fc_enabled;
+        Interface->u.SetVidMemMetadata.fc_value         = nodeObj->metadata.fc_value;
+        Interface->u.SetVidMemMetadata.fc_value_upper   = nodeObj->metadata.fc_value_upper;
+        Interface->u.SetVidMemMetadata.compressed       = nodeObj->metadata.compressed;
+        Interface->u.SetVidMemMetadata.compress_format  = nodeObj->metadata.compress_format;
+    }
+    else
+    {
+#ifdef gcdANDROID
         if (nodeObj->metadata.ts_address == 0 && nodeObj->tsNode != NULL)
         {
-            gctUINT32 Address = 0;
-            gctUINT32 Gid = 0;
-            gctUINT64 PhysicalAddress = 0;
+            gctUINT32 PhysicalAddress = 0;
 
-            gcmkONERROR(gckVIDMEM_Lock(Kernel,
-                    nodeObj->tsNode,
-                    gcvFALSE,
-                    &Address,
-                    &Gid,
-                    &PhysicalAddress));
+            /* Lock for GPU address. */
+            gcmkONERROR(gckVIDMEM_NODE_Lock(Kernel, nodeObj->tsNode, &PhysicalAddress));
 
             nodeObj->metadata.ts_address = (
                     PhysicalAddress + Kernel->hardware->baseAddress);
-            gcmkONERROR(gckVIDMEM_Unlock(Kernel,
-                    nodeObj->tsNode,
-                    gcvSURF_TYPE_UNKNOWN,
-                    gcvNULL));
+
+            gcmkONERROR(gckVIDMEM_NODE_Unlock(Kernel, nodeObj->tsNode, ProcessID, gcvNULL));
         }
 #else
         nodeObj->metadata.ts_fd             = Interface->u.SetVidMemMetadata.ts_fd;
@@ -1746,7 +1976,7 @@ OnError:
 #else
 
 gceSTATUS
-gckKERNEL_SetVidMemMetadata(
+_SetVidMemMetadata(
     IN gckKERNEL Kernel,
     IN gctUINT32 ProcessID,
     INOUT gcsHAL_INTERFACE * Interface
@@ -1757,95 +1987,35 @@ gckKERNEL_SetVidMemMetadata(
 }
 #endif
 
-/*******************************************************************************
-**
-**  gckKERNEL_QueryVidMemPoolNodes
-**
-**  Loop all databases to query used memory nodes of a specific pool.
-**
-**  INPUT:
-**
-**  Pool            The memory pool for query.
-
-**  TotalSize       Total size of the used contiguous memory.
-**
-**  MemoryBlocks    Used contiguous memory block info.
-**
-**  NumMaxBlock     The count of memory blocks array provided by the caller.
-**
-**  NumBlocks       The actual number of memory blocks returned.
-**
-**  OUTPUT:
-**
-**      Error status. Should always be gcvSTATUS_SUCCESS since a query should always succeed.
-*/
-gceSTATUS
-gckKERNEL_QueryVidMemPoolNodes(
-    gckKERNEL            Kernel,
-    gcePOOL              Pool,
-    gctUINT32          * TotalSize,
-    gcsContiguousBlock * MemoryBlocks,
-    gctUINT32            NumMaxBlocks,
-    gctUINT32          * NumBlocks
+static gceSTATUS
+_GetVideoMemoryFd(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
+    IN gcsHAL_INTERFACE * Interface
     )
 {
-    gceSTATUS status = gcvSTATUS_OK;
-    gctINT i;
-    gctINT bcount;
-    gctUINT32 num_blocks = 0;
-    gctSIZE_T total_size = 0;
-    gckVIDMEM memory;
-    gcuVIDMEM_NODE_PTR nodes, node;
-
-    do
-    {
-        /* Get the heap and nodes. */
-        status = gckKERNEL_GetVideoMemoryPool(Kernel, Pool, &memory);
-        if (status != gcvSTATUS_OK)
-            break;
-
-        status = gckVIDMEM_QueryNodes(Kernel, Pool, &bcount, &nodes);
-        if (status != gcvSTATUS_OK)
-            break;
-
-        /* Iterate all nodes. */
-        for (i = 0; i < bcount; i++)
-        {
-            node = nodes[i].VidMem.next;
-            do
-            {
-                if (node == gcvNULL)
-                {
-                    break;
-                }
-
-                /* Is it in the "free" list? */
-                if (node->VidMem.nextFree == gcvNULL)
-                {
-                    if (num_blocks < NumMaxBlocks)
-                    {
-                        MemoryBlocks[num_blocks].ptr = (gctUINT32)node->VidMem.offset + memory->baseAddress;
-                        MemoryBlocks[num_blocks].size = node->VidMem.bytes;
-                    }
-                    total_size += node->VidMem.bytes;
-                    num_blocks++;
-                }
-
-                node = node->VidMem.next;
-            } while (node != &nodes[i]);
-        }
-    }
-    while (gcvFALSE);
+    gceSTATUS status;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
 
-    if (TotalSize != gcvNULL)
-        *TotalSize = (gctUINT32)total_size;
+    gcmkONERROR(
+        gckVIDMEM_HANDLE_Lookup(Kernel,
+                                ProcessID,
+                                Interface->u.GetVideoMemoryFd.handle,
+                                &nodeObject));
 
-    if (NumBlocks != gcvNULL)
-        *NumBlocks = num_blocks;
+    gcmkONERROR(
+        gckVIDMEM_NODE_GetFd(Kernel,
+                             nodeObject,
+                             &Interface->u.GetVideoMemoryFd.fd));
 
+    /* No need to add it to processDB because OS will release all fds when
+    ** process quits.
+    */
+OnError:
     return status;
 }
 
+
 gceSTATUS
 gckKERNEL_QueryDatabase(
     IN gckKERNEL Kernel,
@@ -1856,9 +2026,8 @@ gckKERNEL_QueryDatabase(
     gceSTATUS status;
     gctINT i;
 
-    gceDATABASE_TYPE type[3] = {
+    gceDATABASE_TYPE type[2] = {
         gcvDB_VIDEO_MEMORY | (gcvPOOL_SYSTEM << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
-        gcvDB_VIDEO_MEMORY | (gcvPOOL_CONTIGUOUS << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
         gcvDB_VIDEO_MEMORY | (gcvPOOL_VIRTUAL << gcdDB_VIDEO_MEMORY_POOL_SHIFT),
     };
 
@@ -1880,14 +2049,6 @@ gckKERNEL_QueryDatabase(
                                  gcvDB_NON_PAGED,
                                  &Interface->u.Database.nonPaged));
 
-    /* Query contiguous memory. */
-    gcmkONERROR(
-        gckKERNEL_QueryProcessDB(Kernel,
-                                 Interface->u.Database.processID,
-                                 !Interface->u.Database.validProcessID,
-                                 gcvDB_CONTIGUOUS,
-                                 &Interface->u.Database.contiguous));
-
     /* Query GPU idle time. */
     gcmkONERROR(
         gckKERNEL_QueryProcessDB(Kernel,
@@ -1895,7 +2056,7 @@ gckKERNEL_QueryDatabase(
                                  !Interface->u.Database.validProcessID,
                                  gcvDB_IDLE,
                                  &Interface->u.Database.gpuIdle));
-    for (i = 0; i < 3; i++)
+    for (i = 0; i < 2; i++)
     {
         /* Query each video memory pool. */
         gcmkONERROR(
@@ -1929,12 +2090,12 @@ gckKERNEL_ConfigPowerManagement(
 
     gcmkHEADER();
 
-    gcmkONERROR(gckHARDWARE_SetPowerManagement(Kernel->hardware, enable));
+    gcmkONERROR(gckHARDWARE_EnablePowerManagement(Kernel->hardware, enable));
 
     if (enable == gcvFALSE)
     {
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(Kernel->hardware, gcvPOWER_ON));
+            gckHARDWARE_SetPowerState(Kernel->hardware, gcvPOWER_ON));
     }
 
     gcmkFOOTER_NO();
@@ -1945,6 +2106,7 @@ OnError:
     return status;
 }
 
+
 static gceSTATUS
 gckKERNEL_CacheOperation(
     IN gckKERNEL Kernel,
@@ -1958,6 +2120,7 @@ gckKERNEL_CacheOperation(
     gceSTATUS status;
     gckVIDMEM_NODE nodeObject = gcvNULL;
     gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
     void *memHandle;
 
     gcmkHEADER_ARG("Kernel=%p pid=%u Node=%u op=%d Logical=%p Bytes=0x%lx",
@@ -1970,7 +2133,9 @@ gckKERNEL_CacheOperation(
 
     node = nodeObject->node;
 
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+    vidMemBlock = node->VirtualChunk.parent;
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
         static gctBOOL printed;
 
@@ -1983,6 +2148,10 @@ gckKERNEL_CacheOperation(
         gcmkFOOTER_NO();
         return gcvSTATUS_OK;
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        memHandle = vidMemBlock->physical;
+    }
     else
     {
         memHandle = node->Virtual.physical;
@@ -1995,7 +2164,7 @@ gckKERNEL_CacheOperation(
         status = gckOS_CacheFlush(Kernel->os,
                                   ProcessID,
                                   memHandle,
-                                  gcvINVALID_PHYSICAL_ADDRESS,
+                                  0,
                                   Logical,
                                   Bytes);
         break;
@@ -2004,7 +2173,7 @@ gckKERNEL_CacheOperation(
         status = gckOS_CacheClean(Kernel->os,
                                   ProcessID,
                                   memHandle,
-                                  gcvINVALID_PHYSICAL_ADDRESS,
+                                  0,
                                   Logical,
                                   Bytes);
         break;
@@ -2013,7 +2182,7 @@ gckKERNEL_CacheOperation(
         status = gckOS_CacheInvalidate(Kernel->os,
                                        ProcessID,
                                        memHandle,
-                                       gcvINVALID_PHYSICAL_ADDRESS,
+                                       0,
                                        Logical,
                                        Bytes);
         break;
@@ -2032,24 +2201,29 @@ OnError:
     return status;
 }
 
-gceSTATUS
-gckKERNEL_WaitFence(
+static gceSTATUS
+_WaitFence(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
-    IN gctUINT32 TimeOut
+    IN gctUINT32 ProcessID,
+    IN gcsHAL_INTERFACE * Interface
     )
 {
     gceSTATUS status;
     gckVIDMEM_NODE node;
-    gctUINT32 processID;
     gckCOMMAND command = Kernel->command;
-    gckASYNC_COMMAND asyncCommand = Kernel->asyncCommand;
+    gckCOMMAND asyncCommand = Kernel->asyncCommand;
     gckFENCE fence = gcvNULL;
     gctUINT i;
 
-    gckOS_GetProcessID(&processID);
+    gcmkASSERT(command != gcvNULL);
+
+    gcmkONERROR(
+        gckVIDMEM_HANDLE_Lookup(Kernel,
+                                ProcessID,
+                                Interface->u.WaitFence.handle,
+                                &node));
 
-    gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+    gcmkONERROR(gckVIDMEM_NODE_Reference(Kernel, node));
 
     /* Wait for fence of all engines. */
     for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
@@ -2065,23 +2239,9 @@ gckKERNEL_WaitFence(
             fence = asyncCommand->fence;
         }
 
-#if USE_KERNEL_VIRTUAL_BUFFERS
-        if (Kernel->virtualCommandBuffer)
-        {
-            gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR) fence->physical;
-
-            fence->physHandle = commandBuffer->virtualBuffer.physical;
-        }
-        else
-#endif
-        {
-            fence->physHandle = fence->physical;
-        }
-
-        gcmkONERROR(gckOS_CacheInvalidate(
-            Kernel->os,
-            0,
-            fence->physHandle,
+        gcmkONERROR(gckVIDMEM_NODE_InvalidateCache(
+            Kernel,
+            fence->videoMem,
             0,
             fence->logical,
             8
@@ -2107,7 +2267,12 @@ gckKERNEL_WaitFence(
             gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, &fence->mutex));
 
             /* Wait. */
-            status = gckOS_WaitSignal(Kernel->os, sync->signal, gcvTRUE, TimeOut);
+            status = gckOS_WaitSignal(
+                Kernel->os,
+                sync->signal,
+                gcvTRUE,
+                Interface->u.WaitFence.timeOut
+                );
 
             gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, &fence->mutex, gcvINFINITE));
 
@@ -2127,61 +2292,278 @@ OnError:
     return status;
 }
 
-#ifdef __linux__
-
-typedef struct _gcsGRRAPHIC_BUFFER_PARCLE
+static gceSTATUS
+_Commit(
+    IN gckDEVICE Device,
+    IN gceHARDWARE_TYPE HwType,
+    IN gceENGINE Engine,
+    IN gctUINT32 ProcessId,
+    IN OUT gcsHAL_COMMIT * Commit
+    )
 {
-    gcsFDPRIVATE base;
+    gceSTATUS status;
+    gcsHAL_SUBCOMMIT *subCommit = &Commit->subCommit;
+    gcsHAL_SUBCOMMIT _subCommit;
+    gctPOINTER userPtr = gcvNULL;
+    gctBOOL needCopy = gcvFALSE;
     gckKERNEL kernel;
 
-    gckVIDMEM_NODE node[3];
-    gctSHBUF  shBuf;
-    gctINT32  signal;
-}
-gcsGRAPHIC_BUFFER_PARCLE;
-
-static void
-_ReleaseGraphicBuffer(
-    gckKERNEL Kernel,
-    gcsGRAPHIC_BUFFER_PARCLE * Parcle
-    )
-{
-    gctUINT i;
+    gcmkVERIFY_OK(gckOS_QueryNeedCopy(Device->os, ProcessId, &needCopy));
 
-    for (i = 0; i < 3; i++)
+    do
     {
-        if (Parcle->node[i])
+        gckCOMMAND command;
+        gckEVENT eventObj;
+        gctUINT64 next;
+
+        /* Skip the first nested sub-commit struct. */
+        if (userPtr)
         {
-            gckVIDMEM_NODE_Dereference(Kernel, Parcle->node[i]);
-        }
-    }
+            /* Copy/map sub-commit from user. */
+            if (needCopy)
+            {
+                subCommit = &_subCommit;
+
+                status = gckOS_CopyFromUserData(
+                    Device->os,
+                    subCommit,
+                    userPtr,
+                    gcmSIZEOF(gcsHAL_SUBCOMMIT)
+                    );
+            }
+            else
+            {
+                status = gckOS_MapUserPointer(
+                    Device->os,
+                    userPtr,
+                    gcmSIZEOF(gcsHAL_SUBCOMMIT),
+                    (gctPOINTER *)&subCommit
+                    );
+            }
 
-    if (Parcle->shBuf)
-    {
-        gckKERNEL_DestroyShBuffer(Kernel, Parcle->shBuf);
-    }
+            if (gcmIS_ERROR(status))
+            {
+                userPtr = gcvNULL;
 
-    if (Parcle->signal)
-    {
-        gckOS_DestroyUserSignal(Kernel->os, Parcle->signal);
-    }
+                gcmkONERROR(status);
+            }
+        }
 
-    gcmkOS_SAFE_FREE(Kernel->os, Parcle);
-}
+        if (subCommit->coreId >= gcvCORE_COUNT)
+        {
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+        }
 
-static gctINT
-_FdReleaseGraphicBuffer(
-    gcsFDPRIVATE_PTR Private
-    )
-{
-    gcsGRAPHIC_BUFFER_PARCLE * parcle = (gcsGRAPHIC_BUFFER_PARCLE *) Private;
+        /* Determine the objects. */
+        kernel = Device->map[HwType].kernels[subCommit->coreId];
+        if (Engine == gcvENGINE_BLT)
+        {
+            command  = kernel->asyncCommand;
+            eventObj = kernel->asyncEvent;
+        }
+        else
+        {
+            command  = kernel->command;
+            eventObj = kernel->eventObj;
+        }
 
-    _ReleaseGraphicBuffer(parcle->kernel, parcle);
-    return 0;
-}
+        gcmkONERROR(gckOS_Broadcast(kernel->os,
+                                    kernel->hardware,
+                                    gcvBROADCAST_GPU_COMMIT));
 
-static gceSTATUS
-_GetGraphicBufferFd(
+        {
+            /* Commit command buffers. */
+            status = gckCOMMAND_Commit(command,
+                                       subCommit,
+                                       ProcessId,
+                                       Commit->shared,
+                                       &Commit->commitStamp);
+
+            if (status != gcvSTATUS_INTERRUPTED)
+            {
+                gcmkONERROR(status);
+            }
+
+            /* Commit events. */
+            status = gckEVENT_Commit(
+                eventObj,
+                gcmUINT64_TO_PTR(subCommit->queue),
+                kernel->hardware->options.powerManagement
+                );
+
+            if (status != gcvSTATUS_INTERRUPTED)
+            {
+                gcmkONERROR(status);
+            }
+        }
+
+        next = subCommit->next;
+
+        /* Unmap user pointer if mapped. */
+        if (!needCopy && userPtr)
+        {
+            gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+                Device->os,
+                userPtr,
+                gcmSIZEOF(gcsHAL_SUBCOMMIT),
+                subCommit
+                ));
+        }
+
+        /* Advance to next sub-commit from user. */
+        userPtr = gcmUINT64_TO_PTR(next);
+    }
+    while (userPtr);
+
+    subCommit = &Commit->subCommit;
+    userPtr = gcvNULL;
+    kernel = Device->map[HwType].kernels[subCommit->coreId];
+
+    if (!kernel->hardware->options.gpuProfiler || !kernel->profileEnable)
+    {
+        return gcvSTATUS_OK;
+    }
+
+    do
+    {
+        gctUINT64 next;
+
+        /* Skip the first nested sub-commit struct. */
+        if (userPtr)
+        {
+            /* Copy/map sub-commit from user. */
+            if (needCopy)
+            {
+                subCommit = &_subCommit;
+
+                status = gckOS_CopyFromUserData(
+                    Device->os,
+                    subCommit,
+                    userPtr,
+                    gcmSIZEOF(gcsHAL_SUBCOMMIT)
+                    );
+            }
+            else
+            {
+                status = gckOS_MapUserPointer(
+                    Device->os,
+                    userPtr,
+                    gcmSIZEOF(gcsHAL_SUBCOMMIT),
+                    (gctPOINTER *)&subCommit
+                    );
+            }
+
+            if (gcmIS_ERROR(status))
+            {
+                userPtr = gcvNULL;
+
+                gcmkONERROR(status);
+            }
+        }
+
+        kernel = Device->map[HwType].kernels[subCommit->coreId];
+
+        if ((kernel->hardware->options.gpuProfiler == gcvTRUE) &&
+            (kernel->profileEnable == gcvTRUE))
+        {
+            gcmkONERROR(gckCOMMAND_Stall(kernel->command, gcvTRUE));
+
+            if (kernel->command->currContext)
+            {
+                gcmkONERROR(gckHARDWARE_UpdateContextProfile(
+                            kernel->hardware,
+                            kernel->command->currContext));
+            }
+        }
+
+        next = subCommit->next;
+
+        /* Unmap user pointer if mapped. */
+        if (!needCopy && userPtr)
+        {
+            gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+                Device->os,
+                userPtr,
+                gcmSIZEOF(gcsHAL_SUBCOMMIT),
+                subCommit
+                ));
+        }
+
+        /* Advance to next sub-commit from user. */
+        userPtr = gcmUINT64_TO_PTR(next);
+    }
+    while (userPtr);
+
+    return gcvSTATUS_OK;
+
+OnError:
+    if (!needCopy && userPtr)
+    {
+        gckOS_UnmapUserPointer(
+            Device->os,
+            userPtr,
+            gcmSIZEOF(gcsHAL_SUBCOMMIT),
+            subCommit
+            );
+    }
+
+    return status;
+}
+
+#ifdef __linux__
+typedef struct _gcsGRRAPHIC_BUFFER_PARCLE
+{
+    gcsFDPRIVATE base;
+    gckKERNEL kernel;
+
+    gckVIDMEM_NODE node[3];
+    gctSHBUF  shBuf;
+    gctINT32  signal;
+}
+gcsGRAPHIC_BUFFER_PARCLE;
+
+static void
+_ReleaseGraphicBuffer(
+    gckKERNEL Kernel,
+    gcsGRAPHIC_BUFFER_PARCLE * Parcle
+    )
+{
+    gctUINT i;
+
+    for (i = 0; i < 3; i++)
+    {
+        if (Parcle->node[i])
+        {
+            gckVIDMEM_NODE_Dereference(Kernel, Parcle->node[i]);
+        }
+    }
+
+    if (Parcle->shBuf)
+    {
+        gckKERNEL_DestroyShBuffer(Kernel, Parcle->shBuf);
+    }
+
+    if (Parcle->signal)
+    {
+        gckOS_DestroyUserSignal(Kernel->os, Parcle->signal);
+    }
+
+    gcmkOS_SAFE_FREE(Kernel->os, Parcle);
+}
+
+static gctINT
+_FdReleaseGraphicBuffer(
+    gcsFDPRIVATE_PTR Private
+    )
+{
+    gcsGRAPHIC_BUFFER_PARCLE * parcle = (gcsGRAPHIC_BUFFER_PARCLE *) Private;
+
+    _ReleaseGraphicBuffer(parcle->kernel, parcle);
+    return 0;
+}
+
+static gceSTATUS
+_GetGraphicBufferFd(
     IN gckKERNEL Kernel,
     IN gctUINT32 ProcessID,
     IN gctUINT32 Node[3],
@@ -2205,13 +2587,16 @@ _GetGraphicBufferFd(
     parcle->base.release = _FdReleaseGraphicBuffer;
     parcle->kernel = Kernel;
 
-    for (i = 0; i < 3; i++)
+    for (i = 0; i < 3 && Node[i] != 0; i++)
     {
-        if (Node[i] != 0)
-        {
-            gcmkONERROR(
-                gckVIDMEM_HANDLE_LookupAndReference(Kernel, Node[i], &parcle->node[i]));
-        }
+        gckVIDMEM_NODE nodeObject = gcvNULL;
+
+        gcmkONERROR(
+            gckVIDMEM_HANDLE_Lookup(Kernel, ProcessID, Node[i], &nodeObject));
+
+        gcmkONERROR(gckVIDMEM_NODE_Reference(Kernel, nodeObject));
+
+        parcle->node[i] = nodeObject;
     }
 
     if (ShBuf)
@@ -2259,9 +2644,6 @@ OnError:
 **      gckKERNEL Kernel
 **          Pointer to an gckKERNEL object.
 **
-**      gctBOOL FromUser
-**          whether the call is from the user space.
-**
 **      gcsHAL_INTERFACE * Interface
 **          Pointer to a gcsHAL_INTERFACE structure that defines the command to
 **          be dispatched.
@@ -2276,7 +2658,6 @@ gceSTATUS
 gckKERNEL_Dispatch(
     IN gckKERNEL Kernel,
     IN gckDEVICE Device,
-    IN gctBOOL FromUser,
     IN OUT gcsHAL_INTERFACE * Interface
     )
 {
@@ -2289,20 +2670,14 @@ gckKERNEL_Dispatch(
 #endif
     gckKERNEL kernel = Kernel;
     gctUINT32 processID;
-#if gcdSECURE_USER
-    gcskSECURE_CACHE_PTR cache;
-    gctPOINTER logical;
-#endif
 #if !USE_NEW_LINUX_SIGNAL
     gctSIGNAL   signal;
 #endif
-    gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
 
     gctBOOL powerMutexAcquired = gcvFALSE;
     gctBOOL commitMutexAcquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%x FromUser=%d Interface=0x%x",
-                   Kernel, FromUser, Interface);
+    gcmkHEADER_ARG("Kernel=%p Interface=%p", Kernel, Interface);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -2312,6 +2687,9 @@ gckKERNEL_Dispatch(
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
                    "Dispatching command %d (%s)",
                    Interface->command, _DispatchText[Interface->command]);
+
+    gcmSTATIC_ASSERT(gcvHAL_DESTROY_MMU == gcmCOUNTOF(_DispatchText) - 1,
+                     "DispatchText array does not match command codes");
 #endif
 #if QNX_SINGLE_THREADED_DEBUGGING
     gckOS_AcquireMutex(Kernel->os, Kernel->debugMutex, gcvINFINITE);
@@ -2320,21 +2698,17 @@ gckKERNEL_Dispatch(
     /* Get the current process ID. */
     gcmkONERROR(gckOS_GetProcessID(&processID));
 
-#if gcdSECURE_USER
-    gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
-#endif
-
     /* Dispatch on command. */
     switch (Interface->command)
     {
     case gcvHAL_GET_BASE_ADDRESS:
         /* Get base address. */
         Interface->u.GetBaseAddress.baseAddress = Kernel->hardware->baseAddress;
-        Interface->u.GetBaseAddress.flatMappingRangeCount = Kernel->mmu->flatMappingRangeCount;
-        if (Kernel->mmu->flatMappingRangeCount)
+        Interface->u.GetBaseAddress.flatMappingRangeCount = Kernel->mmu->gpuPhysicalRangeCount;
+        if (Kernel->mmu->gpuPhysicalRangeCount)
         {
-            gckOS_MemCopy(Interface->u.GetBaseAddress.flatMappingRanges, Kernel->mmu->flatMappingRanges,
-                gcmSIZEOF(gcsFLAT_MAPPING_RANGE) * Kernel->mmu->flatMappingRangeCount);
+            gckOS_MemCopy(Interface->u.GetBaseAddress.flatMappingRanges, Kernel->mmu->gpuPhysicalRanges,
+                gcmSIZEOF(gcsFLAT_MAPPING_RANGE) * Kernel->mmu->gpuPhysicalRangeCount);
         }
         break;
 
@@ -2361,7 +2735,7 @@ gckKERNEL_Dispatch(
         break;
 
     case gcvHAL_MAP_MEMORY:
-        physical = gcmINT2PTR(Interface->u.MapMemory.physical);
+        physical = gcmINT2PTR(Interface->u.MapMemory.physName);
 
         /* Map memory. */
         gcmkONERROR(
@@ -2381,7 +2755,7 @@ gckKERNEL_Dispatch(
         break;
 
     case gcvHAL_UNMAP_MEMORY:
-        physical = gcmINT2PTR(Interface->u.UnmapMemory.physical);
+        physical = gcmINT2PTR(Interface->u.UnmapMemory.physName);
 
         gcmkVERIFY_OK(
             gckKERNEL_RemoveProcessDB(Kernel,
@@ -2404,7 +2778,7 @@ gckKERNEL_Dispatch(
         gcmkONERROR(
             gckOS_AllocateNonPagedMemory(
                 Kernel->os,
-                FromUser,
+                gcvTRUE,
                 gcvALLOC_FLAG_CONTIGUOUS,
                 &bytes,
                 &physical,
@@ -2412,153 +2786,42 @@ gckKERNEL_Dispatch(
 
         Interface->u.AllocateNonPagedMemory.bytes    = bytes;
         Interface->u.AllocateNonPagedMemory.logical  = gcmPTR_TO_UINT64(logical);
-        Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
+        Interface->u.AllocateNonPagedMemory.physName = gcmPTR_TO_NAME(physical);
 
         gcmkVERIFY_OK(
             gckKERNEL_AddProcessDB(Kernel,
                                    processID, gcvDB_NON_PAGED,
                                    logical,
-                                   gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical),
-                                   bytes));
-        break;
-
-    case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER:
-        bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes;
-
-        gcmkONERROR(
-            gckKERNEL_AllocateVirtualCommandBuffer(
-                Kernel,
-                FromUser,
-                &bytes,
-                &physical,
-                &logical));
-
-        Interface->u.AllocateVirtualCommandBuffer.bytes    = bytes;
-        Interface->u.AllocateVirtualCommandBuffer.logical  = gcmPTR_TO_UINT64(logical);
-        Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical);
-
-        gcmkVERIFY_OK(
-            gckKERNEL_AddProcessDB(Kernel,
-                                   processID, gcvDB_COMMAND_BUFFER,
-                                   logical,
-                                   gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical),
+                                   gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physName),
                                    bytes));
         break;
 
     case gcvHAL_FREE_NON_PAGED_MEMORY:
-        physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical);
+        physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physName);
 
         gcmkVERIFY_OK(
             gckKERNEL_RemoveProcessDB(Kernel,
                                       processID, gcvDB_NON_PAGED,
                                       gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
 
-        /* Unmap user logical out of physical memory first. */
-        gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
-                                           physical,
-                                           (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
-                                           gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
-
         /* Free non-paged memory. */
         gcmkONERROR(
             gckOS_FreeNonPagedMemory(Kernel->os,
-                                     (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
                                      physical,
-                                     gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
-
-#if gcdSECURE_USER
-        gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
-            Kernel,
-            cache,
-            gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
-            (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes));
-#endif
-
-        gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical);
-        break;
-
-    case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
-        bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes;
-
-        /* Allocate contiguous memory. */
-        gcmkONERROR(gckOS_AllocateContiguous(
-            Kernel->os,
-            FromUser,
-            &bytes,
-            &physical,
-            &logical));
-
-        Interface->u.AllocateContiguousMemory.bytes    = bytes;
-        Interface->u.AllocateContiguousMemory.logical  = gcmPTR_TO_UINT64(logical);
-        Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
-
-        gcmkONERROR(gckHARDWARE_ConvertLogical(
-            Kernel->hardware,
-            logical,
-            gcvTRUE,
-            &Interface->u.AllocateContiguousMemory.address));
-
-        gcmkVERIFY_OK(gckKERNEL_AddProcessDB(
-            Kernel,
-            processID, gcvDB_CONTIGUOUS,
-            logical,
-            gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical),
-            bytes));
-        break;
-
-    case gcvHAL_FREE_CONTIGUOUS_MEMORY:
-        physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical);
-
-        gcmkVERIFY_OK(
-            gckKERNEL_RemoveProcessDB(Kernel,
-                                      processID, gcvDB_CONTIGUOUS,
-                                      gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
-
-        /* Unmap user logical out of physical memory first. */
-        gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os,
-                                           physical,
-                                           (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
-                                           gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
-
-        /* Free contiguous memory. */
-        gcmkONERROR(
-            gckOS_FreeContiguous(Kernel->os,
-                                 physical,
-                                 gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
-                                 (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
-
-#if gcdSECURE_USER
-        gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
-            Kernel,
-            cache,
-            gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical),
-            (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes));
-#endif
-
-        gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical);
-        break;
-
-    case gcvHAL_ALLOCATE_VIDEO_MEMORY:
-
-        gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
+                                     gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical),
+                                     (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes));
 
+        gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physName);
         break;
 
     case gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY:
         /* Allocate memory. */
-        gcmkONERROR(
-            gckKERNEL_AllocateLinearMemory(Kernel, processID,
-                            &Interface->u.AllocateLinearVideoMemory.pool,
-                            Interface->u.AllocateLinearVideoMemory.bytes,
-                            Interface->u.AllocateLinearVideoMemory.alignment,
-                            Interface->u.AllocateLinearVideoMemory.type,
-                            Interface->u.AllocateLinearVideoMemory.flag,
-                            &Interface->u.AllocateLinearVideoMemory.node));
+        gcmkONERROR(_AllocateLinearMemory(Kernel, processID, Interface));
         break;
 
     case gcvHAL_RELEASE_VIDEO_MEMORY:
         /* Release video memory. */
-        gcmkONERROR(gckKERNEL_ReleaseVideoMemory(
+        gcmkONERROR(_ReleaseVideoMemory(
             Kernel, processID,
             (gctUINT32)Interface->u.ReleaseVideoMemory.node
             ));
@@ -2566,17 +2829,18 @@ gckKERNEL_Dispatch(
 
     case gcvHAL_LOCK_VIDEO_MEMORY:
         /* Lock video memory. */
-        gcmkONERROR(gckKERNEL_LockVideoMemory(Kernel, Kernel->core, processID, FromUser, Interface));
+        gcmkONERROR(_LockVideoMemory(Kernel, Kernel->core, processID, Interface));
         break;
 
     case gcvHAL_UNLOCK_VIDEO_MEMORY:
         /* Unlock video memory. */
-        gcmkONERROR(gckKERNEL_UnlockVideoMemory(Kernel, processID, Interface));
+        gcmkONERROR(_UnlockVideoMemory(Kernel, processID, Interface));
         break;
 
     case gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY:
-        gcmkERR_BREAK(gckKERNEL_BottomHalfUnlockVideoMemory(Kernel, processID,
-                                                            Interface->u.BottomHalfUnlockVideoMemory.node));
+        gcmkERR_BREAK(_BottomHalfUnlockVideoMemory(Kernel, processID,
+                                                   Interface->u.BottomHalfUnlockVideoMemory.type,
+                                                   Interface->u.BottomHalfUnlockVideoMemory.node));
         break;
 
     case gcvHAL_EVENT_COMMIT:
@@ -2617,161 +2881,25 @@ gckKERNEL_Dispatch(
         if (!Interface->commitMutex)
         {
             gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
-                Kernel->device->commitMutex,
+                Device->commitMutex,
                 gcvINFINITE
                 ));
             commitMutexAcquired = gcvTRUE;
         }
 
-        /* Commit a command and context buffer. */
-        if (Interface->engine == gcvENGINE_BLT)
-        {
-            gctUINT64 *commandBuffers = gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer);
-
-            if (!gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_ASYNC_BLIT))
-            {
-                gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
-            }
-
-            gcmkONERROR(gckASYNC_COMMAND_Commit(
-                Kernel->asyncCommand,
-                gcmUINT64_TO_PTR(commandBuffers[0]),
-                gcmUINT64_TO_PTR(Interface->u.Commit.queue)
-                ));
-
-            gcmkONERROR(gckEVENT_Commit(
-                Kernel->asyncEvent,
-                gcmUINT64_TO_PTR(Interface->u.Commit.queue),
-                gcvFALSE
-                ));
-        }
-        else
-        {
-            gctUINT32 i;
-
-            if (Interface->u.Commit.count > 1 && Interface->engine == gcvENGINE_RENDER)
-            {
-                for (i = 0; i < Interface->u.Commit.count; i++)
-                {
-                    gceHARDWARE_TYPE type = Interface->hardwareType;
-                    gckKERNEL kernel = Device->map[type].kernels[i];
-
-                    gcmkONERROR(gckOS_Broadcast(kernel->os,
-                                                kernel->hardware,
-                                                gcvBROADCAST_GPU_COMMIT));
-                }
-            }
-
-            status = gckCOMMAND_Commit(Kernel->command,
-                Interface->u.Commit.contexts[0] ?
-                gcmNAME_TO_PTR(Interface->u.Commit.contexts[0]) : gcvNULL,
-                gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffers[0]),
-                gcmUINT64_TO_PTR(Interface->u.Commit.deltas[0]),
-                processID,
-                Interface->u.Commit.shared,
-                Interface->u.Commit.index,
-                &Interface->u.Commit.commitStamp,
-                &Interface->u.Commit.contextSwitched
-                );
-
-            if (status != gcvSTATUS_INTERRUPTED)
-            {
-                gcmkONERROR(status);
-            }
-
-            /* Force an event if powerManagement is on. */
-            status = gckEVENT_Commit(Kernel->eventObj,
-                                     gcmUINT64_TO_PTR(Interface->u.Commit.queue),
-                                     Kernel->hardware->options.powerManagement);
-
-            if (status != gcvSTATUS_INTERRUPTED)
-            {
-                gcmkONERROR(status);
-            }
-
-            if (Interface->u.Commit.count > 1 && Interface->engine == gcvENGINE_RENDER)
-            {
-                for (i = 1; i < Interface->u.Commit.count; i++)
-                {
-                    gceHARDWARE_TYPE type = Interface->hardwareType;
-                    gckKERNEL kernel = Device->map[type].kernels[i];
-
-                    status = gckCOMMAND_Commit(kernel->command,
-                        Interface->u.Commit.contexts[i] ?
-                        gcmNAME_TO_PTR(Interface->u.Commit.contexts[i]) : gcvNULL,
-                        Interface->u.Commit.commandBuffers[i] ?
-                        gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffers[i]) : gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffers[0]),
-                        gcmUINT64_TO_PTR(Interface->u.Commit.deltas[i]),
-                        processID,
-                        Interface->u.Commit.shared,
-                        Interface->u.Commit.commandBuffers[i] ?
-                        Interface->u.Commit.index : i,
-                        &Interface->u.Commit.commitStamp,
-                        &Interface->u.Commit.contextSwitched
-                        );
-
-                    if (status != gcvSTATUS_INTERRUPTED)
-                    {
-                        gcmkONERROR(status);
-                    }
-
-                    /* Force an event if powerManagement is on. */
-                    status = gckEVENT_Commit(kernel->eventObj,
-                                             gcvNULL,
-                                             kernel->hardware->options.powerManagement);
-
-                    if (status != gcvSTATUS_INTERRUPTED)
-                    {
-                        gcmkONERROR(status);
-                    }
-                }
-            }
-
-            for (i = 0; i < Interface->u.Commit.count; i++)
-            {
-                gceHARDWARE_TYPE type = Interface->hardwareType;
-                gckKERNEL kernel = Device->map[type].kernels[i];
-
-                if  ((kernel->hardware->options.gpuProfiler == gcvTRUE) &&
-                     (kernel->profileEnable == gcvTRUE))
-                {
-                    gcmkONERROR(gckCOMMAND_Stall(kernel->command, gcvTRUE));
-
-                    if (kernel->command->currContext)
-                    {
-                        gcmkONERROR(gckHARDWARE_UpdateContextProfile(
-                                    kernel->hardware,
-                                    kernel->command->currContext));
-                    }
-                }
-            }
-        }
+        gcmkONERROR(_Commit(Device,
+                            Kernel->hardware->type,
+                            Interface->engine,
+                            processID,
+                            &Interface->u.Commit));
 
         if (!Interface->commitMutex)
         {
-            gcmkONERROR(gckOS_ReleaseMutex(Kernel->os, Kernel->device->commitMutex));
+            gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Device->commitMutex));
             commitMutexAcquired = gcvFALSE;
         }
         break;
 
-    case gcvHAL_STALL:
-        /* Stall the command queue. */
-        gcmkONERROR(gckCOMMAND_Stall(Kernel->command, gcvFALSE));
-
-        break;
-
-    case gcvHAL_MAP_USER_MEMORY:
-
-        gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
-
-        break;
-
-    case gcvHAL_UNMAP_USER_MEMORY:
-
-        gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
-
-        break;
-
 #if !USE_NEW_LINUX_SIGNAL
     case gcvHAL_USER_SIGNAL:
         /* Dispatch depends on the user signal subcommands. */
@@ -2856,9 +2984,8 @@ gckKERNEL_Dispatch(
     case gcvHAL_SET_POWER_MANAGEMENT_STATE:
         /* Set the power management state. */
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(
-                Kernel->hardware,
-                Interface->u.SetPowerManagement.state));
+            gckHARDWARE_SetPowerState(Kernel->hardware,
+                                      Interface->u.SetPowerManagement.state));
         break;
 
     case gcvHAL_QUERY_POWER_MANAGEMENT_STATE:
@@ -2866,7 +2993,7 @@ gckKERNEL_Dispatch(
         Interface->u.QueryPowerManagement.isIdle = gcvFALSE;
 
         /* Query the power management state. */
-        gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+        gcmkONERROR(gckHARDWARE_QueryPowerState(
             Kernel->hardware,
             &Interface->u.QueryPowerManagement.state));
 
@@ -2883,7 +3010,7 @@ gckKERNEL_Dispatch(
 
             gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE));
             powerMutexAcquired = gcvTRUE;
-            gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
+            gcmkONERROR(gckHARDWARE_QueryPowerState(Kernel->hardware,
                                                               &power));
             if (power == gcvPOWER_ON)
             {
@@ -2917,7 +3044,7 @@ gckKERNEL_Dispatch(
 
             gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->hardware->powerMutex, gcvINFINITE));
             powerMutexAcquired = gcvTRUE;
-            gcmkONERROR(gckHARDWARE_QueryPowerManagementState(Kernel->hardware,
+            gcmkONERROR(gckHARDWARE_QueryPowerState(Kernel->hardware,
                                                                   &power));
             if (power == gcvPOWER_ON)
             {
@@ -3001,48 +3128,25 @@ gckKERNEL_Dispatch(
         status = gcvSTATUS_OK;
         break;
 
-    case gcvHAL_QUERY_KERNEL_SETTINGS:
-        /* Get kernel settings. */
-        gcmkONERROR(
-            gckKERNEL_QuerySettings(Kernel,
-                                    &Interface->u.QueryKernelSettings.settings));
-        break;
-
     case gcvHAL_RESET:
         /* Reset the hardware. */
         gcmkONERROR(
             gckHARDWARE_Reset(Kernel->hardware));
         break;
 
-    case gcvHAL_DEBUG:
+    case gcvHAL_SET_DEBUG_LEVEL_ZONE:
         /* Set debug level and zones. */
-        if (Interface->u.Debug.set)
-        {
-            gckOS_SetDebugLevel(Interface->u.Debug.level);
-            gckOS_SetDebugZones(Interface->u.Debug.zones,
-                                Interface->u.Debug.enable);
-        }
+        gckOS_SetDebugLevel(Interface->u.DebugLevelZone.level);
+        gckOS_SetDebugZones(Interface->u.DebugLevelZone.zones,
+                            Interface->u.DebugLevelZone.enable);
+        break;
 
-        if (Interface->u.Debug.message[0] != '\0')
-        {
-            /* Print a message to the debugger. */
-            if (Interface->u.Debug.type == gcvMESSAGE_TEXT)
-            {
-               gckOS_DumpBuffer(Kernel->os,
-                                Interface->u.Debug.message,
-                                gcmSIZEOF(Interface->u.Debug.message),
-                                gcvDUMP_BUFFER_FROM_USER,
-                                gcvTRUE);
-            }
-            else
-            {
-               gckOS_DumpBuffer(Kernel->os,
-                                Interface->u.Debug.message,
-                                Interface->u.Debug.messageSize,
-                                gcvDUMP_BUFFER_FROM_USER,
-                                gcvTRUE);
-            }
-        }
+    case gcvHAL_DEBUG_DUMP:
+        gckOS_DumpBuffer(Kernel->os,
+                         Interface->u.DebugDump.type,
+                         gcmUINT64_TO_PTR(Interface->u.DebugDump.ptr),
+                         Interface->u.DebugDump.address,
+                         Interface->u.DebugDump.size);
         status = gcvSTATUS_OK;
         break;
 
@@ -3052,7 +3156,7 @@ gckKERNEL_Dispatch(
 
             _DumpDriverConfigure(Kernel);
 
-            gcmkONERROR(gckHARDWARE_QueryPowerManagementState(
+            gcmkONERROR(gckHARDWARE_QueryPowerState(
                 Kernel->hardware,
                 &power
                 ));
@@ -3148,65 +3252,66 @@ gckKERNEL_Dispatch(
 
 #if (gcdENABLE_3D || gcdENABLE_2D)
     case gcvHAL_ATTACH:
-        /* Attach user process. */
-        gcmkONERROR(
-            gckCOMMAND_Attach(Kernel->command,
-                              &context,
-                              &bytes,
-                              &Interface->u.Attach.numStates,
-                              processID));
+        if (Kernel->command)
+        {
+            /* Attach user process. */
+            gcmkONERROR(
+                gckCOMMAND_Attach(Kernel->command,
+                                  &context,
+                                  &bytes,
+                                  &Interface->u.Attach.numStates,
+                                  processID));
 
-        Interface->u.Attach.maxState = bytes;
-        Interface->u.Attach.context = gcmPTR_TO_NAME(context);
+            Interface->u.Attach.maxState = bytes;
+            Interface->u.Attach.context = gcmPTR_TO_NAME(context);
+
+            if (Interface->u.Attach.map)
+            {
+                if (context != gcvNULL)
+                {
+                    gcmkVERIFY_OK(
+                        gckCONTEXT_MapBuffer(context,
+                                             Interface->u.Attach.logicals,
+                                             &Interface->u.Attach.bytes));
+                }
+                else
+                {
+                    gctUINT i;
+
+                    for (i = 0; i < gcmCOUNTOF(Interface->u.Attach.logicals); i++)
+                    {
+                        Interface->u.Attach.logicals[i] = 0;
+                    }
+
+                    Interface->u.Attach.bytes = 0;
+                }
+            }
 
-        if (Interface->u.Attach.map == gcvTRUE)
-        {
             gcmkVERIFY_OK(
-                gckCONTEXT_MapBuffer(context,
-                                     Interface->u.Attach.physicals,
-                                     Interface->u.Attach.logicals,
-                                     &Interface->u.Attach.bytes));
+                gckKERNEL_AddProcessDB(Kernel,
+                                       processID, gcvDB_CONTEXT,
+                                       gcmINT2PTR(Interface->u.Attach.context),
+                                       gcvNULL,
+                                       0));
         }
-
-        gcmkVERIFY_OK(
-            gckKERNEL_AddProcessDB(Kernel,
-                                   processID, gcvDB_CONTEXT,
-                                   gcmINT2PTR(Interface->u.Attach.context),
-                                   gcvNULL,
-                                   0));
         break;
 #endif
 
     case gcvHAL_DETACH:
-        gcmkVERIFY_OK(
-            gckKERNEL_RemoveProcessDB(Kernel,
-                              processID, gcvDB_CONTEXT,
-                              gcmINT2PTR(Interface->u.Detach.context)));
-
-        /* Detach user process. */
-        gcmkONERROR(
-            gckCOMMAND_Detach(Kernel->command,
-                              gcmNAME_TO_PTR(Interface->u.Detach.context)));
-
-        gcmRELEASE_NAME(Interface->u.Detach.context);
-        gcmkONERROR(gckOS_AcquireMutex(Kernel->os,
-             Kernel->device->commitMutex,
-             gcvINFINITE
-             ));
-
-        commitMutexAcquired = gcvTRUE;
-
-        gcmkONERROR(gckEVENT_Submit(
-            Kernel->eventObj,
-            gcvTRUE,
-            gcvFALSE
-            ));
+        if (Kernel->command)
+        {
+            gcmkVERIFY_OK(
+                gckKERNEL_RemoveProcessDB(Kernel,
+                                  processID, gcvDB_CONTEXT,
+                                  gcmINT2PTR(Interface->u.Detach.context)));
 
-        gcmkONERROR(gckOS_ReleaseMutex(Kernel->os,
-            Kernel->device->commitMutex
-            ));
+            /* Detach user process. */
+            gcmkONERROR(
+                gckCOMMAND_Detach(Kernel->command,
+                                  gcmNAME_TO_PTR(Interface->u.Detach.context)));
 
-        commitMutexAcquired = gcvFALSE;
+            gcmRELEASE_NAME(Interface->u.Detach.context);
+        }
         break;
 
     case gcvHAL_GET_FRAME_INFO:
@@ -3240,46 +3345,23 @@ gckKERNEL_Dispatch(
 
     case gcvHAL_EXPORT_VIDEO_MEMORY:
         /* Unlock video memory. */
-        gcmkONERROR(gckVIDMEM_NODE_Export(Kernel,
-                                          Interface->u.ExportVideoMemory.node,
-                                          Interface->u.ExportVideoMemory.flags,
-                                          gcvNULL,
-                                          &Interface->u.ExportVideoMemory.fd));
+        gcmkONERROR(_ExportVideoMemory(Kernel, processID, Interface));
         break;
 
     case gcvHAL_NAME_VIDEO_MEMORY:
-        gcmkONERROR(gckVIDMEM_NODE_Name(Kernel,
-                                        Interface->u.NameVideoMemory.handle,
-                                        &Interface->u.NameVideoMemory.name));
+        gcmkONERROR(_NameVideoMemory(Kernel, processID, Interface));
         break;
 
     case gcvHAL_IMPORT_VIDEO_MEMORY:
-        gcmkONERROR(gckVIDMEM_NODE_Import(Kernel,
-                                          Interface->u.ImportVideoMemory.name,
-                                          &Interface->u.ImportVideoMemory.handle));
-
-        gcmkONERROR(
-            gckKERNEL_AddProcessDB(Kernel,
-                                   processID, gcvDB_VIDEO_MEMORY,
-                                   gcmINT2PTR(Interface->u.ImportVideoMemory.handle),
-                                   gcvNULL,
-                                   0));
+        gcmkONERROR(_ImportVideoMemory(Kernel, processID, Interface));
         break;
 
     case gcvHAL_SET_VIDEO_MEMORY_METADATA:
-        gcmkONERROR(gckKERNEL_SetVidMemMetadata(Kernel, processID, Interface));
+        gcmkONERROR(_SetVidMemMetadata(Kernel, processID, Interface));
         break;
 
     case gcvHAL_GET_VIDEO_MEMORY_FD:
-        gcmkONERROR(gckVIDMEM_NODE_GetFd(
-            Kernel,
-            Interface->u.GetVideoMemoryFd.handle,
-            &Interface->u.GetVideoMemoryFd.fd
-            ));
-
-        /* No need to add it to processDB because OS will release all fds when
-        ** process quits.
-        */
+        gcmkONERROR(_GetVideoMemoryFd(Kernel, processID, Interface));
         break;
 
     case gcvHAL_QUERY_RESET_TIME_STAMP:
@@ -3287,30 +3369,6 @@ gckKERNEL_Dispatch(
         Interface->u.QueryResetTimeStamp.contextID = Kernel->hardware->contextID;
         break;
 
-    case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
-        buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)gcmNAME_TO_PTR(Interface->u.FreeVirtualCommandBuffer.physical);
-
-        gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
-            Kernel,
-            processID,
-            gcvDB_COMMAND_BUFFER,
-            gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
-
-        gcmkONERROR(gckOS_DestroyUserVirtualMapping(
-            Kernel->os,
-            buffer->virtualBuffer.physical,
-            (gctSIZE_T)Interface->u.FreeVirtualCommandBuffer.bytes,
-            gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
-
-        gcmkONERROR(gckKERNEL_DestroyVirtualCommandBuffer(
-            Kernel,
-            (gctSIZE_T)Interface->u.FreeVirtualCommandBuffer.bytes,
-            (gctPHYS_ADDR)buffer,
-            gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
-
-        gcmRELEASE_NAME(Interface->u.FreeVirtualCommandBuffer.physical);
-        break;
-
 #if gcdLINUX_SYNC_FILE
     case gcvHAL_CREATE_NATIVE_FENCE:
         {
@@ -3451,26 +3509,11 @@ gckKERNEL_Dispatch(
         break;
 
     case gcvHAL_WRAP_USER_MEMORY:
-        gcmkONERROR(gckVIDMEM_NODE_WrapUserMemory(Kernel,
-                                                  &Interface->u.WrapUserMemory.desc,
-                                                  &Interface->u.WrapUserMemory.node,
-                                                  &Interface->u.WrapUserMemory.bytes));
-
-        gcmkONERROR(
-            gckKERNEL_AddProcessDB(Kernel,
-                                   processID,
-                                   gcvDB_VIDEO_MEMORY,
-                                   gcmINT2PTR(Interface->u.WrapUserMemory.node),
-                                   gcvNULL,
-                                   0));
+        gcmkONERROR(_WrapUserMemory(Kernel, processID, Interface));
         break;
 
     case gcvHAL_WAIT_FENCE:
-        gcmkONERROR(gckKERNEL_WaitFence(
-            Kernel,
-            Interface->u.WaitFence.handle,
-            Interface->u.WaitFence.timeOut
-            ));
+        gcmkONERROR(_WaitFence(Kernel, processID, Interface));
         break;
 
     case gcvHAL_DEVICE_MUTEX:
@@ -3588,7 +3631,7 @@ gckKERNEL_AttachProcess(
     gceSTATUS status;
     gctUINT32 processID;
 
-    gcmkHEADER_ARG("Kernel=0x%x Attach=%d", Kernel, Attach);
+    gcmkHEADER_ARG("Kernel=%p Attach=%d", Kernel, Attach);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -3640,7 +3683,7 @@ gckKERNEL_AttachProcessEx(
     gceSTATUS status;
     gctINT32 old;
 
-    gcmkHEADER_ARG("Kernel=0x%x Attach=%d PID=%d", Kernel, Attach, PID);
+    gcmkHEADER_ARG("Kernel=%p Attach=%d PID=%d", Kernel, Attach, PID);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -3668,11 +3711,6 @@ gckKERNEL_AttachProcessEx(
             /* Create the process database. */
             gcmkONERROR(gckKERNEL_CreateProcessDB(Kernel, PID));
         }
-
-#if gcdPROCESS_ADDRESS_SPACE
-        /* Map kernel command buffer in the process's own MMU. */
-        gcmkONERROR(_MapCommandBuffer(Kernel));
-#endif
     }
     else
     {
@@ -3718,9 +3756,6 @@ gckKERNEL_AttachProcessEx(
                                             Kernel->hardware,
                                             gcvBROADCAST_LAST_PROCESS));
             }
-
-            /* Flush the debug cache. */
-            gcmkDEBUGFLUSH(~0U);
         }
     }
 
@@ -3734,297 +3769,109 @@ OnError:
     return status;
 }
 
-#if gcdSECURE_USER
+/*******************************************************************************
+**
+**  gckKERNEL_Recovery
+**
+**  Try to recover the GPU from a fatal error.
+**
+**  INPUT:
+**
+**      gckKERNEL Kernel
+**          Pointer to an gckKERNEL object.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
 gceSTATUS
-gckKERNEL_MapLogicalToPhysical(
-    IN gckKERNEL Kernel,
-    IN gcskSECURE_CACHE_PTR Cache,
-    IN OUT gctPOINTER * Data
+gckKERNEL_Recovery(
+    IN gckKERNEL Kernel
     )
 {
     gceSTATUS status;
-    static gctBOOL baseAddressValid = gcvFALSE;
-    static gctUINT32 baseAddress;
-    gctBOOL needBase;
-    gcskLOGICAL_CACHE_PTR slot;
+    gckEVENT eventObj;
+    gckHARDWARE hardware;
+    gctUINT32 mask = 0;
+    gctUINT32 i = 0, count = 0;
+#if gcdINTERRUPT_STATISTIC
+    gctINT32 oldValue;
+#endif
 
-    gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x *Data=0x%x",
-                   Kernel, Cache, gcmOPT_POINTER(Data));
+    gcmkHEADER_ARG("Kernel=%p", Kernel);
 
-    /* Verify the arguments. */
+    /* Validate the arguemnts. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
 
-    if (!baseAddressValid)
-    {
-        /* Get base address. */
-        gcmkONERROR(gckHARDWARE_GetBaseAddress(Kernel->hardware, &baseAddress));
-
-        baseAddressValid = gcvTRUE;
-    }
+    /* Grab gckEVENT object. */
+    eventObj = Kernel->eventObj;
+    gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
 
-    /* Does this state load need a base address? */
-    gcmkONERROR(gckHARDWARE_NeedBaseAddress(Kernel->hardware,
-                                            ((gctUINT32_PTR) Data)[-1],
-                                            &needBase));
+    /* Grab gckHARDWARE object. */
+    hardware = Kernel->hardware;
+    gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
 
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
+    if (Kernel->stuckDump == gcvSTUCK_DUMP_NONE)
     {
-        gcskLOGICAL_CACHE_PTR next;
-        gctINT i;
-
-        /* Walk all used cache slots. */
-        for (i = 1, slot = Cache->cache[0].next, next = gcvNULL;
-             (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-             ++i, slot = slot->next
-        )
-        {
-            if (slot->logical == *Data)
-            {
-                /* Bail out. */
-                next = slot;
-                break;
-            }
-        }
-
-        /* See if we had a miss. */
-        if (next == gcvNULL)
-        {
-            /* Use the tail of the cache. */
-            slot = Cache->cache[0].prev;
-
-            /* Initialize the cache line. */
-            slot->logical = *Data;
-
-            /* Map the logical address to a DMA address. */
-            gcmkONERROR(
-                gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
-
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
-        }
-
-        /* Move slot to head of list. */
-        if (slot != Cache->cache[0].next)
-        {
-            /* Unlink. */
-            slot->prev->next = slot->next;
-            slot->next->prev = slot->prev;
-
-            /* Move to head of chain. */
-            slot->prev       = &Cache->cache[0];
-            slot->next       = Cache->cache[0].next;
-            slot->prev->next = slot;
-            slot->next->prev = slot;
-        }
+        gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
     }
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
+    else
     {
-        gctINT i;
-        gcskLOGICAL_CACHE_PTR next = gcvNULL;
-        gcskLOGICAL_CACHE_PTR oldestSlot = gcvNULL;
-        slot = gcvNULL;
-
-        if (Cache->cacheIndex != gcvNULL)
-        {
-            /* Walk the cache forwards. */
-            for (i = 1, slot = Cache->cacheIndex;
-                 (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-                 ++i, slot = slot->next)
-            {
-                if (slot->logical == *Data)
-                {
-                    /* Bail out. */
-                    next = slot;
-                    break;
-                }
-
-                /* Determine age of this slot. */
-                if ((oldestSlot       == gcvNULL)
-                ||  (oldestSlot->stamp > slot->stamp)
-                )
-                {
-                    oldestSlot = slot;
-                }
-            }
-
-            if (next == gcvNULL)
-            {
-                /* Walk the cache backwards. */
-                for (slot = Cache->cacheIndex->prev;
-                     (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-                     ++i, slot = slot->prev)
-                {
-                    if (slot->logical == *Data)
-                    {
-                        /* Bail out. */
-                        next = slot;
-                        break;
-                    }
-
-                    /* Determine age of this slot. */
-                    if ((oldestSlot       == gcvNULL)
-                    ||  (oldestSlot->stamp > slot->stamp)
-                    )
-                    {
-                        oldestSlot = slot;
-                    }
-                }
-            }
-        }
-
-        /* See if we had a miss. */
-        if (next == gcvNULL)
-        {
-            if (Cache->cacheFree != 0)
-            {
-                slot = &Cache->cache[Cache->cacheFree];
-                gcmkASSERT(slot->logical == gcvNULL);
-
-                ++ Cache->cacheFree;
-                if (Cache->cacheFree >= gcmCOUNTOF(Cache->cache))
-                {
-                    Cache->cacheFree = 0;
-                }
-            }
-            else
-            {
-                /* Use the oldest cache slot. */
-                gcmkASSERT(oldestSlot != gcvNULL);
-                slot = oldestSlot;
-
-                /* Unlink from the chain. */
-                slot->prev->next = slot->next;
-                slot->next->prev = slot->prev;
-
-                /* Append to the end. */
-                slot->prev       = Cache->cache[0].prev;
-                slot->next       = &Cache->cache[0];
-                slot->prev->next = slot;
-                slot->next->prev = slot;
-            }
-
-            /* Initialize the cache line. */
-            slot->logical = *Data;
-
-            /* Map the logical address to a DMA address. */
-            gcmkONERROR(
-                gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
-
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
-        }
+        gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->device->stuckDumpMutex, gcvINFINITE));
 
-        /* Save time stamp. */
-        slot->stamp = ++ Cache->cacheStamp;
+        _DumpDriverConfigure(Kernel);
+        _DumpState(Kernel);
 
-        /* Save current slot for next lookup. */
-        Cache->cacheIndex = slot;
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->device->stuckDumpMutex));
     }
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-    {
-        gctINT i;
-        gctUINT32 data = gcmPTR2INT32(*Data);
-        gctUINT32 key, index;
-        gcskLOGICAL_CACHE_PTR hash;
-
-        /* Generate a hash key. */
-        key   = (data >> 24) + (data >> 16) + (data >> 8) + data;
-        index = key % gcmCOUNTOF(Cache->hash);
-
-        /* Get the hash entry. */
-        hash = &Cache->hash[index];
-
-        for (slot = hash->nextHash, i = 0;
-             (slot != gcvNULL) && (i < gcdSECURE_CACHE_SLOTS);
-             slot = slot->nextHash, ++i
-        )
-        {
-            if (slot->logical == (*Data))
-            {
-                break;
-            }
-        }
-
-        if (slot == gcvNULL)
-        {
-            /* Grab from the tail of the cache. */
-            slot = Cache->cache[0].prev;
 
-            /* Unlink slot from any hash table it is part of. */
-            if (slot->prevHash != gcvNULL)
-            {
-                slot->prevHash->nextHash = slot->nextHash;
-            }
-            if (slot->nextHash != gcvNULL)
-            {
-                slot->nextHash->prevHash = slot->prevHash;
-            }
-
-            /* Initialize the cache line. */
-            slot->logical = *Data;
+    if (Kernel->recovery == gcvFALSE)
+    {
+        gcmkPRINT("[galcore]: Stop driver to keep scene.");
 
-            /* Map the logical address to a DMA address. */
-            gcmkONERROR(
-                gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
+        /* Stop monitor timer. */
+        Kernel->monitorTimerStop = gcvTRUE;
 
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
+        /* Success. */
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
 
-            if (hash->nextHash != gcvNULL)
-            {
-                gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
-                               "Hash Collision: logical=0x%x key=0x%08x",
-                               *Data, key);
-            }
+    /* Issuing a soft reset for the GPU. */
+    gcmkONERROR(gckHARDWARE_Reset(hardware));
 
-            /* Insert the slot at the head of the hash list. */
-            slot->nextHash     = hash->nextHash;
-            if (slot->nextHash != gcvNULL)
-            {
-                slot->nextHash->prevHash = slot;
-            }
-            slot->prevHash     = hash;
-            hash->nextHash     = slot;
-        }
+    mask = Kernel->restoreMask;
 
-        /* Move slot to head of list. */
-        if (slot != Cache->cache[0].next)
+    for (i = 0; i < 32; i++)
+    {
+        if (mask & (1 << i))
         {
-            /* Unlink. */
-            slot->prev->next = slot->next;
-            slot->next->prev = slot->prev;
-
-            /* Move to head of chain. */
-            slot->prev       = &Cache->cache[0];
-            slot->next       = Cache->cache[0].next;
-            slot->prev->next = slot;
-            slot->next->prev = slot;
+            count++;
         }
     }
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
-    {
-        gctUINT32 index = (gcmPTR2INT32(*Data) % gcdSECURE_CACHE_SLOTS) + 1;
 
-        /* Get cache slot. */
-        slot = &Cache->cache[index];
-
-        /* Check for cache miss. */
-        if (slot->logical != *Data)
-        {
-            /* Initialize the cache line. */
-            slot->logical = *Data;
-
-            /* Map the logical address to a DMA address. */
-            gcmkONERROR(
-                gckOS_GetPhysicalAddress(Kernel->os, *Data, &slot->dma));
+    /* Handle all outstanding events now. */
+    gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, mask));
 
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Kernel->os, slot->dma, &slot->dma));
-        }
+#if gcdINTERRUPT_STATISTIC
+    while (count--)
+    {
+        gcmkONERROR(gckOS_AtomDecrement(
+            Kernel->os,
+            eventObj->interruptCount,
+            &oldValue
+            ));
     }
+
+    gckOS_AtomClearMask(Kernel->hardware->pendingEvent, mask);
 #endif
 
-    /* Return DMA address. */
-    *Data = gcmINT2PTR(slot->dma + (needBase ? baseAddress : 0));
+    gcmkONERROR(gckEVENT_Notify(eventObj, 1));
+
+    gcmkVERIFY_OK(gckOS_GetTime(&Kernel->resetTimeStamp));
 
     /* Success. */
-    gcmkFOOTER_ARG("*Data=0x%08x", *Data);
+    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
@@ -4033,363 +3880,37 @@ OnError:
     return status;
 }
 
+/*******************************************************************************
+**
+**  gckKERNEL_OpenUserData
+**
+**  Get access to the user data.
+**
+**  INPUT:
+**
+**      gckKERNEL Kernel
+**          Pointer to an gckKERNEL object.
+**
+**      gctBOOL NeedCopy
+**          The flag indicating whether or not the data should be copied.
+**
+**      gctPOINTER StaticStorage
+**          Pointer to the kernel storage where the data is to be copied if
+**          NeedCopy is gcvTRUE.
+**
+**      gctPOINTER UserPointer
+**          User pointer to the data.
+**
+**      gctSIZE_T Size
+**          Size of the data.
+**
+**  OUTPUT:
+**
+**      gctPOINTER * KernelPointer
+**          Pointer to the kernel pointer that will be pointing to the data.
+*/
 gceSTATUS
-gckKERNEL_FlushTranslationCache(
-    IN gckKERNEL Kernel,
-    IN gcskSECURE_CACHE_PTR Cache,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gctINT i;
-    gcskLOGICAL_CACHE_PTR slot;
-    gctUINT8_PTR ptr;
-
-    gcmkHEADER_ARG("Kernel=0x%x Cache=0x%x Logical=0x%x Bytes=%lu",
-                   Kernel, Cache, Logical, Bytes);
-
-    /* Do we need to flush the entire cache? */
-    if (Logical == gcvNULL)
-    {
-        /* Clear all cache slots. */
-        for (i = 1; i <= gcdSECURE_CACHE_SLOTS; ++i)
-        {
-            Cache->cache[i].logical  = gcvNULL;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-            Cache->cache[i].nextHash = gcvNULL;
-            Cache->cache[i].prevHash = gcvNULL;
-#endif
-}
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-        /* Zero the hash table. */
-        for (i = 0; i < gcmCOUNTOF(Cache->hash); ++i)
-        {
-            Cache->hash[i].nextHash = gcvNULL;
-        }
-#endif
-
-        /* Reset the cache functionality. */
-        Cache->cacheIndex = gcvNULL;
-        Cache->cacheFree  = 1;
-        Cache->cacheStamp = 0;
-    }
-
-    else
-    {
-        gctUINT8_PTR low  = (gctUINT8_PTR) Logical;
-        gctUINT8_PTR high = low + Bytes;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LRU
-        gcskLOGICAL_CACHE_PTR next;
-
-        /* Walk all used cache slots. */
-        for (i = 1, slot = Cache->cache[0].next;
-             (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-             ++i, slot = next
-        )
-        {
-            /* Save pointer to next slot. */
-            next = slot->next;
-
-            /* Test if this slot falls within the range to flush. */
-            ptr = (gctUINT8_PTR) slot->logical;
-            if ((ptr >= low) && (ptr < high))
-            {
-                /* Unlink slot. */
-                slot->prev->next = slot->next;
-                slot->next->prev = slot->prev;
-
-                /* Append slot to tail of cache. */
-                slot->prev       = Cache->cache[0].prev;
-                slot->next       = &Cache->cache[0];
-                slot->prev->next = slot;
-                slot->next->prev = slot;
-
-                /* Mark slot as empty. */
-                slot->logical = gcvNULL;
-            }
-        }
-
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
-        gcskLOGICAL_CACHE_PTR next;
-
-        for (i = 1, slot = Cache->cache[0].next;
-             (i <= gcdSECURE_CACHE_SLOTS) && (slot->logical != gcvNULL);
-             ++i, slot = next)
-        {
-            /* Save pointer to next slot. */
-            next = slot->next;
-
-            /* Test if this slot falls within the range to flush. */
-            ptr = (gctUINT8_PTR) slot->logical;
-            if ((ptr >= low) && (ptr < high))
-            {
-                /* Test if this slot is the current slot. */
-                if (slot == Cache->cacheIndex)
-                {
-                    /* Move to next or previous slot. */
-                    Cache->cacheIndex = (slot->next->logical != gcvNULL)
-                                      ? slot->next
-                                      : (slot->prev->logical != gcvNULL)
-                                      ? slot->prev
-                                      : gcvNULL;
-                }
-
-                /* Unlink slot from cache. */
-                slot->prev->next = slot->next;
-                slot->next->prev = slot->prev;
-
-                /* Insert slot to head of cache. */
-                slot->prev       = &Cache->cache[0];
-                slot->next       = Cache->cache[0].next;
-                slot->prev->next = slot;
-                slot->next->prev = slot;
-
-                /* Mark slot as empty. */
-                slot->logical = gcvNULL;
-                slot->stamp   = 0;
-            }
-        }
-
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-        gctINT j;
-        gcskLOGICAL_CACHE_PTR hash, next;
-
-        /* Walk all hash tables. */
-        for (i = 0, hash = Cache->hash;
-             i < gcmCOUNTOF(Cache->hash);
-             ++i, ++hash)
-        {
-            /* Walk all slots in the hash. */
-            for (j = 0, slot = hash->nextHash;
-                 (j < gcdSECURE_CACHE_SLOTS) && (slot != gcvNULL);
-                 ++j, slot = next)
-            {
-                /* Save pointer to next slot. */
-                next = slot->next;
-
-                /* Test if this slot falls within the range to flush. */
-                ptr = (gctUINT8_PTR) slot->logical;
-                if ((ptr >= low) && (ptr < high))
-                {
-                    /* Unlink slot from hash table. */
-                    if (slot->prevHash == hash)
-                    {
-                        hash->nextHash = slot->nextHash;
-                    }
-                    else
-                    {
-                        slot->prevHash->nextHash = slot->nextHash;
-                    }
-
-                    if (slot->nextHash != gcvNULL)
-                    {
-                        slot->nextHash->prevHash = slot->prevHash;
-                    }
-
-                    /* Unlink slot from cache. */
-                    slot->prev->next = slot->next;
-                    slot->next->prev = slot->prev;
-
-                    /* Append slot to tail of cache. */
-                    slot->prev       = Cache->cache[0].prev;
-                    slot->next       = &Cache->cache[0];
-                    slot->prev->next = slot;
-                    slot->next->prev = slot;
-
-                    /* Mark slot as empty. */
-                    slot->logical  = gcvNULL;
-                    slot->prevHash = gcvNULL;
-                    slot->nextHash = gcvNULL;
-                }
-            }
-        }
-
-#elif gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_TABLE
-        gctUINT32 index;
-
-        /* Loop while inside the range. */
-        for (i = 1; (low < high) && (i <= gcdSECURE_CACHE_SLOTS); ++i)
-        {
-            /* Get index into cache for this range. */
-            index = (gcmPTR2INT32(low) % gcdSECURE_CACHE_SLOTS) + 1;
-            slot  = &Cache->cache[index];
-
-            /* Test if this slot falls within the range to flush. */
-            ptr = (gctUINT8_PTR) slot->logical;
-            if ((ptr >= low) && (ptr < high))
-            {
-                /* Remove entry from cache. */
-                slot->logical = gcvNULL;
-            }
-
-            /* Next block. */
-            low += gcdSECURE_CACHE_SLOTS;
-        }
-#endif
-    }
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-#endif
-
-/*******************************************************************************
-**
-**  gckKERNEL_Recovery
-**
-**  Try to recover the GPU from a fatal error.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckKERNEL_Recovery(
-    IN gckKERNEL Kernel
-    )
-{
-    gceSTATUS status;
-    gckEVENT eventObj;
-    gckHARDWARE hardware;
-#if gcdSECURE_USER
-    gctUINT32 processID;
-    gcskSECURE_CACHE_PTR cache;
-#endif
-    gctUINT32 mask = 0;
-    gctUINT32 i = 0, count = 0;
-#if gcdINTERRUPT_STATISTIC
-    gctINT32 oldValue;
-#endif
-
-    gcmkHEADER_ARG("Kernel=0x%x", Kernel);
-
-    /* Validate the arguemnts. */
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-
-    /* Grab gckEVENT object. */
-    eventObj = Kernel->eventObj;
-    gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT);
-
-    /* Grab gckHARDWARE object. */
-    hardware = Kernel->hardware;
-    gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
-
-#if gcdSECURE_USER
-    /* Flush the secure mapping cache. */
-    gcmkONERROR(gckOS_GetProcessID(&processID));
-    gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
-    gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
-#endif
-
-    if (Kernel->stuckDump == gcvSTUCK_DUMP_NONE)
-    {
-        gcmkPRINT("[galcore]: GPU[%d] hang, automatic recovery.", Kernel->core);
-    }
-    else
-    {
-        gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->device->stuckDumpMutex, gcvINFINITE));
-
-        _DumpDriverConfigure(Kernel);
-        _DumpState(Kernel);
-
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->device->stuckDumpMutex));
-    }
-
-    if (Kernel->recovery == gcvFALSE)
-    {
-        gcmkPRINT("[galcore]: Stop driver to keep scene.");
-
-        /* Stop monitor timer. */
-        Kernel->monitorTimerStop = gcvTRUE;
-
-        /* Success. */
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-
-    /* Issuing a soft reset for the GPU. */
-    gcmkONERROR(gckHARDWARE_Reset(hardware));
-
-    mask = Kernel->restoreMask;
-
-    for (i = 0; i < 32; i++)
-    {
-        if (mask & (1 << i))
-        {
-            count++;
-        }
-    }
-
-    /* Handle all outstanding events now. */
-    gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, mask));
-
-#if gcdINTERRUPT_STATISTIC
-    while (count--)
-    {
-        gcmkONERROR(gckOS_AtomDecrement(
-            Kernel->os,
-            eventObj->interruptCount,
-            &oldValue
-            ));
-    }
-
-    gckOS_AtomClearMask(Kernel->hardware->pendingEvent, mask);
-#endif
-
-    gcmkONERROR(gckEVENT_Notify(eventObj, 1));
-
-    gcmkVERIFY_OK(gckOS_GetTime(&Kernel->resetTimeStamp));
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gckKERNEL_OpenUserData
-**
-**  Get access to the user data.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gctBOOL NeedCopy
-**          The flag indicating whether or not the data should be copied.
-**
-**      gctPOINTER StaticStorage
-**          Pointer to the kernel storage where the data is to be copied if
-**          NeedCopy is gcvTRUE.
-**
-**      gctPOINTER UserPointer
-**          User pointer to the data.
-**
-**      gctSIZE_T Size
-**          Size of the data.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * KernelPointer
-**          Pointer to the kernel pointer that will be pointing to the data.
-*/
-gceSTATUS
-gckKERNEL_OpenUserData(
+gckKERNEL_OpenUserData(
     IN gckKERNEL Kernel,
     IN gctBOOL NeedCopy,
     IN gctPOINTER StaticStorage,
@@ -4401,8 +3922,8 @@ gckKERNEL_OpenUserData(
     gceSTATUS status;
 
     gcmkHEADER_ARG(
-        "Kernel=0x%08X NeedCopy=%d StaticStorage=0x%08X "
-        "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
+        "Kernel=%p NeedCopy=%d StaticStorage=%p "
+        "UserPointer=%p Size=%lu KernelPointer=%p",
         Kernel, NeedCopy, StaticStorage, UserPointer, Size, KernelPointer
         );
 
@@ -4469,532 +3990,65 @@ OnError:
 **  OUTPUT:
 **
 **      gctPOINTER * KernelPointer
-**          Kernel pointer to the data.
-*/
-gceSTATUS
-gckKERNEL_CloseUserData(
-    IN gckKERNEL Kernel,
-    IN gctBOOL NeedCopy,
-    IN gctBOOL FlushData,
-    IN gctPOINTER UserPointer,
-    IN gctSIZE_T Size,
-    OUT gctPOINTER * KernelPointer
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gctPOINTER pointer;
-
-    gcmkHEADER_ARG(
-        "Kernel=0x%08X NeedCopy=%d FlushData=%d "
-        "UserPointer=0x%08X Size=%lu KernelPointer=0x%08X",
-        Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer
-        );
-
-    /* Validate the arguemnts. */
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-    gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
-    gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Size > 0);
-
-    /* Get a shortcut to the kernel pointer. */
-    pointer = * KernelPointer;
-
-    if (pointer != gcvNULL)
-    {
-        if (NeedCopy)
-        {
-            if (FlushData)
-            {
-                gcmkONERROR(gckOS_CopyToUserData(
-                    Kernel->os, * KernelPointer, UserPointer, Size
-                    ));
-            }
-        }
-        else
-        {
-            /* Unmap record from kernel memory. */
-            gcmkONERROR(gckOS_UnmapUserPointer(
-                Kernel->os,
-                UserPointer,
-                Size,
-                * KernelPointer
-                ));
-        }
-
-        /* Reset the kernel pointer. */
-        * KernelPointer = gcvNULL;
-    }
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckKERNEL_AllocateVirtualCommandBuffer(
-    IN gckKERNEL Kernel,
-    IN gctBOOL InUserSpace,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctPHYS_ADDR * Physical,
-    OUT gctPOINTER * Logical
-    )
-{
-    gceSTATUS                       status;
-    gckOS                           os = Kernel->os;
-    gckVIRTUAL_COMMAND_BUFFER_PTR   buffer;
-
-    gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
-        os, InUserSpace, gcmOPT_VALUE(Bytes));
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
-    gcmkVERIFY_ARGUMENT(*Bytes > 0);
-    gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-
-    gcmkONERROR(
-        gckOS_Allocate(
-            os,
-            sizeof(gckVIRTUAL_COMMAND_BUFFER),
-            (gctPOINTER)&buffer
-            ));
-
-    gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_COMMAND_BUFFER)));
-
-    gcmkONERROR(
-        gckKERNEL_AllocateVirtualMemory(
-            Kernel,
-            gcvFALSE,
-            InUserSpace,
-            Bytes,
-            (gctPHYS_ADDR *)&buffer,
-            Logical
-            ));
-
-    gcmkVERIFY_OK(gckOS_AcquireMutex(os, Kernel->virtualBufferLock, gcvINFINITE));
-
-    if (Kernel->virtualBufferHead == gcvNULL)
-    {
-        Kernel->virtualBufferHead =
-        Kernel->virtualBufferTail = buffer;
-    }
-    else
-    {
-        buffer->prev = Kernel->virtualBufferTail;
-        Kernel->virtualBufferTail->next = buffer;
-        Kernel->virtualBufferTail = buffer;
-    }
-
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Kernel->virtualBufferLock));
-
-    *Physical = buffer;
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkVERIFY_OK(gckOS_Free(os, buffer));
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckKERNEL_DestroyVirtualCommandBuffer(
-    IN gckKERNEL Kernel,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical
-    )
-{
-    gckOS                           os;
-    gckKERNEL                       kernel;
-    gckVIRTUAL_COMMAND_BUFFER_PTR   buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)Physical;
-
-    gcmkHEADER();
-    gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
-
-    kernel = buffer->virtualBuffer.kernel;
-    os = kernel->os;
-
-    gcmkVERIFY_OK(gckOS_AcquireMutex(os, kernel->virtualBufferLock, gcvINFINITE));
-
-    if (buffer == kernel->virtualBufferHead)
-    {
-        if ((kernel->virtualBufferHead = buffer->next) == gcvNULL)
-        {
-            kernel->virtualBufferTail = gcvNULL;
-        }
-    }
-    else
-    {
-        buffer->prev->next = buffer->next;
-
-        if (buffer == kernel->virtualBufferTail)
-        {
-            kernel->virtualBufferTail = buffer->prev;
-        }
-        else
-        {
-            buffer->next->prev = buffer->prev;
-        }
-    }
-
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, kernel->virtualBufferLock));
-
-    gcmkVERIFY_OK(
-        gckKERNEL_FreeVirtualMemory(
-        Physical,
-        Logical,
-        gcvFALSE
-        ));
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckKERNEL_AllocateVirtualMemory(
-    IN gckKERNEL Kernel,
-    IN gctBOOL NonPaged,
-    IN gctBOOL InUserSpace,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctPHYS_ADDR * Physical,
-    OUT gctPOINTER * Logical
-    )
-{
-    gckOS os                             = Kernel->os;
-    gceSTATUS status;
-    gctPOINTER logical                   = gcvNULL;
-    gctSIZE_T pageCount;
-    gctSIZE_T bytes                      = *Bytes;
-    gckVIRTUAL_BUFFER_PTR buffer         = gcvNULL;
-    gckMMU mmu                           = gcvNULL;
-    gctUINT32 allocFlag                  = 0;
-
-    gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
-        os, InUserSpace, gcmOPT_VALUE(Bytes));
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
-    gcmkVERIFY_ARGUMENT(*Bytes > 0);
-    gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-
-    if (*Physical == gcvNULL)
-    {
-        gcmkONERROR(gckOS_Allocate(os,
-            sizeof(gckVIRTUAL_BUFFER),
-            (gctPOINTER)&buffer));
-
-        gcmkONERROR(gckOS_ZeroMemory(buffer, sizeof(gckVIRTUAL_BUFFER)));
-    }
-    else
-    {
-        buffer = *Physical;
-    }
-
-    buffer->bytes = bytes;
-
-#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
-    allocFlag = gcvALLOC_FLAG_CACHEABLE;
-#endif
-
-    if (NonPaged)
-    {
-        gcmkONERROR(gckOS_AllocateNonPagedMemory(
-            os,
-            InUserSpace,
-            allocFlag | gcvALLOC_FLAG_CONTIGUOUS,
-            &bytes,
-            &buffer->physical,
-            &logical
-            ));
-    }
-    else
-    {
-        gcmkONERROR(gckOS_AllocatePagedMemoryEx(
-            os,
-            allocFlag | gcvALLOC_FLAG_NON_CONTIGUOUS,
-            bytes,
-            gcvNULL,
-            &buffer->physical
-            ));
-    }
-
-    if (NonPaged)
-    {
-        gctSIZE_T pageSize;
-        gcmkONERROR(gckOS_GetPageSize(os, &pageSize));
-
-        pageCount = (bytes + pageSize - 1) / pageSize;
-
-        if (InUserSpace)
-        {
-            *Logical =
-                buffer->userLogical = logical;
-        }
-        else
-        {
-            *Logical =
-                buffer->kernelLogical = logical;
-        }
-    }
-    else
-    {
-        if (InUserSpace)
-        {
-            gcmkONERROR(gckOS_CreateUserVirtualMapping(os,
-                buffer->physical,
-                bytes,
-                &logical,
-                &pageCount));
-
-            *Logical =
-                buffer->userLogical = logical;
-        }
-        else
-        {
-            gcmkONERROR(gckOS_CreateKernelVirtualMapping(os,
-                buffer->physical,
-                bytes,
-                &logical,
-                &pageCount));
-
-            *Logical =
-                buffer->kernelLogical = logical;
-        }
-
-    }
-
-    buffer->pageCount = pageCount;
-    buffer->kernel = Kernel;
-
-    gcmkONERROR(gckOS_GetProcessID(&buffer->pid));
-
-#if gcdPROCESS_ADDRESS_SPACE
-    gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
-    buffer->mmu = mmu;
-#else
-    mmu = Kernel->mmu;
-#endif
-
-    gcmkONERROR(gckMMU_AllocatePages(mmu,
-        pageCount,
-        &buffer->pageTable,
-        &buffer->gpuAddress));
-
-#if gcdENABLE_TRUST_APPLICATION
-    if (Kernel->hardware->options.secureMode == gcvSECURE_IN_TA)
-    {
-        gcmkONERROR(gckKERNEL_MapInTrustApplicaiton(
-            Kernel,
-            logical,
-            buffer->physical,
-            buffer->gpuAddress,
-            pageCount
-            ));
-    }
-    else
-#endif
-    {
-        gcmkONERROR(gckOS_MapPagesEx(os,
-            Kernel->core,
-            buffer->physical,
-            pageCount,
-            buffer->gpuAddress,
-            buffer->pageTable,
-            gcvFALSE,
-            gcvSURF_TYPE_UNKNOWN
-            ));
-    }
-
-    gcmkONERROR(gckMMU_Flush(mmu, gcvSURF_INDEX));
-
-    if (*Physical == gcvNULL)
-        *Physical = buffer;
-
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL,
-        "gpuAddress = %x pageCount = %d kernelLogical = %x userLogical=%x",
-        buffer->gpuAddress, buffer->pageCount,
-        buffer->kernelLogical, buffer->userLogical);
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    if (buffer && buffer->gpuAddress)
-    {
-        gcmkVERIFY_OK(
-            gckMMU_FreePages(mmu, gcvFALSE, buffer->gpuAddress, buffer->pageTable, buffer->pageCount));
-    }
-
-    if (NonPaged && buffer->physical)
-    {
-        gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
-            os,
-            bytes,
-            buffer->physical,
-            logical
-            ));
-    }
-    else
-    {
-        if (buffer && buffer->userLogical)
-        {
-            gcmkVERIFY_OK(
-                gckOS_DestroyUserVirtualMapping(os,
-                buffer->physical,
-                bytes,
-                (NonPaged ? 0 : buffer->userLogical)));
-        }
-
-        if (buffer && buffer->kernelLogical)
-        {
-            gcmkVERIFY_OK(
-                gckOS_DestroyKernelVirtualMapping(os,
-                buffer->physical,
-                bytes,
-                (NonPaged ? 0 : buffer->kernelLogical)));
-        }
-
-        if (buffer && buffer->physical)
-        {
-            gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, bytes));
-        }
-    }
-
-    if (*Physical == gcvNULL)
-        gcmkVERIFY_OK(gckOS_Free(os, buffer));
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-
-}
-
-gceSTATUS
-gckKERNEL_FreeVirtualMemory(
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gctBOOL NonPaged
-    )
-{
-    gckOS os;
-    gckKERNEL kernel;
-    gckMMU mmu;
-    gckVIRTUAL_BUFFER_PTR buffer = (gckVIRTUAL_BUFFER_PTR)Physical;
-
-    gcmkHEADER();
-    gcmkVERIFY_ARGUMENT(buffer != gcvNULL);
-
-    kernel = buffer->kernel;
-    os = kernel->os;
-
-#if gcdPROCESS_ADDRESS_SPACE
-    gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
-#else
-    mmu = kernel->mmu;
-#endif
-
-    if (!buffer->userLogical && !NonPaged)
-    {
-        gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(os,
-            buffer->physical,
-            buffer->bytes,
-            Logical));
-    }
-
-    gcmkVERIFY_OK(
-        gckMMU_FreePages(mmu, gcvFALSE, buffer->gpuAddress, buffer->pageTable, buffer->pageCount));
-
-    gcmkVERIFY_OK(gckOS_UnmapPages(os, buffer->pageCount, buffer->gpuAddress));
-
-    if (NonPaged)
-    {
-        gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
-            os,
-            buffer->bytes,
-            buffer->physical,
-            Logical
-            ));
-    }
-    else
-    {
-        gcmkVERIFY_OK(gckOS_FreePagedMemory(os, buffer->physical, buffer->bytes));
-    }
-
-    gcmkVERIFY_OK(gckOS_Free(os, buffer));
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckKERNEL_GetGPUAddress(
-    IN gckKERNEL Kernel,
-    IN gctPOINTER Logical,
-    IN gctBOOL InUserSpace,
-    IN gctPHYS_ADDR Physical,
-    OUT gctUINT32 * Address
-    )
-{
-    gckVIRTUAL_BUFFER_PTR buffer = Physical;
-    gctPOINTER start;
-
-    gcmkHEADER_ARG("Logical = %x InUserSpace=%d.", Logical, InUserSpace);
-
-    if (InUserSpace)
-    {
-        start = buffer->userLogical;
-    }
-    else
-    {
-        start = buffer->kernelLogical;
-    }
-
-    gcmkASSERT(Logical >= start
-           && (Logical < (gctPOINTER)((gctUINT8_PTR)start + buffer->bytes)));
-
-    * Address = buffer->gpuAddress + (gctUINT32)((gctUINT8_PTR)Logical - (gctUINT8_PTR)start);
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
+**          Kernel pointer to the data.
+*/
 gceSTATUS
-gckKERNEL_QueryGPUAddress(
+gckKERNEL_CloseUserData(
     IN gckKERNEL Kernel,
-    IN gctUINT32 GpuAddress,
-    OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
+    IN gctBOOL NeedCopy,
+    IN gctBOOL FlushData,
+    IN gctPOINTER UserPointer,
+    IN gctSIZE_T Size,
+    OUT gctPOINTER * KernelPointer
     )
 {
-    gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
-    gctUINT32 start;
-    gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
+    gceSTATUS status = gcvSTATUS_OK;
+    gctPOINTER pointer;
 
-    gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, Kernel->virtualBufferLock, gcvINFINITE));
+    gcmkHEADER_ARG(
+        "Kernel=%p NeedCopy=%d FlushData=%d "
+        "UserPointer=%p Size=%lu KernelPointer=%p",
+        Kernel, NeedCopy, FlushData, UserPointer, Size, KernelPointer
+        );
 
-    /* Walk all command buffers. */
-    for (buffer = Kernel->virtualBufferHead; buffer != gcvNULL; buffer = buffer->next)
-    {
-        start = (gctUINT32)buffer->virtualBuffer.gpuAddress;
+    /* Validate the arguemnts. */
+    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+    gcmkVERIFY_ARGUMENT(UserPointer != gcvNULL);
+    gcmkVERIFY_ARGUMENT(KernelPointer != gcvNULL);
+    gcmkVERIFY_ARGUMENT(Size > 0);
 
-        if (GpuAddress >= start && GpuAddress <= (start - 1 + buffer->virtualBuffer.pageCount * 4096))
+    /* Get a shortcut to the kernel pointer. */
+    pointer = * KernelPointer;
+
+    if (pointer != gcvNULL)
+    {
+        if (NeedCopy)
         {
-            /* Find a range matched. */
-            *Buffer = buffer;
-            status = gcvSTATUS_OK;
-            break;
+            if (FlushData)
+            {
+                gcmkONERROR(gckOS_CopyToUserData(
+                    Kernel->os, * KernelPointer, UserPointer, Size
+                    ));
+            }
+        }
+        else
+        {
+            /* Unmap record from kernel memory. */
+            gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+                Kernel->os,
+                UserPointer,
+                Size,
+                * KernelPointer
+                ));
         }
-    }
 
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->virtualBufferLock));
+        /* Reset the kernel pointer. */
+        * KernelPointer = gcvNULL;
+    }
 
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
     return status;
 }
 
@@ -5040,7 +4094,7 @@ gckQUEUE_GetData(
 {
     gcuQUEUEDATA * datas = LinkQueue->datas;
 
-    gcmkASSERT(Index >= 0 && Index < LinkQueue->size);
+    gcmkASSERT(Index < LinkQueue->size);
 
     *Data = &datas[(Index + LinkQueue->front) % LinkQueue->size];
 }
@@ -5085,33 +4139,41 @@ gckQUEUE_Free(
 /******************************************************************************\
 *************************** Pointer - ID translation ***************************
 \******************************************************************************/
-#define gcdID_TABLE_LENGTH 1024
+
+/* The capacity is 32 initially, double when expand, but no more than 512. */
+#define gcdID_TABLE_MAX_EXPAND    512
+
 typedef struct _gcsINTEGERDB * gckINTEGERDB;
 typedef struct _gcsINTEGERDB
 {
-    gckOS                       os;
-    gctPOINTER*                 table;
-    gctPOINTER                  mutex;
-    gctUINT32                   tableLen;
-    gctUINT32                   currentID;
-    gctUINT32                   unused;
+    gckOS        os;
+    gctPOINTER * table;
+    gctUINT32 *  bitmap;
+    gctPOINTER   mutex;
+    gctUINT32    capacity;
+    gctUINT32    nextId;
+    gctUINT32    freeCount;
 }
 gcsINTEGERDB;
 
 gceSTATUS
 gckKERNEL_CreateIntegerDatabase(
     IN gckKERNEL Kernel,
+    IN gctUINT32 Capacity,
     OUT gctPOINTER * Database
     )
 {
     gceSTATUS status;
     gckINTEGERDB database = gcvNULL;
 
-    gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
+    gcmkHEADER_ARG("Kernel=%p Capacity=%u Datbase=%p", Kernel, Capacity, Database);
 
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
     gcmkVERIFY_ARGUMENT(Database != gcvNULL);
 
+    /* round up to 32 alignment. */
+    Capacity = (Capacity + 31) & ~31;
+
     /* Allocate a database. */
     gcmkONERROR(gckOS_Allocate(
         Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database));
@@ -5120,18 +4182,26 @@ gckKERNEL_CreateIntegerDatabase(
 
     /* Allocate a pointer table. */
     gcmkONERROR(gckOS_Allocate(
-        Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table));
+        Kernel->os,
+        gcmSIZEOF(gctPOINTER) * Capacity,
+        (gctPOINTER *)&database->table
+        ));
+
+    /* Allocate bitmap. */
+    gcmkONERROR(gckOS_Allocate(
+        Kernel->os, Capacity / 8, (gctPOINTER *)&database->bitmap));
 
-    gcmkONERROR(gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH));
+    gcmkONERROR(gckOS_ZeroMemory(database->bitmap, Capacity / 8));
 
     /* Allocate a database mutex. */
     gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex));
 
     /* Initialize. */
-    database->currentID = 0;
-    database->unused = gcdID_TABLE_LENGTH;
-    database->os = Kernel->os;
-    database->tableLen = gcdID_TABLE_LENGTH;
+    database->os        = Kernel->os;
+
+    database->nextId    = 0;
+    database->freeCount = Capacity;
+    database->capacity  = Capacity;
 
     *Database = database;
 
@@ -5144,10 +4214,15 @@ OnError:
     {
         if (database->table)
         {
-            gcmkOS_SAFE_FREE(Kernel->os, database->table);
+            gckOS_Free(Kernel->os, database->table);
+        }
+
+        if (database->bitmap)
+        {
+            gckOS_Free(Kernel->os, database->bitmap);
         }
 
-        gcmkOS_SAFE_FREE(Kernel->os, database);
+        gckOS_Free(Kernel->os, database);
     }
 
     gcmkFOOTER();
@@ -5162,19 +4237,20 @@ gckKERNEL_DestroyIntegerDatabase(
 {
     gckINTEGERDB database = Database;
 
-    gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database);
+    gcmkHEADER_ARG("Kernel=%p Datbase=%p", Kernel, Database);
 
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
     gcmkVERIFY_ARGUMENT(Database != gcvNULL);
 
     /* Destroy pointer table. */
     gcmkOS_SAFE_FREE(Kernel->os, database->table);
+    gcmkOS_SAFE_FREE(Kernel->os, database->bitmap);
 
     /* Destroy database mutex. */
     gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex));
 
     /* Destroy database. */
-    gcmkOS_SAFE_FREE(Kernel->os, database);
+    gckOS_Free(Kernel->os, database);
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
@@ -5189,87 +4265,91 @@ gckKERNEL_AllocateIntegerId(
 {
     gceSTATUS status;
     gckINTEGERDB database = Database;
-    gctUINT32 i, unused, currentID, tableLen;
-    gctPOINTER * table;
+    gctUINT32 pos;
+    gctUINT32 n, i;
     gckOS os = database->os;
-    gctBOOL acquired = gcvFALSE;
-
-    gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer);
 
-    gcmkVERIFY_ARGUMENT(Id != gcvNULL);
+    gcmkHEADER_ARG("Database=%p Pointer=%p", Database, Pointer);
 
     gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
-    acquired = gcvTRUE;
 
-    if (database->unused < 1)
+    if (database->freeCount < 1)
     {
+        gctPOINTER * table = gcvNULL;
+        gctUINT32 * bitmap = gcvNULL;
+        gctUINT32 expand;
+        gctUINT32 capacity;
+
+        expand = database->capacity < gcdID_TABLE_MAX_EXPAND
+               ? database->capacity : gcdID_TABLE_MAX_EXPAND;
+
+        capacity = database->capacity + expand;
+
         /* Extend table. */
         gcmkONERROR(
             gckOS_Allocate(os,
-                           gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH),
+                           gcmSIZEOF(gctPOINTER) * capacity,
                            (gctPOINTER *)&table));
 
-        gcmkONERROR(gckOS_ZeroMemory(table + database->tableLen,
-                                     gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH));
+        gcmkONERROR(
+            gckOS_Allocate(os, capacity / 32 * sizeof(gctUINT32), (gctPOINTER *)&bitmap));
+
+        gckOS_ZeroMemory(bitmap + database->capacity / 32, expand / 8);
 
         /* Copy data from old table. */
         gckOS_MemCopy(table,
                       database->table,
-                      database->tableLen * gcmSIZEOF(gctPOINTER));
+                      database->capacity * gcmSIZEOF(gctPOINTER));
+
+        gckOS_MemCopy(bitmap,
+                      database->bitmap,
+                      database->capacity / 32 * sizeof(gctUINT32));
 
-        gcmkOS_SAFE_FREE(os, database->table);
+        gckOS_Free(os, database->table);
+        gckOS_Free(os, database->bitmap);
 
         /* Update databse with new allocated table. */
-        database->table = table;
-        database->currentID = database->tableLen;
-        database->tableLen += gcdID_TABLE_LENGTH;
-        database->unused += gcdID_TABLE_LENGTH;
+        database->table      = table;
+        database->bitmap     = bitmap;
+        database->nextId     = database->capacity;
+        database->capacity   = capacity;
+        database->freeCount += expand;
     }
 
-    table = database->table;
-    currentID = database->currentID;
-    tableLen = database->tableLen;
-    unused = database->unused;
-
-    /* Connect id with pointer. */
-    table[currentID] = Pointer;
-
-    *Id = currentID + 1;
+    pos = database->nextId;
+    n = pos >> 5;
+    i = pos & 31;
 
-    /* Update the currentID. */
-    if (--unused > 0)
+    while (database->bitmap[n] & (1u << i))
     {
-        for (i = 0; i < tableLen; i++)
-        {
-            if (++currentID >= tableLen)
-            {
-                /* Wrap to the begin. */
-                currentID = 0;
-            }
+        pos++;
 
-            if (table[currentID] == gcvNULL)
-            {
-                break;
-            }
+        if (pos == database->capacity)
+        {
+            /* Wrap to the begin. */
+            pos = 0;
         }
+
+        n = pos >> 5;
+        i = pos & 31;
     }
 
-    database->table = table;
-    database->currentID = currentID;
-    database->tableLen = tableLen;
-    database->unused = unused;
+    /* Connect id with pointer. */
+    database->table[pos] = Pointer;
+    database->bitmap[n] |= (1u << i);
+
+    *Id = pos + 1;
+
+    database->nextId = (pos + 1) % database->capacity;
+    database->freeCount--;
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
-    acquired = gcvFALSE;
 
-    gcmkFOOTER_ARG("*Id=%d", *Id);
+    gcmkFOOTER_ARG("*Id=%u", *Id);
     return gcvSTATUS_OK;
 
 OnError:
-    if (acquired)
-    {
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
-    }
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
 
     gcmkFOOTER();
     return status;
@@ -5284,39 +4364,34 @@ gckKERNEL_FreeIntegerId(
     gceSTATUS status;
     gckINTEGERDB database = Database;
     gckOS os = database->os;
-    gctBOOL acquired = gcvFALSE;
+    gctUINT32 pos = Id - 1;
+    gctUINT32 n, i;
 
-    gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
+    gcmkHEADER_ARG("Database=%p Id=%d", Database, Id);
 
     gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
-    acquired = gcvTRUE;
 
-    if (!(Id > 0 && Id <= database->tableLen))
+    n = pos >> 5;
+    i = pos & 31;
+
+    if (pos >= database->capacity || (database->bitmap[n] & (1u << i)) == 0)
     {
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
         gcmkONERROR(gcvSTATUS_NOT_FOUND);
     }
 
-    Id -= 1;
+    /* Clear id. */
+    database->bitmap[n] &= ~(1u << i);
+    database->table[pos] = gcvNULL;
 
-    database->table[Id] = gcvNULL;
-
-    if (database->unused++ == 0)
-    {
-        database->currentID = Id;
-    }
+    ++database->freeCount;
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
-    acquired = gcvFALSE;
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if (acquired)
-    {
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
-    }
-
     gcmkFOOTER();
     return status;
 }
@@ -5330,46 +4405,32 @@ gckKERNEL_QueryIntegerId(
 {
     gceSTATUS status;
     gckINTEGERDB database = Database;
-    gctPOINTER pointer;
     gckOS os = database->os;
-    gctBOOL acquired = gcvFALSE;
+    gctUINT32 pos = Id - 1;
+    gctUINT32 n, i;
 
-    gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id);
+    gcmkHEADER_ARG("Database=%p Id=%d", Database, Id);
     gcmkVERIFY_ARGUMENT(Pointer != gcvNULL);
 
     gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE));
-    acquired = gcvTRUE;
 
-    if (!(Id > 0 && Id <= database->tableLen))
+    n = pos >> 5;
+    i = pos & 31;
+
+    if (pos >= database->capacity || (database->bitmap[n] & (1u << i)) == 0)
     {
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
         gcmkONERROR(gcvSTATUS_NOT_FOUND);
     }
 
-    Id -= 1;
-
-    pointer = database->table[Id];
+    *Pointer = database->table[pos];
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
-    acquired = gcvFALSE;
-
-    if (pointer)
-    {
-        *Pointer = pointer;
-    }
-    else
-    {
-        gcmkONERROR(gcvSTATUS_NOT_FOUND);
-    }
 
     gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer);
     return gcvSTATUS_OK;
 
 OnError:
-    if (acquired)
-    {
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex));
-    }
-
     gcmkFOOTER();
     return status;
 }
@@ -5385,10 +4446,9 @@ gckKERNEL_AllocateNameFromPointer(
     gctUINT32 name;
     gctPOINTER database = Kernel->db->pointerDatabase;
 
-    gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer);
+    gcmkHEADER_ARG("Kernel=%p Pointer=%p", Kernel, Pointer);
 
-    gcmkONERROR(
-        gckKERNEL_AllocateIntegerId(database, Pointer, &name));
+    gcmkONERROR(gckKERNEL_AllocateIntegerId(database, Pointer, &name));
 
     gcmkFOOTER_ARG("name=%d", name);
     return name;
@@ -5408,7 +4468,7 @@ gckKERNEL_QueryPointerFromName(
     gctPOINTER pointer = gcvNULL;
     gctPOINTER database = Kernel->db->pointerDatabase;
 
-    gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name);
+    gcmkHEADER_ARG("Kernel=%p Name=%d", Kernel, Name);
 
     /* Lookup in database to get pointer. */
     gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer));
@@ -5429,7 +4489,7 @@ gckKERNEL_DeleteName(
 {
     gctPOINTER database = Kernel->db->pointerDatabase;
 
-    gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name);
+    gcmkHEADER_ARG("Kernel=%p Name=%p", Kernel, Name);
 
     /* Free name if exists. */
     gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name));
@@ -5473,7 +4533,7 @@ gckKERNEL_CreateShBuffer(
     gceSTATUS status;
     gcsSHBUF_PTR shBuf = gcvNULL;
 
-    gcmkHEADER_ARG("Kernel=0x%X, Size=%u", Kernel, Size);
+    gcmkHEADER_ARG("Kernel=%p, Size=%u", Kernel, Size);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -5566,22 +4626,14 @@ gckKERNEL_DestroyShBuffer(
     gceSTATUS status;
     gcsSHBUF_PTR shBuf;
     gctINT32 oldValue = 0;
-    gctBOOL acquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u",
+    gcmkHEADER_ARG("Kernel=%p ShBuf=%u",
                    Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
     gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
 
-    /* Acquire mutex. */
-    gcmkONERROR(
-        gckOS_AcquireMutex(Kernel->os,
-                           Kernel->db->pointerDatabaseMutex,
-                           gcvINFINITE));
-    acquired = gcvTRUE;
-
     /* Find shared buffer structure. */
     gcmkONERROR(
         gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
@@ -5613,22 +4665,10 @@ gckKERNEL_DestroyShBuffer(
         gcmkOS_SAFE_FREE(Kernel->os, shBuf);
     }
 
-    /* Release the mutex. */
-    gcmkVERIFY_OK(
-        gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
-    acquired = gcvFALSE;
-
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if (acquired)
-    {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(
-            gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
-    }
-
     gcmkFOOTER();
     return status;
 }
@@ -5662,22 +4702,14 @@ gckKERNEL_MapShBuffer(
     gceSTATUS status;
     gcsSHBUF_PTR shBuf;
     gctINT32 oldValue = 0;
-    gctBOOL acquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u",
+    gcmkHEADER_ARG("Kernel=%p ShBuf=%u",
                    Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
     gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
 
-    /* Acquire mutex. */
-    gcmkONERROR(
-        gckOS_AcquireMutex(Kernel->os,
-                           Kernel->db->pointerDatabaseMutex,
-                           gcvINFINITE));
-    acquired = gcvTRUE;
-
     /* Find shared buffer structure. */
     gcmkONERROR(
         gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
@@ -5689,22 +4721,10 @@ gckKERNEL_MapShBuffer(
     /* Increase the reference count. */
     gckOS_AtomIncrement(Kernel->os, shBuf->reference, &oldValue);
 
-    /* Release the mutex. */
-    gcmkVERIFY_OK(
-        gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
-    acquired = gcvFALSE;
-
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if (acquired)
-    {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(
-            gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
-    }
-
     gcmkFOOTER();
     return status;
 }
@@ -5744,22 +4764,14 @@ gckKERNEL_WriteShBuffer(
 {
     gceSTATUS status;
     gcsSHBUF_PTR shBuf = gcvNULL;
-    gctBOOL acquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u",
+    gcmkHEADER_ARG("Kernel=%p ShBuf=%u UserData=%p ByteCount=%u",
                    Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
     gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
 
-    /* Acquire mutex. */
-    gcmkONERROR(
-        gckOS_AcquireMutex(Kernel->os,
-                           Kernel->db->pointerDatabaseMutex,
-                           gcvINFINITE));
-    acquired = gcvTRUE;
-
     /* Find shared buffer structure. */
     gcmkONERROR(
         gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
@@ -5789,11 +4801,6 @@ gckKERNEL_WriteShBuffer(
                                UserData,
                                ByteCount));
 
-    /* Release the mutex. */
-    gcmkVERIFY_OK(
-        gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
-    acquired = gcvFALSE;
-
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
@@ -5804,13 +4811,6 @@ OnError:
         shBuf->data = gcvNULL;
     }
 
-    if (acquired)
-    {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(
-            gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
-    }
-
     gcmkFOOTER();
     return status;
 }
@@ -5854,22 +4854,14 @@ gckKERNEL_ReadShBuffer(
     gceSTATUS status;
     gcsSHBUF_PTR shBuf;
     gctUINT32 bytes;
-    gctBOOL acquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%X ShBuf=%u UserData=0x%X ByteCount=%u",
+    gcmkHEADER_ARG("Kernel=%p ShBuf=%u UserData=%p ByteCount=%u",
                    Kernel, (gctUINT32)(gctUINTPTR_T) ShBuf, UserData, ByteCount);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
     gcmkVERIFY_ARGUMENT(ShBuf != gcvNULL);
 
-    /* Acquire mutex. */
-    gcmkONERROR(
-        gckOS_AcquireMutex(Kernel->os,
-                           Kernel->db->pointerDatabaseMutex,
-                           gcvINFINITE));
-    acquired = gcvTRUE;
-
     /* Find shared buffer structure. */
     gcmkONERROR(
         gckKERNEL_QueryIntegerId(Kernel->db->pointerDatabase,
@@ -5905,22 +4897,10 @@ gckKERNEL_ReadShBuffer(
     /* Return copied size. */
     *BytesRead = bytes;
 
-    /* Release the mutex. */
-    gcmkVERIFY_OK(
-        gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
-    acquired = gcvFALSE;
-
     gcmkFOOTER_ARG("*BytesRead=%u", bytes);
     return gcvSTATUS_OK;
 
 OnError:
-    if (acquired)
-    {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(
-            gckOS_ReleaseMutex(Kernel->os, Kernel->db->pointerDatabaseMutex));
-    }
-
     gcmkFOOTER();
     return status;
 }
@@ -6007,8 +4987,15 @@ gckFENCE_Create(
     )
 {
     gceSTATUS status;
+    gcePOOL pool = gcvPOOL_DEFAULT;
     gckFENCE fence = gcvNULL;
-    gctSIZE_T pageSize = 4096;
+    gctSIZE_T size = 8;
+    gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+    allocFlag |= gcvALLOC_FLAG_CACHEABLE;
+#endif
+
 
     gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsFENCE), (gctPOINTER *)&fence));
     gcmkONERROR(gckOS_ZeroMemory(fence, gcmSIZEOF(gcsFENCE)));
@@ -6016,55 +5003,32 @@ gckFENCE_Create(
 
     fence->kernel = Kernel;
 
-#if USE_KERNEL_VIRTUAL_BUFFERS
-    if (Kernel->virtualCommandBuffer)
-    {
-        gcmkONERROR(gckKERNEL_AllocateVirtualMemory(
-            Kernel,
-            gcvFALSE,
-            gcvFALSE,
-            &pageSize,
-            &fence->physical,
-            &fence->logical
-            ));
-
-        gcmkONERROR(gckKERNEL_GetGPUAddress(
-            Kernel,
-            fence->logical,
-            gcvFALSE,
-            fence->physical,
-            &fence->address
-            ));
-    }
-    else
-#endif
-    {
-        gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
-
-#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
-        allocFlag |= gcvALLOC_FLAG_CACHEABLE;
-#endif
-
-        gcmkONERROR(gckOS_AllocateNonPagedMemory(
-            Os,
-            gcvFALSE,
-            allocFlag,
-            &pageSize,
-            &fence->physical,
-            &fence->logical
-            ));
+    /* Allocate video memory node for fence. */
+    gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+        Kernel,
+        64,
+        gcvVIDMEM_TYPE_FENCE,
+        allocFlag,
+        &size,
+        &pool,
+        &fence->videoMem
+        ));
 
-        gcmkONERROR(gckHARDWARE_ConvertLogical(
-            Kernel->hardware,
-            fence->logical,
-            gcvFALSE,
-            &fence->address
-            ));
+    /* Lock for GPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_Lock(
+        Kernel,
+        fence->videoMem,
+        &fence->address
+        ));
 
-        gcmkONERROR(gckMMU_FillFlatMapping(
-            Kernel->mmu, fence->address, pageSize
-            ));
-    }
+    /* Lock for kernel side CPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+        Kernel,
+        fence->videoMem,
+        gcvFALSE,
+        gcvFALSE,
+        &fence->logical
+        ));
 
     gcsLIST_Init(&fence->waitingList);
 
@@ -6093,25 +5057,26 @@ gckFENCE_Destory(
 
     if (Fence->logical)
     {
-#if USE_KERNEL_VIRTUAL_BUFFERS
-        if (Fence->kernel->virtualCommandBuffer)
-        {
-            gcmkVERIFY_OK(gckKERNEL_FreeVirtualMemory(
-                Fence->physical,
-                Fence->logical,
-                gcvFALSE
-                ));
-        }
-        else
-#endif
-        {
-            gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
-                Os,
-                4096,
-                Fence->physical,
-                Fence->logical
-                ));
-        }
+        gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+            Fence->kernel,
+            Fence->videoMem,
+            0,
+            gcvFALSE
+            ));
+
+        /* Synchronueous unlock. */
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Unlock(
+            Fence->kernel,
+            Fence->videoMem,
+            0,
+            gcvNULL
+            ));
+
+        /* Free video memory. */
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+            Fence->kernel,
+            Fence->videoMem
+            ));
     }
 
     gcmkOS_SAFE_FREE(Os, Fence);
@@ -6143,7 +5108,7 @@ gckFENCE_Signal(
 
     gcmkLIST_FOR_EACH_SAFE(nodeHead, nodeTemp, list)
     {
-        sync = gcmCONTAINEROF(nodeHead, _gcsFENCE_SYNC, head);
+        sync = gcmCONTAINEROF(nodeHead, struct _gcsFENCE_SYNC, head);
 
         /* Signal all nodes which are complete. */
         if (sync->commitStamp <= stamp && sync->inList)
@@ -6172,19 +5137,27 @@ gckDEVICE_Construct(
 {
     gceSTATUS status;
     gckDEVICE device;
-    gctUINT i;
+    gctUINT i, j;
 
     gcmkHEADER();
 
     gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsDEVICE), (gctPOINTER *)&device));
 
+    gckOS_ZeroMemory(device, gcmSIZEOF(gcsDEVICE));
+
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
         device->coreInfoArray[i].type = gcvHARDWARE_INVALID;
+
+        /* Initialize device SRAM. */
+        for (j = 0; j < gcvSRAM_COUNT; j++)
+        {
+            device->sRAMBases[i][j] = gcvINVALID_PHYSICAL_ADDRESS;
+            device->sRAMSizes[i][j] = 0;
+        }
     }
-    device->defaultHwType = gcvHARDWARE_INVALID;
 
-    gckOS_ZeroMemory(device, gcmSIZEOF(gcsDEVICE));
+    device->defaultHwType = gcvHARDWARE_INVALID;
 
     gcmkONERROR(gckOS_CreateMutex(Os, &device->stuckDumpMutex));
     gcmkONERROR(gckOS_CreateMutex(Os, &device->commitMutex));
@@ -6226,6 +5199,9 @@ gckDEVICE_AddCore(
     gceHARDWARE_TYPE defaultHwType;
     gckKERNEL kernel;
 
+    gcmkHEADER_ARG("Device=%p Core=%d ChipID=%d Context=%p Kernel=%p",
+        Device, Core, ChipID, Context, Kernel);
+
     gcmkASSERT(Device->coreNum < gcvCORE_COUNT);
 
     if (Core >= gcvCORE_MAJOR && Core <= gcvCORE_3D_MAX)
@@ -6249,7 +5225,9 @@ gckDEVICE_AddCore(
         Device->database = kernel->db;
     }
 
-    kernelType =  _GetHardwareType(kernel);
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(kernel,
+                                  &kernelType));
 
     if (kernelType >= gcvHARDWARE_NUM_TYPES)
     {
@@ -6302,9 +5280,11 @@ gckDEVICE_AddCore(
         Device->defaultHwType = defaultHwType;
     }
 
+    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
+    gcmkFOOTER();
     return status;
 }
 
@@ -6314,16 +5294,18 @@ gckDEVICE_ChipInfo(
     IN gcsHAL_INTERFACE_PTR Interface
     )
 {
-    gctUINT i;
-    gcsCORE_INFO * info = Device->coreInfoArray;
-
-    for (i = 0; i < Device->coreNum; i++)
     {
-        Interface->u.ChipInfo.types[i] = info[i].type;
-        Interface->u.ChipInfo.ids[i] = info[i].chipID;
-    }
+        gctUINT i;
+        gcsCORE_INFO * info = Device->coreInfoArray;
+
+        for (i = 0; i < Device->coreNum; i++)
+        {
+            Interface->u.ChipInfo.types[i] = info[i].type;
+            Interface->u.ChipInfo.ids[i] = info[i].chipID;
+        }
 
-    Interface->u.ChipInfo.count = Device->coreNum;
+        Interface->u.ChipInfo.count = Device->coreNum;
+    }
 
     return gcvSTATUS_OK;
 }
@@ -6449,12 +5431,12 @@ gckDEVICE_Dispatch(
 #if gcdENABLE_VG
         if (kernel->vg)
         {
-            status = gckVGKERNEL_Dispatch(kernel, gcvTRUE, Interface);
+            status = gckVGKERNEL_Dispatch(kernel, Interface);
         }
         else
 #endif
         {
-            status = gckKERNEL_Dispatch(kernel, Device, gcvTRUE, Interface);
+            status = gckKERNEL_Dispatch(kernel, Device, Interface);
         }
 
         /* Interface->status is handled in gckKERNEL_Dispatch(). */
@@ -6495,54 +5477,6 @@ gckDEVICE_SetMMU(
     return gcvSTATUS_OK;
 }
 
-/*******************************************************************************
-**
-**  gckDEVICE_QueryGPUAddress
-**
-**  Search GPUAddress in other core's address space, whose type is same as current
-**  core. It is used to find correct command buffer which is shared by mulitple
-**  core.
-**
-*/
-gceSTATUS
-gckDEVICE_QueryGPUAddress(
-    IN gckDEVICE Device,
-    IN gckKERNEL Kernel,
-    IN gctUINT32 GPUAddress,
-    OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
-    )
-{
-    gceSTATUS status = gcvSTATUS_NOT_FOUND;
-    gctUINT i;
-    gceHARDWARE_TYPE kernelType;
-
-    kernelType = _GetHardwareType(Kernel);
-
-    if (Device != gcvNULL)
-    {
-        for (i = 0; i < Device->coreNum; i++)
-        {
-            if (Device->coreInfoArray[i].type == kernelType)
-            {
-                /* Search other core's command buffer list whose type is same. */
-                status = gckKERNEL_QueryGPUAddress(
-                            Device->coreInfoArray[i].kernel, GPUAddress, Buffer);
-
-                if (gcmIS_SUCCESS(status))
-                {
-                    break;
-                }
-            }
-        }
-    }
-    else
-    {
-        status = gckKERNEL_QueryGPUAddress(Kernel, GPUAddress, Buffer);
-    }
-
-    return status;
-}
-
 #if gcdENABLE_TRUST_APPLICATION
 gceSTATUS
 gckKERNEL_MapInTrustApplicaiton(
@@ -6579,7 +5513,7 @@ gckKERNEL_MapInTrustApplicaiton(
     for (i = 0; i < PageCount; i++)
     {
         gctPHYS_ADDR_T phys;
-        status = gckOS_PhysicalToPhysicalAddress(
+        status = gckOS_GetPhysicalFromHandle(
             Kernel->os,
             Physical,
             i * 4096,
@@ -6615,23 +5549,22 @@ gckKERNEL_MapInTrustApplicaiton(
     gcmkVERIFY_OK(gckOS_Free(
         Kernel->os,
         physicalArrayLogical
-        ))
+        ));
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if(physicalArrayLogical != gcvNULL)
+    if (physicalArrayLogical != gcvNULL)
+    {
         gcmkVERIFY_OK(gckOS_Free(
             Kernel->os,
             (gctPOINTER)physicalArrayLogical
             ));
+    }
+
     gcmkFOOTER();
     return status;
 }
 #endif
 
-/*******************************************************************************
-***** Test Code ****************************************************************
-*******************************************************************************/
-
index 1aad1ef..c877394 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 
 #include "gc_hal.h"
 #include "gc_hal_kernel_hardware.h"
+#include "gc_hal_kernel_hardware_fe.h"
 #include "gc_hal_driver.h"
 #include "gc_hal_kernel_mutex.h"
 #include "gc_hal_metadata.h"
-#include "gc_hal_kernel_buffer.h"
-
 
 #if gcdENABLE_VG
 #include "gc_hal_kernel_vg.h"
@@ -78,6 +77,80 @@ extern "C" {
 
 /*******************************************************************************
 ***** New MMU Defination *******************************************************/
+
+#if gcdENABLE_MMU_1KMODE
+/* 1k mode */
+#define gcdMMU_MTLB_SHIFT           24
+#define gcdMMU_STLB_4K_SHIFT        12
+#define gcdMMU_STLB_64K_SHIFT       16
+#define gcdMMU_STLB_1M_SHIFT        20
+#define gcdMMU_STLB_16M_SHIFT       24
+
+#define gcdMMU_MTLB_BITS            (32 - gcdMMU_MTLB_SHIFT)
+#define gcdMMU_PAGE_4K_BITS         gcdMMU_STLB_4K_SHIFT
+#define gcdMMU_STLB_4K_BITS         (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_4K_BITS)
+#define gcdMMU_PAGE_64K_BITS        gcdMMU_STLB_64K_SHIFT
+#define gcdMMU_STLB_64K_BITS        (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_64K_BITS)
+#define gcdMMU_PAGE_1M_BITS         gcdMMU_STLB_1M_SHIFT
+#define gcdMMU_STLB_1M_BITS        (32 - gcdMMU_MTLB_BITS - gcdMMU_PAGE_1M_BITS)
+#define gcdMMU_PAGE_16M_BITS        gcdMMU_STLB_16M_SHIFT
+#define gcdMMU_STLB_16M_BITS        4
+
+
+#define gcdMMU_MTLB_ENTRY_NUM       (1 << gcdMMU_MTLB_BITS)
+#define gcdMMU_MTLB_SIZE            (gcdMMU_MTLB_ENTRY_NUM << 2)
+#define gcdMMU_STLB_4K_ENTRY_NUM    (1 << gcdMMU_STLB_4K_BITS)
+#define gcdMMU_STLB_4K_SIZE         (gcdMMU_STLB_4K_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_4K_SIZE         (1 << gcdMMU_STLB_4K_SHIFT)
+#define gcdMMU_STLB_64K_ENTRY_NUM   (1 << gcdMMU_STLB_64K_BITS)
+#define gcdMMU_STLB_64K_SIZE        (gcdMMU_STLB_64K_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_64K_SIZE        (1 << gcdMMU_STLB_64K_SHIFT)
+#define gcdMMU_STLB_1M_ENTRY_NUM   (1 << gcdMMU_STLB_1M_BITS)
+#define gcdMMU_STLB_1M_SIZE        (gcdMMU_STLB_1M_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_1M_SIZE        (1 << gcdMMU_STLB_1M_SHIFT)
+#define gcdMMU_STLB_16M_ENTRY_NUM   (1 << gcdMMU_STLB_16M_BITS)
+#define gcdMMU_STLB_16M_SIZE        (gcdMMU_STLB_16M_ENTRY_NUM << 2)
+#define gcdMMU_PAGE_16M_SIZE        (1 << gcdMMU_STLB_16M_SHIFT)
+
+
+#define gcdMMU_MTLB_MASK            (~((1U << gcdMMU_MTLB_SHIFT)-1))
+#define gcdMMU_STLB_4K_MASK         ((~0U << gcdMMU_STLB_4K_SHIFT) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_4K_MASK         (gcdMMU_PAGE_4K_SIZE - 1)
+#define gcdMMU_STLB_64K_MASK        ((~((1U << gcdMMU_STLB_64K_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_64K_MASK        (gcdMMU_PAGE_64K_SIZE - 1)
+#define gcdMMU_STLB_1M_MASK        ((~((1U << gcdMMU_STLB_1M_SHIFT)-1)) ^ gcdMMU_MTLB_MASK)
+#define gcdMMU_PAGE_1M_MASK        (gcdMMU_PAGE_1M_SIZE - 1)
+#define gcdMMU_STLB_16M_MASK        0x0F000000
+#define gcdMMU_PAGE_16M_MASK        (gcdMMU_PAGE_16M_SIZE - 1)
+
+
+/* Page offset definitions. */
+#define gcdMMU_OFFSET_4K_BITS       (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_4K_BITS)
+#define gcdMMU_OFFSET_4K_MASK       ((1U << gcdMMU_OFFSET_4K_BITS) - 1)
+#define gcdMMU_OFFSET_64K_BITS      (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_64K_BITS)
+#define gcdMMU_OFFSET_64K_MASK      ((1U << gcdMMU_OFFSET_64K_BITS) - 1)
+#define gcdMMU_OFFSET_1M_BITS      (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_1M_BITS)
+#define gcdMMU_OFFSET_1M_MASK      ((1U << gcdMMU_OFFSET_1M_BITS) - 1)
+#define gcdMMU_OFFSET_16M_BITS      (32 - gcdMMU_MTLB_BITS)
+#define gcdMMU_OFFSET_16M_MASK      ((1U << gcdMMU_OFFSET_16M_BITS) - 1)
+
+
+#define gcdMMU_MTLB_ENTRY_HINTS_BITS 6
+#define gcdMMU_MTLB_ENTRY_STLB_MASK  (~((1U << gcdMMU_MTLB_ENTRY_HINTS_BITS) - 1))
+
+#define gcdMMU_MTLB_PRESENT         0x00000001
+#define gcdMMU_MTLB_EXCEPTION       0x00000002
+#define gcdMMU_MTLB_4K_PAGE         (0 << 2)
+#define gcdMMU_MTLB_64K_PAGE        (1 << 2)
+#define gcdMMU_MTLB_1M_PAGE         (2 << 2)
+#define gcdMMU_MTBL_16M_PAGE        (3 << 2)
+
+#define gcdMMU_STLB_PRESENT         0x00000001
+#define gcdMMU_STLB_EXCEPTION       0x00000002
+#define gcdMMU_STBL_WRITEABLE       0x00000004
+
+#else /* 4K mode */
+
 #define gcdMMU_MTLB_SHIFT           22
 #define gcdMMU_STLB_4K_SHIFT        12
 #define gcdMMU_STLB_64K_SHIFT       16
@@ -106,19 +179,26 @@ extern "C" {
 /* Page offset definitions. */
 #define gcdMMU_OFFSET_4K_BITS       (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_4K_BITS)
 #define gcdMMU_OFFSET_4K_MASK       ((1U << gcdMMU_OFFSET_4K_BITS) - 1)
-#define gcdMMU_OFFSET_16K_BITS      (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS)
-#define gcdMMU_OFFSET_16K_MASK      ((1U << gcdMMU_OFFSET_16K_BITS) - 1)
+#define gcdMMU_OFFSET_64K_BITS      (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_64K_BITS)
+#define gcdMMU_OFFSET_64K_MASK      ((1U << gcdMMU_OFFSET_64K_BITS) - 1)
 
 #define gcdMMU_MTLB_ENTRY_HINTS_BITS 6
 #define gcdMMU_MTLB_ENTRY_STLB_MASK  (~((1U << gcdMMU_MTLB_ENTRY_HINTS_BITS) - 1))
 
 #define gcdMMU_MTLB_PRESENT         0x00000001
 #define gcdMMU_MTLB_EXCEPTION       0x00000002
-#define gcdMMU_MTLB_4K_PAGE         0x00000000
+#define gcdMMU_MTLB_4K_PAGE         (0 << 2)
+#define gcdMMU_MTLB_64K_PAGE        (1 << 2)
+
 
 #define gcdMMU_STLB_PRESENT         0x00000001
 #define gcdMMU_STLB_EXCEPTION       0x00000002
-#define gcdMMU_STLB_4K_PAGE         0x00000000
+#define gcdMMU_STLB_WRITEABLE       0x00000004
+
+#endif
+
+#define gcd1M_PAGE_SIZE (1 << 20)
+#define gcd1M_PAGE_SHIFT 20
 
 /*******************************************************************************
 ***** Stuck Dump Level ********************************************************/
@@ -140,81 +220,23 @@ extern "C" {
 #define gcvSTUCK_DUMP_ALL_COMMAND   4
 
 /*******************************************************************************
-***** Process Secure Cache ****************************************************/
-
-#define gcdSECURE_CACHE_LRU         1
-#define gcdSECURE_CACHE_LINEAR      2
-#define gcdSECURE_CACHE_HASH        3
-#define gcdSECURE_CACHE_TABLE       4
+***** Page table **************************************************************/
 
 #define gcvPAGE_TABLE_DIRTY_BIT_OTHER   (1 << 0)
 #define gcvPAGE_TABLE_DIRTY_BIT_FE      (1 << 1)
 
-typedef struct _gcskLOGICAL_CACHE * gcskLOGICAL_CACHE_PTR;
-typedef struct _gcskLOGICAL_CACHE   gcskLOGICAL_CACHE;
-struct _gcskLOGICAL_CACHE
-{
-    /* Logical address. */
-    gctPOINTER                      logical;
-
-    /* DMAable address. */
-    gctUINT32                       dma;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-    /* Pointer to the previous and next hash tables. */
-    gcskLOGICAL_CACHE_PTR           nextHash;
-    gcskLOGICAL_CACHE_PTR           prevHash;
-#endif
-
-#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
-    /* Pointer to the previous and next slot. */
-    gcskLOGICAL_CACHE_PTR           next;
-    gcskLOGICAL_CACHE_PTR           prev;
-#endif
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_LINEAR
-    /* Time stamp. */
-    gctUINT64                       stamp;
-#endif
-};
-
-typedef struct _gcskSECURE_CACHE * gcskSECURE_CACHE_PTR;
-typedef struct _gcskSECURE_CACHE
-{
-    /* Cache memory. */
-    gcskLOGICAL_CACHE               cache[1 + gcdSECURE_CACHE_SLOTS];
-
-    /* Last known index for LINEAR mode. */
-    gcskLOGICAL_CACHE_PTR           cacheIndex;
-
-    /* Current free slot for LINEAR mode. */
-    gctUINT32                       cacheFree;
-
-    /* Time stamp for LINEAR mode. */
-    gctUINT64                       cacheStamp;
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-    /* Hash table for HASH mode. */
-    gcskLOGICAL_CACHE              hash[256];
-#endif
-}
-gcskSECURE_CACHE;
-
 /*******************************************************************************
 ***** Process Database Management *********************************************/
 
 typedef enum _gceDATABASE_TYPE
 {
     gcvDB_VIDEO_MEMORY = 1,             /* Video memory created. */
-    gcvDB_COMMAND_BUFFER,               /* Command Buffer. */
     gcvDB_NON_PAGED,                    /* Non paged memory. */
-    gcvDB_CONTIGUOUS,                   /* Contiguous memory. */
     gcvDB_SIGNAL,                       /* Signal. */
     gcvDB_VIDEO_MEMORY_LOCKED,          /* Video memory locked. */
     gcvDB_CONTEXT,                      /* Context */
     gcvDB_IDLE,                         /* GPU idle. */
     gcvDB_MAP_MEMORY,                   /* Map memory */
-    gcvDB_MAP_USER_MEMORY,              /* Map user memory */
     gcvDB_SHBUF,                        /* Shared buffer. */
 
     gcvDB_NUM_TYPES,
@@ -266,11 +288,9 @@ typedef struct _gcsDATABASE
     /* Sizes to query. */
     gcsDATABASE_COUNTERS                vidMem;
     gcsDATABASE_COUNTERS                nonPaged;
-    gcsDATABASE_COUNTERS                contiguous;
-    gcsDATABASE_COUNTERS                mapUserMemory;
     gcsDATABASE_COUNTERS                mapMemory;
 
-    gcsDATABASE_COUNTERS                vidMemType[gcvSURF_NUM_TYPES];
+    gcsDATABASE_COUNTERS                vidMemType[gcvVIDMEM_TYPE_COUNT];
     /* Counter for each video memory pool. */
     gcsDATABASE_COUNTERS                vidMemPool[gcvPOOL_NUMBER_OF_POOLS];
     gctPOINTER                          counterMutex;
@@ -282,17 +302,8 @@ typedef struct _gcsDATABASE
     /* Pointer to database. */
     gcsDATABASE_RECORD_PTR              list[48];
 
-#if gcdSECURE_USER
-    /* Secure cache. */
-    gcskSECURE_CACHE                    cache;
-#endif
-
     gctPOINTER                          handleDatabase;
     gctPOINTER                          handleDatabaseMutex;
-
-#if gcdPROCESS_ADDRESS_SPACE
-    gckMMU                              mmu;
-#endif
 }
 gcsDATABASE;
 
@@ -390,37 +401,24 @@ gckKERNEL_FindHandleDatbase(
     OUT gctPOINTER * HandleDatabaseMutex
     );
 
-gceSTATUS
-gckKERNEL_GetProcessMMU(
-    IN gckKERNEL Kernel,
-    OUT gckMMU * Mmu
-    );
-
-gceSTATUS
-gckMMU_FlatMapping(
-    IN gckMMU Mmu,
-    IN gctUINT32 Physical,
-    IN gctUINT32 NumPages
-    );
-
 gceSTATUS
 gckMMU_GetPageEntry(
     IN gckMMU Mmu,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctUINT32_PTR *PageTable
     );
 
 gceSTATUS
-gckMMU_FreePagesEx(
+gckMMU_SetupPerHardware(
     IN gckMMU Mmu,
-    IN gctUINT32 Address,
-    IN gctSIZE_T PageCount
+    IN gckHARDWARE Hardware,
+    IN gckDEVICE Device
     );
 
 gceSTATUS
-gckMMU_AttachHardware(
-    IN gckMMU Mmu,
-    IN gckHARDWARE Hardware
+gckMMU_SetupDynamicSpace(
+    IN gckMMU Mmu
     );
 
 void
@@ -431,6 +429,7 @@ gckMMU_DumpRecentFreedAddress(
 gceSTATUS
 gckKERNEL_CreateIntegerDatabase(
     IN gckKERNEL Kernel,
+    IN gctUINT32 Capacity,
     OUT gctPOINTER * Database
     );
 
@@ -479,16 +478,6 @@ gckKERNEL_DeleteName(
     IN gctUINT32 Name
     );
 
-#if gcdSECURE_USER
-/* Get secure cache from the process database. */
-gceSTATUS
-gckKERNEL_GetProcessDBCache(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    OUT gcskSECURE_CACHE_PTR * Cache
-    );
-#endif
-
 /*******************************************************************************
 ********* Timer Management ****************************************************/
 typedef struct _gcsTIMER *           gcsTIMER_PTR;
@@ -518,42 +507,19 @@ struct _gckDB
     gctUINT64                   idleTime;
     gctUINT64                   lastSlowdown;
     gctUINT64                   lastSlowdownIdle;
+
     gctPOINTER                  nameDatabase;
     gctPOINTER                  nameDatabaseMutex;
 
     gctPOINTER                  pointerDatabase;
-    gctPOINTER                  pointerDatabaseMutex;
 
-    gcsLISTHEAD                 onFaultVidmemList;
-    gctPOINTER                  onFaultVidmemListMutex;
+    gcsLISTHEAD                 videoMemList;
+    gctPOINTER                  videoMemListMutex;
 };
 
-typedef struct _gckVIRTUAL_BUFFER * gckVIRTUAL_BUFFER_PTR;
-typedef struct _gckVIRTUAL_BUFFER
-{
-    gctPHYS_ADDR                physical;
-    gctPOINTER                  userLogical;
-    gctPOINTER                  kernelLogical;
-    gctSIZE_T                   bytes;
-    gctSIZE_T                   pageCount;
-    gctPOINTER                  pageTable;
-    gctUINT32                   gpuAddress;
-    gctUINT                     pid;
-    gckKERNEL                   kernel;
-#if gcdPROCESS_ADDRESS_SPACE
-    gckMMU                      mmu;
-#endif
-}
-gckVIRTUAL_BUFFER;
+typedef struct _gckCOMMAND *        gckCOMMAND;
 
-typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR;
-typedef struct _gckVIRTUAL_COMMAND_BUFFER
-{
-    gckVIRTUAL_BUFFER               virtualBuffer;
-    gckVIRTUAL_COMMAND_BUFFER_PTR   next;
-    gckVIRTUAL_COMMAND_BUFFER_PTR   prev;
-}
-gckVIRTUAL_COMMAND_BUFFER;
+typedef struct _gckEVENT *      gckEVENT;
 
 /* gckKERNEL object. */
 struct _gckKERNEL
@@ -564,21 +530,25 @@ struct _gckKERNEL
     /* Pointer to gckOS object. */
     gckOS                       os;
 
-    /* Core */
-    gceCORE                     core;
+    /* Pointer to gckDEVICE object. */
+    gckDEVICE                   device;
 
     /* Pointer to gckHARDWARE object. */
     gckHARDWARE                 hardware;
 
-    /* Pointer to gckCOMMAND object. */
-    gckCOMMAND                  command;
+    /* Core */
+    gceCORE                     core;
+    gctUINT                     chipID;
 
-    /* Pointer to gckEVENT object. */
+    /* Main command module, event and context. */
+    gckCOMMAND                  command;
     gckEVENT                    eventObj;
-
-    /* Pointer to context. */
     gctPOINTER                  context;
 
+    /* Async FE command and event modules. */
+    gckCOMMAND                  asyncCommand;
+    gckEVENT                    asyncEvent;
+
     /* Pointer to gckMMU object. */
     gckMMU                      mmu;
 
@@ -610,14 +580,6 @@ struct _gckKERNEL
     gckVGKERNEL                 vg;
 #endif
 
-    /* Virtual command buffer list. */
-    gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead;
-    gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail;
-    gctPOINTER                    virtualBufferLock;
-
-    /* Enable virtual command buffer. */
-    gctBOOL                     virtualCommandBuffer;
-
 #if gcdDVFS
     gckDVFS                     dvfs;
 #endif
@@ -649,17 +611,21 @@ struct _gckKERNEL
     gctUINT32                   restoreAddress;
     gctINT32                    restoreMask;
 
-    /* 3DBLIT */
-    gckASYNC_COMMAND            asyncCommand;
-    gckEVENT                    asyncEvent;
-
-    /* Pointer to gckDEVICE object. */
-    gckDEVICE                   device;
-
-    gctUINT                     chipID;
+    gckVIDMEM_BLOCK             vidMemBlock;
+    gctPOINTER                  vidMemBlockMutex;
 
     gctUINT32                   contiguousBaseAddress;
     gctUINT32                   externalBaseAddress;
+    gctUINT32                   internalBaseAddress;
+
+    /* Per core SRAM description. */
+    gctUINT32                   sRAMIndex;
+    gckVIDMEM                   sRAMVideoMem[gcvSRAM_COUNT];
+    gctPHYS_ADDR                sRAMPhysical[gcvSRAM_COUNT];
+    gctUINT32                   sRAMBaseAddress[gcvSRAM_COUNT];
+    gctUINT32                   sRAMSizes[gcvSRAM_COUNT];
+    /* SRAM mode. */
+    gctUINT32                   sRAMNonExclusive;
 };
 
 struct _FrequencyHistory
@@ -689,8 +655,7 @@ typedef struct _gcsFENCE
     gckKERNEL                   kernel;
 
     /* Fence location. */
-    gctPHYS_ADDR                physical;
-    gctPHYS_ADDR                physHandle;
+    gckVIDMEM_NODE              videoMem;
     gctPOINTER                  logical;
     gctUINT32                   address;
 
@@ -715,6 +680,15 @@ typedef struct _gcsFENCE_SYNC
 }
 gcsFENCE_SYNC;
 
+typedef struct _gcsCOMMAND_QUEUE
+{
+    gctSIGNAL               signal;
+    gckVIDMEM_NODE          videoMem;
+    gctPOINTER              logical;
+    gctUINT32               address;
+}
+gcsCOMMAND_QUEUE;
+
 /* gckCOMMAND object. */
 struct _gckCOMMAND
 {
@@ -725,6 +699,8 @@ struct _gckCOMMAND
     gckKERNEL                   kernel;
     gckOS                       os;
 
+    gceHW_FE_TYPE               feType;
+
     /* Number of bytes per page. */
     gctUINT32                   pageSize;
 
@@ -750,21 +726,14 @@ struct _gckCOMMAND
     /* Command queue power semaphore. */
     gctPOINTER                  powerSemaphore;
 
-    /* Current command queue. */
-    struct _gcskCOMMAND_QUEUE
-    {
-        gctSIGNAL               signal;
-        gctPHYS_ADDR            physical;
-        gctPOINTER              logical;
-        gctUINT32               address;
-    }
-    queues[gcdCOMMAND_QUEUES];
+    /* Command queues. */
+    gcsCOMMAND_QUEUE            queues[gcdCOMMAND_QUEUES];
 
-    gctPHYS_ADDR                virtualMemory;
-    gctPHYS_ADDR                physHandle;
-    gctUINT32                   physical;
+    /* Current queue. */
+    gckVIDMEM_NODE              videoMem;
     gctPOINTER                  logical;
     gctUINT32                   address;
+
     gctUINT32                   offset;
     gctINT                      index;
 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
@@ -779,15 +748,89 @@ struct _gckCOMMAND
     gctPOINTER                  stateMap;
 
     /* Pointer to last WAIT command. */
-    gctUINT32                   waitPhysical;
-    gctPOINTER                  waitLogical;
-    gctUINT32                   waitAddress;
-    gctUINT32                   waitSize;
-    gctUINT32                   waitOffset;
+    /* Wait-Link FE only. */
+    struct
+    {
+        gckVIDMEM_NODE          videoMem;
+        gctUINT32               offset;
+        gctPOINTER              logical;
+        gctUINT32               address;
+        gctUINT32               size;
+    }
+    waitPos;
+
+    /* MCFE. */
+    gctUINT32                   totalSemaId;
+
+    /*
+     * freeSemaId   ------>  [pendingSema]
+     * ^                    freePos -->+ +
+     * |                    ^          | |
+     * |                    |          | |
+     * |                    nextPos ---+ |
+     * |                                 |
+     * |                                 |
+     * |                                 v
+     * nextSemaId <----------------------+
+     *
+     * Terminology:
+     * 'freeSemaId': the top (final) free sema id can be used, signaled already.
+     * 'nextSemaId': the next sema id to be used.
+     * 'pendingSema': the used semaphores which are tracked in the ring.
+     *
+     * 3 Id sections:
+     * Id(s) between 'nextSemaId' and 'freeSemaId':
+     * Available for immediate use.
+     *
+     * Id(s) between 'freeSemaId' (exclusive) and 'pendingSema':
+     * To be signed, will be available to use later.
+     *
+     * Id(s) between 'pendingSema' and 'nextSemaId':
+     * The semaphores just used, not tracking in pendingSema ring.
+     *
+     * Conditions:
+     * 'nextSemaId' = 'freeSemaId':
+     * Using the final free semaphore, means the ring is full of used ones.
+     *
+     * 'freeSemaId' + 1 = 'nextSemaId':
+     * Can use 'freeSema' + 1 to 'freeSema'(loop back), means empty ring,
+     * ie, no used one.
+     */
+
+    /* MCFE semaphore id tracking ring. */
+    gctUINT32                   nextSemaId;
+    gctUINT32                   freeSemaId;
+
+    gctUINT32                   semaMinThreshhold;
+
+    /* pending semaphore id tracking ring. */
+    struct
+    {
+        gctUINT32               semaId;
+        gctSIGNAL               signal;
+    }
+    pendingSema[8];
+
+    gctUINT32                   nextPendingPos;
+    gctUINT32                   freePendingPos;
+
+    /* semaphore id (array index) to handle value map. */
+    gctUINT32 *                 semaHandleMap;
+
+    /*
+     * Dirty channels, ie channels ever submitted commands.
+     * Need sync to (send semaphore to) system channel.
+     */
+    gctUINT64                   dirtyChannel[2];
+
+    /*
+     * Sync channels, need sync from (wait semaphore from) the system
+     * channel before its own jobs.
+     */
+    gctUINT64                   syncChannel[2];
 
     /* Command buffer alignment. */
     gctUINT32                   alignment;
-    gctUINT32                   reservedHead;
 
     /* Commit counter. */
     gctPOINTER                  atomCommit;
@@ -795,39 +838,13 @@ struct _gckCOMMAND
     /* Kernel process ID. */
     gctUINT32                   kernelProcessID;
 
-    /* End Event signal. */
-    gctSIGNAL                   endEventSignal;
-
-#if gcdSECURE_USER
-    /* Hint array copy buffer. */
-    gctBOOL                     hintArrayAllocated;
-    gctUINT                     hintArraySize;
-    gctUINT32_PTR               hintArray;
-#endif
-
-#if gcdPROCESS_ADDRESS_SPACE
-    gckMMU                      currentMmu;
-#endif
-
 #if gcdRECORD_COMMAND
     gckRECORDER                 recorder;
 #endif
 
-    gctPOINTER                  kList;
-
     gckFENCE                    fence;
 
-    /* For getting state from async command buffer. */
-    gckASYNC_COMMAND            asyncCommand;
-
     gctBOOL                     dummyDraw;
-
-    /* a copy in kernel space for current committing command buffer
-     * avoid occupyting stack space.
-     */
-    struct _gcoCMDBUF           _commandBufferObject;
-
-    struct _gcoCMDBUF           _nextCMDBUF;
 };
 
 typedef struct _gcsEVENT *      gcsEVENT_PTR;
@@ -891,6 +908,7 @@ gcsEVENT_QUEUE;
 */
 #define gcdREPO_LIST_COUNT      3
 
+
 /* gckEVENT object. */
 struct _gckEVENT
 {
@@ -901,8 +919,11 @@ struct _gckEVENT
     gckOS                       os;
     gckKERNEL                   kernel;
 
-    /* Pointer to gckASYNC_COMMAND object. */
-    gckASYNC_COMMAND            asyncCommand;
+    /* Pointer to COMMAND object, either one of the 3. */
+    gckCOMMAND                  command;
+
+    /* Submit function pointer, different for different command module. */
+    gceSTATUS                (* submitEvent)(gckEVENT, gctBOOL, gctBOOL);
 
     /* Time stamp. */
     gctUINT64                   stamp;
@@ -940,45 +961,109 @@ struct _gckEVENT
     gctINT                      notifyState;
 };
 
-/* Free all events belonging to a process. */
+/* Construct a new gckEVENT object. */
 gceSTATUS
-gckEVENT_FreeProcess(
+gckEVENT_Construct(
+    IN gckKERNEL Kernel,
+    IN gckCOMMAND Command,
+    OUT gckEVENT * Event
+    );
+
+/* Destroy an gckEVENT object. */
+gceSTATUS
+gckEVENT_Destroy(
+    IN gckEVENT Event
+    );
+
+/* Reserve the next available hardware event. */
+gceSTATUS
+gckEVENT_GetEvent(
     IN gckEVENT Event,
-    IN gctUINT32 ProcessID
+    IN gctBOOL Wait,
+    OUT gctUINT8 * EventID,
+    IN gceKERNEL_WHERE Source
+   );
+
+/* Add a new event to the list of events. */
+gceSTATUS
+gckEVENT_AddList(
+    IN gckEVENT Event,
+    IN gcsHAL_INTERFACE_PTR Interface,
+    IN gceKERNEL_WHERE FromWhere,
+    IN gctBOOL AllocateAllowed,
+    IN gctBOOL FromKernel
     );
 
+/* Schedule a FreeVideoMemory event. */
 gceSTATUS
-gckEVENT_Stop(
+gckEVENT_FreeVideoMemory(
+    IN gckEVENT Event,
+    IN gcuVIDMEM_NODE_PTR VideoMemory,
+    IN gceKERNEL_WHERE FromWhere
+    );
+
+/* Schedule a signal event. */
+gceSTATUS
+gckEVENT_Signal(
     IN gckEVENT Event,
-    IN gctUINT32 ProcessID,
-    IN gctPHYS_ADDR Handle,
-    IN gctSIZE_T Offset,
-    IN gctPOINTER Logical,
-    IN gctUINT32 Address,
     IN gctSIGNAL Signal,
-    IN OUT gctUINT32 * waitSize
+    IN gceKERNEL_WHERE FromWhere
     );
 
-typedef struct _gcsLOCK_INFO * gcsLOCK_INFO_PTR;
-typedef struct _gcsLOCK_INFO
-{
-    gctUINT32                   GPUAddresses[gcdMAX_GPU_COUNT];
-    gctPOINTER                  pageTables[gcdMAX_GPU_COUNT];
-    gctUINT32                   lockeds[gcdMAX_GPU_COUNT];
-    gckKERNEL                   lockKernels[gcdMAX_GPU_COUNT];
-    gckMMU                      lockMmus[gcdMAX_GPU_COUNT];
-}
-gcsLOCK_INFO;
+/* Schedule an Unlock event. */
+gceSTATUS
+gckEVENT_Unlock(
+    IN gckEVENT Event,
+    IN gceKERNEL_WHERE FromWhere,
+    IN gctPOINTER Node
+    );
 
-typedef struct _gcsGPU_MAP * gcsGPU_MAP_PTR;
-typedef struct _gcsGPU_MAP
-{
-    gctINT                      pid;
-    gcsLOCK_INFO                lockInfo;
-    gcsGPU_MAP_PTR              prev;
-    gcsGPU_MAP_PTR              next;
-}
-gcsGPU_MAP;
+gceSTATUS
+gckEVENT_CommitDone(
+    IN gckEVENT Event,
+    IN gceKERNEL_WHERE FromWhere,
+    IN gckCONTEXT Context
+    );
+
+gceSTATUS
+gckEVENT_Submit(
+    IN gckEVENT Event,
+    IN gctBOOL Wait,
+    IN gctBOOL FromPower
+    );
+
+gceSTATUS
+gckEVENT_Commit(
+    IN gckEVENT Event,
+    IN gcsQUEUE_PTR Queue,
+    IN gctBOOL Forced
+    );
+
+/* Event callback routine. */
+gceSTATUS
+gckEVENT_Notify(
+    IN gckEVENT Event,
+    IN gctUINT32 IDs
+    );
+
+/* Event callback routine. */
+gceSTATUS
+gckEVENT_Interrupt(
+    IN gckEVENT Event,
+    IN gctUINT32 IDs
+    );
+
+gceSTATUS
+gckEVENT_Dump(
+    IN gckEVENT Event
+    );
+
+/* Free all events belonging to a process. */
+gceSTATUS
+gckEVENT_FreeProcess(
+    IN gckEVENT Event,
+    IN gctUINT32 ProcessID
+    );
 
 /* gcuVIDMEM_NODE structure. */
 typedef union _gcuVIDMEM_NODE
@@ -987,7 +1072,7 @@ typedef union _gcuVIDMEM_NODE
     struct _gcsVIDMEM_NODE_VIDMEM
     {
         /* Owner of this node. */
-        gckVIDMEM               memory;
+        gckVIDMEM               parent;
 
         /* Dual-linked list of nodes. */
         gcuVIDMEM_NODE_PTR      next;
@@ -999,12 +1084,17 @@ typedef union _gcuVIDMEM_NODE
 
         /* Information for this node. */
         gctSIZE_T               offset;
+
+        gctUINT32               address;
         gctSIZE_T               bytes;
         gctUINT32               alignment;
 
 #ifdef __QNXNTO__
         /* Client virtual address. */
         gctPOINTER              logical;
+
+        /* Process ID owning this memory. */
+        gctUINT32               processID;
 #endif
 
         /* Locked counter. */
@@ -1012,10 +1102,9 @@ typedef union _gcuVIDMEM_NODE
 
         /* Memory pool. */
         gcePOOL                 pool;
-        gctUINT32               physical;
 
-        /* Process ID owning this memory. */
-        gctUINT32               processID;
+        /* Kernel virtual address. */
+        gctPOINTER              kvaddr;
 
 #if gcdENABLE_VG
         gctPOINTER              kernelVirtual;
@@ -1035,9 +1124,13 @@ typedef union _gcuVIDMEM_NODE
         /* mdl record pointer... a kmalloc address. Process agnostic. */
         gctPHYS_ADDR            physical;
         gctSIZE_T               bytes;
+
         /* do_mmap_pgoff address... mapped per-process. */
         gctPOINTER              logical;
 
+        /* Kernel virtual address. */
+        gctPOINTER              kvaddr;
+
 #if gcdENABLE_VG
         /* Physical address of this node, only meaningful when it is contiguous. */
         gctUINT64               physicalAddress;
@@ -1054,47 +1147,83 @@ typedef union _gcuVIDMEM_NODE
         gctSIZE_T               pageCount;
 
         /* Used only when node is not contiguous */
-        gctPOINTER              pageTables[gcdMAX_GPU_COUNT];
+        gctPOINTER              pageTables[gcvHARDWARE_NUM_TYPES];
         /* Actual physical address */
-        gctUINT32               addresses[gcdMAX_GPU_COUNT];
+        gctUINT32               addresses[gcvHARDWARE_NUM_TYPES];
 
         /* Locked counter. */
-        gctINT32                lockeds[gcdMAX_GPU_COUNT];
+        gctINT32                lockeds[gcvHARDWARE_NUM_TYPES];
+
+        /* MMU page size type */
+        gcePAGE_TYPE            pageType;
 
-        /* Surface type. */
-        gceSURF_TYPE            type;
+        gceVIDMEM_TYPE          type;
 
         /* Secure GPU virtual address. */
         gctBOOL                 secure;
 
         gctBOOL                 onFault;
-
-        gcsLISTHEAD             head;
     }
     Virtual;
-}
-gcuVIDMEM_NODE;
 
-/* gckVIDMEM object. */
-struct _gckVIDMEM
-{
-    /* Object. */
-    gcsOBJECT                   object;
+    struct _gcsVIDMEM_NODE_VIRTUAL_CHUNK
+    {
+        /* Owner of this chunk */
+        gckVIDMEM_BLOCK         parent;
 
-    /* Pointer to gckOS object. */
-    gckOS                       os;
+        /* Pointer to gckKERNEL object. */
+        gckKERNEL               kernel;
 
-    /* mdl record pointer... a kmalloc address. Process agnostic. */
-    gctPHYS_ADDR                physical;
+        /* Dual-linked list of chunk. */
+        gcuVIDMEM_NODE_PTR      next;
+        gcuVIDMEM_NODE_PTR      prev;
 
-    /* Information for this video memory heap. */
-    gctUINT32                   baseAddress;
-    gctSIZE_T                   bytes;
-    gctSIZE_T                   freeBytes;
+        /* Dual linked list of free chunk. */
+        gcuVIDMEM_NODE_PTR      nextFree;
+        gcuVIDMEM_NODE_PTR      prevFree;
+
+        /* Information for this chunk. */
+        gctSIZE_T               offset;
+        gctUINT32               addresses[gcvHARDWARE_NUM_TYPES];
+        gctINT32                lockeds[gcvHARDWARE_NUM_TYPES];
+        gctSIZE_T               bytes;
+
+        /* Mapped user logical */
+        gctPOINTER              logical;
+
+        /* Kernel virtual address. */
+        gctPOINTER              kvaddr;
+
+        /* Locked counter. */
+    }
+    VirtualChunk;
+
+}
+gcuVIDMEM_NODE;
+
+/* gckVIDMEM object. */
+struct _gckVIDMEM
+{
+    /* Object. */
+    gcsOBJECT                   object;
+
+    /* Pointer to gckOS object. */
+    gckOS                       os;
+
+    /* mdl record pointer... a kmalloc address. Process agnostic. */
+    gctPHYS_ADDR                physical;
+
+    /* Information for this video memory heap. */
+    gctPHYS_ADDR_T              physicalBase;
+    gctSIZE_T                   bytes;
+    gctSIZE_T                   freeBytes;
     gctSIZE_T                   minFreeBytes;
 
+    /* caps inherit from its allocator, ~0u if allocator was not applicable. */
+    gctUINT32                   capability;
+
     /* Mapping for each type of surface. */
-    gctINT                      mapping[gcvSURF_NUM_TYPES];
+    gctINT                      mapping[gcvVIDMEM_TYPE_COUNT];
 
     /* Sentinel nodes for up to 8 banks. */
     gcuVIDMEM_NODE              sentinel[8];
@@ -1106,6 +1235,51 @@ struct _gckVIDMEM
     gctPOINTER                  mutex;
 };
 
+/* gckVIDMEM_BLOCK object. */
+typedef struct _gcsVIDMEM_BLOCK
+{
+    /* Object. */
+    gcsOBJECT                   object;
+
+    /* Pointer to gckOS object. */
+    gckOS                       os;
+
+    /* linked list of nodes. */
+    gckVIDMEM_BLOCK             next;
+
+    /* Contiguously allocated? */
+    gctBOOL                     contiguous;
+
+    /* Customer private handle */
+    gctUINT32                   gid;
+
+    /* mdl record pointer... a kmalloc address. Process agnostic. */
+    gctPHYS_ADDR                physical;
+
+    /* Information for this video memory virtual block. */
+    gctSIZE_T                   bytes;
+    gctSIZE_T                   freeBytes;
+
+    /* 1M page count. */
+    gctUINT32                   pageCount;
+
+    /* Gpu virtual base of this video memory heap. */
+    gctUINT32                   addresses[gcvHARDWARE_NUM_TYPES];
+    gctPOINTER                  pageTables[gcvHARDWARE_NUM_TYPES];
+
+    /* TODO: */
+    gceVIDMEM_TYPE              type;
+
+    /* Virtual chunk. */
+    gcuVIDMEM_NODE              node;
+
+    gctPOINTER                  mutex;
+
+    gctBOOL                     secure;
+    gctBOOL                     onFault;
+}
+gcsVIDMEM_BLOCK;
+
 typedef struct _gcsVIDMEM_NODE
 {
     _VIV_VIDMEM_METADATA        metadata;
@@ -1125,21 +1299,14 @@ typedef struct _gcsVIDMEM_NODE
     /* Name for client to import. */
     gctUINT32                   name;
 
+    /* Link in _gckDB::videoMemList. */
+    gcsLISTHEAD                 link;
+
     /* dma_buf */
     gctPOINTER                  dmabuf;
 
-#if gcdPROCESS_ADDRESS_SPACE
-    /* Head of mapping list. */
-    gcsGPU_MAP_PTR              mapHead;
-
-    /* Tail of mapping list. */
-    gcsGPU_MAP_PTR              mapTail;
-
-    gctPOINTER                  mapMutex;
-#endif
-
-    /* Surface Type. */
-    gceSURF_TYPE                type;
+    /* Video memory allocation type. */
+    gceVIDMEM_TYPE              type;
 
     /* Pool from which node is allocated. */
     gcePOOL                     pool;
@@ -1218,6 +1385,10 @@ typedef struct _gcsDEVICE
     /* Same hardware type shares one MMU. */
     gckMMU                      mmus[gcvHARDWARE_NUM_TYPES];
 
+    gctUINT64                   sRAMBases[gcvCORE_COUNT][gcvSRAM_COUNT];
+    gctUINT32                   sRAMSizes[gcvCORE_COUNT][gcvSRAM_COUNT];
+    gctUINT32                   sRAMBaseAddress[gcvCORE_COUNT][gcvSRAM_COUNT];
+
     /* Mutex to make sure stuck dump for multiple cores doesn't interleave. */
     gctPOINTER                  stuckDumpMutex;
 
@@ -1226,6 +1397,25 @@ typedef struct _gcsDEVICE
 }
 gcsDEVICE;
 
+/* video memory pool functions. */
+/* Construct a new gckVIDMEM object. */
+gceSTATUS
+gckVIDMEM_Construct(
+    IN gckOS Os,
+    IN gctPHYS_ADDR_T PhysicalBase,
+    IN gctSIZE_T Bytes,
+    IN gctSIZE_T Threshold,
+    IN gctSIZE_T Banking,
+    OUT gckVIDMEM * Memory
+    );
+
+/* Destroy an gckVDIMEM object. */
+gceSTATUS
+gckVIDMEM_Destroy(
+    IN gckVIDMEM Memory
+    );
+
+
 gceSTATUS
 gckVIDMEM_HANDLE_Allocate(
     IN gckKERNEL Kernel,
@@ -1248,40 +1438,52 @@ gckVIDMEM_HANDLE_Dereference(
     );
 
 gceSTATUS
-gckVIDMEM_NODE_Allocate(
+gckVIDMEM_HANDLE_Lookup(
     IN gckKERNEL Kernel,
-    IN gcuVIDMEM_NODE_PTR VideoNode,
-    IN gceSURF_TYPE Type,
-    IN gcePOOL Pool,
-    IN gctUINT32 * Handle
+    IN gctUINT32 ProcessID,
+    IN gctUINT32 Handle,
+    OUT gckVIDMEM_NODE * Node
     );
 
 gceSTATUS
-gckVIDMEM_NODE_LockCPU(
+gckVIDMEM_HANDLE_Lookup2(
     IN gckKERNEL Kernel,
+    IN gcsDATABASE_PTR Database,
     IN gctUINT32 Handle,
-    OUT gctPOINTER * Logical
+    OUT gckVIDMEM_NODE * Node
     );
 
+/* video memory node functions. */
 gceSTATUS
-gckVIDMEM_NODE_UnlockCPU(
+gckVIDMEM_NODE_AllocateLinear(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
-    OUT gctPOINTER Logical
+    IN gckVIDMEM VideoMemory,
+    IN gcePOOL Pool,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Alignment,
+    IN gctBOOL Specified,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gckVIDMEM_NODE * NodeObject
     );
 
 gceSTATUS
-gckVIDMEM_Node_Lock(
+gckVIDMEM_NODE_AllocateVirtual(
     IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    OUT gctUINT32 *Address
+    IN gcePOOL Pool,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gckVIDMEM_NODE * NodeObject
     );
 
 gceSTATUS
-gckVIDMEM_NODE_Unlock(
+gckVIDMEM_NODE_AllocateVirtualChunk(
     IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    IN gctUINT32 ProcessID
+    IN gcePOOL Pool,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gckVIDMEM_NODE * NodeObject
     );
 
 gceSTATUS
@@ -1296,10 +1498,104 @@ gckVIDMEM_NODE_Dereference(
     IN gckVIDMEM_NODE Node
     );
 
+gceSTATUS
+gckVIDMEM_NODE_GetReference(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctINT32 * ReferenceCount
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_Lock(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctUINT32 *Address
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_Unlock(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctUINT32 ProcessID,
+    IN OUT gctBOOL * Asynchroneous
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_CleanCache(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctSIZE_T Offset,
+    IN gctPOINTER Logical,
+    IN gctSIZE_T Bytes
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_InvalidateCache(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctSIZE_T Offset,
+    IN gctPOINTER Logical,
+    IN gctSIZE_T Bytes
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_GetLockCount(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctINT32 * LockCount
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_LockCPU(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctBOOL Cacheable,
+    IN gctBOOL FromUser,
+    OUT gctPOINTER * Logical
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_UnlockCPU(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctUINT32 ProcessID,
+    IN gctBOOL FromUser
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_GetPhysical(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctUINT32 Offset,
+    OUT gctPHYS_ADDR_T * PhysicalAddress
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_GetGid(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctUINT32 * Gid
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_GetSize(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctSIZE_T * Size
+    );
+
+gceSTATUS
+gckVIDMEM_NODE_GetType(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gceVIDMEM_TYPE * Type,
+    OUT gcePOOL * Pool
+    );
+
 gceSTATUS
 gckVIDMEM_NODE_Export(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
+    IN gckVIDMEM_NODE NodeObject,
     IN gctINT32 Flags,
     OUT gctPOINTER *DmaBuf,
     OUT gctINT32 *FD
@@ -1308,7 +1604,7 @@ gckVIDMEM_NODE_Export(
 gceSTATUS
 gckVIDMEM_NODE_Name(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
+    IN gckVIDMEM_NODE NodeObject,
     OUT gctUINT32 * Name
     );
 
@@ -1316,79 +1612,68 @@ gceSTATUS
 gckVIDMEM_NODE_Import(
     IN gckKERNEL Kernel,
     IN gctUINT32 Name,
-    OUT gctUINT32 * Handle
+    OUT gckVIDMEM_NODE * NodeObject
     );
 
 gceSTATUS
 gckVIDMEM_NODE_GetFd(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
+    IN gckVIDMEM_NODE NodeObject,
     OUT gctINT * Fd
     );
 
-gceSTATUS
-gckVIDMEM_HANDLE_LookupAndReference(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
-    OUT gckVIDMEM_NODE * Node
-    );
-
-gceSTATUS
-gckVIDMEM_HANDLE_Lookup(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    IN gctUINT32 Handle,
-    OUT gckVIDMEM_NODE * Node
-    );
-
 gceSTATUS
 gckVIDMEM_NODE_WrapUserMemory(
     IN gckKERNEL Kernel,
     IN gcsUSER_MEMORY_DESC_PTR Desc,
-    OUT gctUINT32 * Handle,
+    IN gceVIDMEM_TYPE Type,
+    OUT gckVIDMEM_NODE * NodeObject,
     OUT gctUINT64 * Bytes
     );
 
 gceSTATUS
-gckVIDMEM_FindVIDMEM(
+gckVIDMEM_NODE_SetCommitStamp(
     IN gckKERNEL Kernel,
-    IN gctUINT32 HardwareAddress,
-    OUT gcuVIDMEM_NODE_PTR * Node,
-    OUT gctUINT32_PTR PageTableEntryValue
+    IN gceENGINE Engine,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctUINT64 CommitStamp
     );
 
 gceSTATUS
-gckVIDMEM_QueryNodes(
+gckVIDMEM_NODE_GetCommitStamp(
     IN gckKERNEL Kernel,
-    IN gcePOOL   Pool,
-    OUT gctINT32 *Count,
-    OUT gcuVIDMEM_NODE_PTR *Nodes
+    IN gceENGINE Engine,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctUINT64_PTR CommitStamp
     );
 
-#if gcdPROCESS_ADDRESS_SPACE
 gceSTATUS
-gckEVENT_DestroyMmu(
-    IN gckEVENT Event,
-    IN gckMMU Mmu,
-    IN gceKERNEL_WHERE FromWhere
+gckVIDMEM_NODE_Find(
+    IN gckKERNEL Kernel,
+    IN gctUINT32 Address,
+    OUT gckVIDMEM_NODE * NodeObject,
+    OUT gctUINT32 * Offset
     );
-#endif
 
 typedef struct _gcsADDRESS_AREA * gcsADDRESS_AREA_PTR;
 typedef struct _gcsADDRESS_AREA
 {
-    /* Page table information. */
-    gctSIZE_T                   pageTableSize;
-    gctPHYS_ADDR                pageTablePhysical;
-    gctUINT32_PTR               pageTableLogical;
-    gctUINT32                   pageTableEntries;
+    /* Page table / STLB table information. */
+    gctSIZE_T                   stlbSize;
+    gckVIDMEM_NODE              stlbVideoMem;
+    gctUINT32_PTR               stlbLogical;
+    gctUINT32                   stlbEntries;
+    /* stlb physical address. */
+    gctPHYS_ADDR_T              stlbPhysical;
 
     /* Free entries. */
     gctUINT32                   heapList;
     gctBOOL                     freeNodes;
 
-    gctUINT32                   dynamicMappingStart;
-    gctUINT32                   dynamicMappingEnd;
+    gceAREA_TYPE                areaType;
+
+    gctUINT32                   mappingStart;
+    gctUINT32                   mappingEnd;
 
     gctUINT32_PTR               mapLogical;
 }
@@ -1411,55 +1696,48 @@ struct _gckMMU
 
     /* Master TLB information. */
     gctSIZE_T                   mtlbSize;
-    gctPHYS_ADDR                mtlbPhysical;
+    gckVIDMEM_NODE              mtlbVideoMem;
     gctUINT32_PTR               mtlbLogical;
     gctUINT32                   mtlbEntries;
+    /* mtlb physical address. */
+    gctPHYS_ADDR_T              mtlbPhysical;
 
     gctPOINTER                  staticSTLB;
     gctBOOL                     enabled;
 
-#if gcdPROCESS_ADDRESS_SPACE
-    gctPOINTER                  pageTableDirty[gcdMAX_GPU_COUNT];
-    gctPOINTER                  stlbs;
-#endif
-
+    gctSIZE_T                   safePageSize;
+    gckVIDMEM_NODE              safePageVideoMem;
     gctPOINTER                  safePageLogical;
-    gctPHYS_ADDR                safePagePhysical;
     gctUINT32                   safeAddress;
-    gctSIZE_T                   safePageSize;
+    /* Safe page physical address. */
+    gctPHYS_ADDR_T              safePagePhysical;
+
+    /* GPU physical address flat mapping area. */
+    gctUINT32                   gpuPhysicalRangeCount;
+    gcsFLAT_MAPPING_RANGE       gpuPhysicalRanges[gcdMAX_FLAT_MAPPING_COUNT];
 
-    /* physBase,physSize flat mapping area. */
-    gctUINT32                   flatMappingRangeCount;
-    gcsFLAT_MAPPING_RANGE       flatMappingRanges[gcdMAX_FLAT_MAPPING_COUNT];
+    /* GPU virtual address flat mapping area*/
+    gctUINT32                   gpuAddressRangeCount;
+    gcsFLAT_MAPPING_RANGE       gpuAddressRanges[gcdMAX_FLAT_MAPPING_COUNT];
 
     /* List of hardware which uses this MMU. */
     gcsLISTHEAD                 hardwareList;
 
     struct _gckQUEUE            recentFreedAddresses;
 
-    gcsADDRESS_AREA             area[gcvADDRESS_AREA_COUNT];
+    gcsADDRESS_AREA             dynamicArea1M;
+    gcsADDRESS_AREA             dynamicArea4K;
+    gcsADDRESS_AREA             secureArea;
+
+    gctBOOL                     dynamicAreaSetuped;
+
+    gctBOOL                     sRAMMapped;
 
     gctUINT32                   contiguousBaseAddress;
     gctUINT32                   externalBaseAddress;
+    gctUINT32                   internalBaseAddress;
 };
 
-typedef struct _gcsASYNC_COMMAND
-{
-    gckOS                           os;
-    gckHARDWARE                     hardware;
-    gckKERNEL                       kernel;
-
-    gctPOINTER                      mutex;
-    gcsFE                           fe;
-
-    gctUINT32                       reservedTail;
-    gctUINT64                       commitStamp;
-
-    gckFENCE                        fence;
-
-    gctPOINTER                      kList;
-}
-gcsASYNC_COMMAND;
 
 gceSTATUS
 gckOS_CreateKernelMapping(
@@ -1477,40 +1755,6 @@ gckOS_DestroyKernelMapping(
     IN gctPOINTER Logical
     );
 
-gceSTATUS
-gckOS_CreateKernelVirtualMapping(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    OUT gctPOINTER * Logical,
-    OUT gctSIZE_T * PageCount
-    );
-
-gceSTATUS
-gckOS_DestroyKernelVirtualMapping(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    IN gctPOINTER Logical
-    );
-
-gceSTATUS
-gckOS_CreateUserVirtualMapping(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    OUT gctPOINTER * Logical,
-    OUT gctSIZE_T * PageCount
-    );
-
-gceSTATUS
-gckOS_DestroyUserVirtualMapping(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    IN gctPOINTER Logical
-    );
-
 gceSTATUS
 gckOS_GetFd(
     IN gctSTRING Name,
@@ -1546,56 +1790,6 @@ gckOS_ReadMappedPointer(
     IN gctUINT32_PTR Data
     );
 
-gceSTATUS
-gckKERNEL_AllocateVirtualCommandBuffer(
-    IN gckKERNEL Kernel,
-    IN gctBOOL InUserSpace,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctPHYS_ADDR * Physical,
-    OUT gctPOINTER * Logical
-    );
-
-gceSTATUS
-gckKERNEL_DestroyVirtualCommandBuffer(
-    IN gckKERNEL Kernel,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical
-    );
-
-gceSTATUS
-gckKERNEL_AllocateVirtualMemory(
-    IN gckKERNEL Kernel,
-    IN gctBOOL NonPaged,
-    IN gctBOOL InUserSpace,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctPHYS_ADDR * Physical,
-    OUT gctPOINTER * Logical
-    );
-
-gceSTATUS
-gckKERNEL_FreeVirtualMemory(
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gctBOOL NonPaged
-    );
-
-gceSTATUS
-gckKERNEL_GetGPUAddress(
-    IN gckKERNEL Kernel,
-    IN gctPOINTER Logical,
-    IN gctBOOL InUserSpace,
-    IN gctPHYS_ADDR Physical,
-    OUT gctUINT32 * Address
-    );
-
-gceSTATUS
-gckKERNEL_QueryGPUAddress(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 GpuAddress,
-    OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
-    );
-
 gceSTATUS
 gckKERNEL_AttachProcess(
     IN gckKERNEL Kernel,
@@ -1609,22 +1803,16 @@ gckKERNEL_AttachProcessEx(
     IN gctUINT32 PID
     );
 
-#if gcdSECURE_USER
 gceSTATUS
-gckKERNEL_MapLogicalToPhysical(
+gckKERNEL_AllocateVideoMemory(
     IN gckKERNEL Kernel,
-    IN gcskSECURE_CACHE_PTR Cache,
-    IN OUT gctPOINTER * Data
-    );
-
-gceSTATUS
-gckKERNEL_FlushTranslationCache(
-    IN gckKERNEL Kernel,
-    IN gcskSECURE_CACHE_PTR Cache,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
+    IN gctUINT32 Alignment,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN OUT gctSIZE_T * Bytes,
+    IN OUT gcePOOL * Pool,
+    OUT gckVIDMEM_NODE * NodeObject
     );
-#endif
 
 gceSTATUS
 gckHARDWARE_QueryIdle(
@@ -1642,15 +1830,15 @@ gckHARDWARE_WaitFence(
     );
 
 gceSTATUS
-gckHARDWARE_AddressInHardwareFuncions(
-    IN gckHARDWARE Hardware,
-    IN gctUINT32 Address,
-    OUT gctPOINTER *Pointer
+gckHARDWARE_UpdateContextID(
+    IN gckHARDWARE Hardware
     );
 
 gceSTATUS
-gckHARDWARE_UpdateContextID(
-    IN gckHARDWARE Hardware
+gckHARDWARE_QueryMcfe(
+    IN gckHARDWARE Hardware,
+    OUT const gceMCFE_CHANNEL_TYPE * Channels[],
+    OUT gctUINT32 * Count
     );
 
 #if gcdSECURITY
@@ -1819,6 +2007,11 @@ gckKERNEL_ReadShBuffer(
     OUT gctUINT32 * BytesRead
     );
 
+gceSTATUS
+gckKERNEL_GetHardwareType(
+    IN gckKERNEL Kernel,
+    OUT gceHARDWARE_TYPE *Type
+    );
 
 /******************************************************************************\
 ******************************* gckCONTEXT Object *******************************
@@ -1847,7 +2040,6 @@ gckCONTEXT_Update(
 gceSTATUS
 gckCONTEXT_MapBuffer(
     IN gckCONTEXT Context,
-    OUT gctUINT32 *Physicals,
     OUT gctUINT64 *Logicals,
     OUT gctUINT32 *Bytes
     );
@@ -1922,41 +2114,128 @@ gckRECORDER_UpdateMirror(
     );
 
 /******************************************************************************\
-*************************** gckASYNC_COMMAND Object ****************************
+****************************** gckCOMMAND Object *******************************
 \******************************************************************************/
+
+/* Construct a new gckCOMMAND object. */
 gceSTATUS
-gckASYNC_COMMAND_Construct(
+gckCOMMAND_Construct(
     IN gckKERNEL Kernel,
-    OUT gckASYNC_COMMAND * Command
+    IN gceHW_FE_TYPE FeType,
+    OUT gckCOMMAND * Command
     );
 
+/* Destroy an gckCOMMAND object. */
 gceSTATUS
-gckASYNC_COMMAND_Destroy(
-    IN gckASYNC_COMMAND Command
+gckCOMMAND_Destroy(
+    IN gckCOMMAND Command
     );
 
+/* Acquire command queue synchronization objects. */
 gceSTATUS
-gckASYNC_COMMAND_Commit(
-    IN gckASYNC_COMMAND Command,
-    IN gcoCMDBUF CommandBuffer,
-    IN gcsQUEUE_PTR EventQueue
+gckCOMMAND_EnterCommit(
+    IN gckCOMMAND Command,
+    IN gctBOOL FromPower
     );
 
+/* Release command queue synchronization objects. */
 gceSTATUS
-gckASYNC_COMMAND_EnterCommit(
-    IN gckASYNC_COMMAND Command
+gckCOMMAND_ExitCommit(
+    IN gckCOMMAND Command,
+    IN gctBOOL FromPower
     );
 
+/* Start the command queue. */
 gceSTATUS
-gckASYNC_COMMAND_ExitCommit(
-    IN gckASYNC_COMMAND Command
+gckCOMMAND_Start(
+    IN gckCOMMAND Command
     );
 
+/* Stop the command queue. */
 gceSTATUS
-gckASYNC_COMMAND_Execute(
-    IN gckASYNC_COMMAND Command,
-    IN gctUINT32 Start,
-    IN gctUINT32 End
+gckCOMMAND_Stop(
+    IN gckCOMMAND Command
+    );
+
+/* Commit command buffers. */
+gceSTATUS
+gckCOMMAND_Commit(
+    IN gckCOMMAND Command,
+    IN gcsHAL_SUBCOMMIT * SubCommit,
+    IN gctUINT32 ProcessId,
+    IN gctBOOL Shared,
+    OUT gctUINT64_PTR CommitStamp
+    );
+
+/* Reserve space in the command buffer. */
+gceSTATUS
+gckCOMMAND_Reserve(
+    IN gckCOMMAND Command,
+    IN gctUINT32 RequestedBytes,
+    OUT gctPOINTER * Buffer,
+    OUT gctUINT32 * BufferSize
+    );
+
+/*
+ * Execute reserved space in the command buffer.
+ * Wait link FE version.
+ */
+gceSTATUS
+gckCOMMAND_Execute(
+    IN gckCOMMAND Command,
+    IN gctUINT32 RequstedBytes
+    );
+
+/*
+ * Execute reserved space in the command buffer.
+ * Async FE version.
+ */
+gceSTATUS
+gckCOMMAND_ExecuteAsync(
+    IN gckCOMMAND Command,
+    IN gctUINT32 RequestedBytes
+    );
+
+/*
+ * Execute reserved space in the command buffer.
+ * MC-FE version.
+ */
+gceSTATUS
+gckCOMMAND_ExecuteMultiChannel(
+    IN gckCOMMAND Command,
+    IN gctBOOL Priority,
+    IN gctUINT32 ChannelId,
+    IN gctUINT32 RequstedBytes
+    );
+
+/* Stall the command queue. */
+gceSTATUS
+gckCOMMAND_Stall(
+    IN gckCOMMAND Command,
+    IN gctBOOL FromPower
+    );
+
+/* Attach user process. */
+gceSTATUS
+gckCOMMAND_Attach(
+    IN gckCOMMAND Command,
+    OUT gckCONTEXT * Context,
+    OUT gctSIZE_T * MaxState,
+    OUT gctUINT32 * NumStates,
+    IN gctUINT32 ProcessID
+    );
+
+/* Dump command buffer being executed by GPU. */
+gceSTATUS
+gckCOMMAND_DumpExecutingBuffer(
+    IN gckCOMMAND Command
+    );
+
+/* Detach user process. */
+gceSTATUS
+gckCOMMAND_Detach(
+    IN gckCOMMAND Command,
+    IN gckCONTEXT Context
     );
 
 void
@@ -2053,14 +2332,6 @@ gckDEVICE_SetMMU(
     IN gckMMU Mmu
     );
 
-gceSTATUS
-gckDEVICE_QueryGPUAddress(
-    IN gckDEVICE Device,
-    IN gckKERNEL Kernel,
-    IN gctUINT32 GPUAddress,
-    OUT gckVIRTUAL_COMMAND_BUFFER_PTR * Buffer
-    );
-
 #if gcdENABLE_TRUST_APPLICATION
 gceSTATUS
 gckKERNEL_MapInTrustApplicaiton(
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_async_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_async_command.c
deleted file mode 100644 (file)
index 2a0c554..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-/****************************************************************************
-*
-*    The MIT License (MIT)
-*
-*    Copyright (c) 2014 - 2018 Vivante Corporation
-*
-*    Permission is hereby granted, free of charge, to any person obtaining a
-*    copy of this software and associated documentation files (the "Software"),
-*    to deal in the Software without restriction, including without limitation
-*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
-*    and/or sell copies of the Software, and to permit persons to whom the
-*    Software is furnished to do so, subject to the following conditions:
-*
-*    The above copyright notice and this permission notice shall be included in
-*    all copies or substantial portions of the Software.
-*
-*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-*    DEALINGS IN THE SOFTWARE.
-*
-*****************************************************************************
-*
-*    The GPL License (GPL)
-*
-*    Copyright (C) 2014 - 2018 Vivante Corporation
-*
-*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*
-*****************************************************************************
-*
-*    Note: This software is released under dual MIT and GPL licenses. A
-*    recipient may use this file under the terms of either the MIT license or
-*    GPL License. If you wish to use only one license not the other, you can
-*    indicate your decision by deleting one of the above license notices in your
-*    version of this file.
-*
-*****************************************************************************/
-
-
-#include "gc_hal_kernel_precomp.h"
-#include "gc_hal_kernel_context.h"
-
-#define _GC_OBJ_ZONE            gcvZONE_ASYNC_COMMAND
-
-static gceSTATUS
-_HandlePatchList(
-    IN gckASYNC_COMMAND Command,
-    IN gcoCMDBUF CommandBuffer,
-    IN gctBOOL NeedCopy
-    )
-{
-    gceSTATUS status;
-    gcsPATCH_LIST * uList;
-    gcsPATCH_LIST * previous;
-    gcsPATCH_LIST * kList;
-
-    gcmkHEADER_ARG(
-        "Command=0x%x CommandBuffer=0x%x NeedCopy=%d",
-        Command, CommandBuffer, NeedCopy
-        );
-
-    uList = gcmUINT64_TO_PTR(CommandBuffer->patchHead);
-
-    while (uList)
-    {
-        gctUINT i;
-
-        kList = gcvNULL;
-        previous = uList;
-
-        gcmkONERROR(gckKERNEL_OpenUserData(
-            Command->kernel,
-            NeedCopy,
-            Command->kList,
-            uList,
-            gcmSIZEOF(gcsPATCH_LIST),
-            (gctPOINTER *)&kList
-            ));
-
-        for (i = 0; i < kList->count; i++)
-        {
-            gcsPATCH * patch = &kList->patch[i];
-
-            /* Touch video memory node. */
-            gcmkVERIFY_OK(gckVIDMEM_SetCommitStamp(Command->kernel, gcvENGINE_BLT, patch->handle, Command->commitStamp));
-        }
-
-        uList = kList->next;
-
-        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
-            Command->kernel,
-            NeedCopy,
-            gcvFALSE,
-            previous,
-            gcmSIZEOF(gcsPATCH_LIST),
-            (gctPOINTER *)&kList
-            ));
-    }
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    if (kList)
-    {
-        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
-            Command->kernel,
-            NeedCopy,
-            gcvFALSE,
-            previous,
-            gcmSIZEOF(gcsPATCH_LIST),
-            (gctPOINTER *)&kList
-            ));
-    }
-
-    gcmkFOOTER();
-    return status;
-}
-
-
-gceSTATUS
-gckASYNC_COMMAND_Construct(
-    IN gckKERNEL Kernel,
-    OUT gckASYNC_COMMAND * Command
-    )
-{
-    gceSTATUS status;
-    gckASYNC_COMMAND command;
-    gckOS os = Kernel->os;
-
-    gcmkHEADER();
-
-    /* Allocate gckASYNC_COMMAND object. */
-    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsASYNC_COMMAND), (gctPOINTER *)&command));
-
-    gckOS_ZeroMemory(command, gcmSIZEOF(gcsASYNC_COMMAND));
-
-    /* Mutex to protect gckFE. */
-    gcmkONERROR(gckOS_CreateMutex(os, &command->mutex));
-
-    /* Initialize gckFE. */
-    gckFE_Initialize(Kernel->hardware, &command->fe);
-
-    /* Initialize gckASYNC_COMMAND object. */
-    command->os = os;
-    command->kernel = Kernel;
-    command->hardware = Kernel->hardware;
-
-    gcmkVERIFY_OK(gckHARDWARE_QueryCommandBuffer(
-        Kernel->hardware,
-        gcvENGINE_BLT,
-        gcvNULL,
-        gcvNULL,
-        &command->reservedTail
-        ));
-
-    gcmkONERROR(gckFENCE_Create(
-        os, Kernel, &command->fence
-        ));
-
-    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsPATCH_LIST), &command->kList));
-
-    /* Commit stamp start from 1. */
-    command->commitStamp = 1;
-
-    *Command = command;
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Rollback. */
-    gckASYNC_COMMAND_Destroy(command);
-
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckASYNC_COMMAND_Destroy(
-    IN gckASYNC_COMMAND Command
-    )
-{
-    gcmkHEADER();
-
-    if (Command)
-    {
-        if (Command->mutex)
-        {
-            gcmkVERIFY_OK(gckOS_DeleteMutex(Command->os, Command->mutex));
-        }
-
-        if (Command->fence)
-        {
-            gcmkVERIFY_OK(gckFENCE_Destory(Command->os, Command->fence));
-        }
-
-        if (Command->kList)
-        {
-            gcmkOS_SAFE_FREE(Command->os, Command->kList);
-        }
-
-        if (Command->fe.freeDscriptors)
-        {
-            gcmkOS_SAFE_FREE(Command->os, Command->fe.freeDscriptors);
-        }
-
-        gcmkOS_SAFE_FREE(Command->os, Command);
-    }
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckASYNC_COMMAND_Commit(
-    IN gckASYNC_COMMAND Command,
-    IN gcoCMDBUF CommandBuffer,
-    IN gcsQUEUE_PTR EventQueue
-    )
-{
-    gceSTATUS       status;
-    gctBOOL         available = gcvFALSE;
-    gctBOOL         acquired = gcvFALSE;
-    gcoCMDBUF       commandBufferObject = gcvNULL;
-    struct _gcoCMDBUF _commandBufferObject;
-    gctUINT8_PTR    commandBufferLogical;
-    gctUINT8_PTR    commandBufferTail;
-    gctUINT         commandBufferSize;
-    gctUINT32       commandBufferAddress;
-    gcsFEDescriptor descriptor;
-    gctUINT32       skipFlushBytes;
-    gctUINT32       fenceBytes;
-    gctBOOL         needCopy;
-    gctUINT32       oldValue;
-    gctUINT32       flushBytes;
-
-    gcmkHEADER();
-
-    gckOS_QueryNeedCopy(Command->os, 0, &needCopy);
-
-    gcmkVERIFY_OK(_HandlePatchList(Command, CommandBuffer, needCopy));
-
-    /* Open user passed gcoCMDBUF object. */
-    gcmkONERROR(gckKERNEL_OpenUserData(
-        Command->kernel,
-        needCopy,
-        &_commandBufferObject,
-        CommandBuffer,
-        gcmSIZEOF(struct _gcoCMDBUF),
-        (gctPOINTER *)&commandBufferObject
-        ));
-
-    gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
-
-    gckHARDWARE_FlushAsyncMMU(Command->hardware, gcvNULL, &flushBytes);
-
-    gcmkONERROR(gckOS_AtomicExchange(Command->os,
-                                     Command->hardware->pageTableDirty[gcvENGINE_BLT],
-                                     0,
-                                     &oldValue));
-
-    if (oldValue)
-    {
-        commandBufferLogical
-            = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
-            +                commandBufferObject->startOffset;
-
-        gckHARDWARE_FlushAsyncMMU(Command->hardware, commandBufferLogical, &flushBytes);
-
-        skipFlushBytes = 0;
-    }
-    else
-    {
-        skipFlushBytes = flushBytes;
-    }
-
-    /* Compute the command buffer entry and the size. */
-    commandBufferLogical
-        = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
-        +                commandBufferObject->startOffset
-        +                skipFlushBytes;
-
-    commandBufferSize
-        = commandBufferObject->offset
-        + Command->reservedTail
-        - commandBufferObject->startOffset
-        - skipFlushBytes;
-
-    commandBufferTail
-        = commandBufferLogical
-        + commandBufferSize
-        - Command->reservedTail;
-
-    /* Get the hardware address. */
-    if (Command->kernel && Command->kernel->virtualCommandBuffer)
-    {
-        gckKERNEL kernel = Command->kernel;
-        gckVIRTUAL_COMMAND_BUFFER_PTR virtualCommandBuffer
-            = gcmNAME_TO_PTR(commandBufferObject->physical);
-
-        if (virtualCommandBuffer == gcvNULL)
-        {
-            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-        }
-
-        gcmkONERROR(gckKERNEL_GetGPUAddress(
-            Command->kernel,
-            commandBufferLogical,
-            gcvTRUE,
-            virtualCommandBuffer,
-            &commandBufferAddress
-            ));
-    }
-    else
-    {
-        gcmkONERROR(gckHARDWARE_ConvertLogical(
-            Command->hardware,
-            commandBufferLogical,
-            gcvTRUE,
-            &commandBufferAddress
-            ));
-    }
-
-    gcmkONERROR(gckHARDWARE_Fence(
-        Command->hardware,
-        gcvENGINE_BLT,
-        commandBufferTail,
-        Command->fence->address,
-        Command->commitStamp,
-        &fenceBytes
-        ));
-
-    descriptor.start = commandBufferAddress;
-    descriptor.end   = commandBufferAddress + commandBufferSize;
-
-    gcmkDUMPCOMMAND(
-        Command->os,
-        commandBufferLogical,
-        commandBufferSize,
-        gcvDUMP_BUFFER_USER,
-        gcvFALSE
-        );
-
-    gckOS_AcquireMutex(Command->os, Command->mutex, gcvINFINITE);
-    acquired = gcvTRUE;
-
-    /* Acquire a slot. */
-    for(;;)
-    {
-        gcmkONERROR(gckFE_ReserveSlot(Command->hardware, &Command->fe, &available));
-
-        if (available)
-        {
-            break;
-        }
-        else
-        {
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "No available slot, have to wait");
-
-            gckOS_Delay(Command->os, 1);
-        }
-    }
-
-    /* Send descriptor. */
-    gckFE_Execute(Command->hardware, &Command->fe, &descriptor);
-
-    Command->commitStamp++;
-
-    gckOS_ReleaseMutex(Command->os, Command->mutex);
-    acquired = gcvFALSE;
-
-    gcmkVERIFY_OK(gckKERNEL_CloseUserData(
-        Command->kernel,
-        needCopy,
-        gcvFALSE,
-        CommandBuffer,
-        gcmSIZEOF(struct _gcoCMDBUF),
-        (gctPOINTER *)&commandBufferObject
-        ));
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    if (acquired)
-    {
-        gckOS_ReleaseMutex(Command->os, Command->mutex);
-    }
-
-    if (commandBufferObject)
-    {
-        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
-            Command->kernel,
-            needCopy,
-            gcvFALSE,
-            CommandBuffer,
-            gcmSIZEOF(struct _gcoCMDBUF),
-            (gctPOINTER *)&commandBufferObject
-            ));
-    }
-
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckASYNC_COMMAND_EnterCommit(
-    IN gckASYNC_COMMAND Command
-    )
-{
-    return gckOS_AcquireMutex(Command->os, Command->mutex, gcvINFINITE);
-}
-
-
-gceSTATUS
-gckASYNC_COMMAND_ExitCommit(
-    IN gckASYNC_COMMAND Command
-    )
-{
-    return gckOS_ReleaseMutex(Command->os, Command->mutex);
-}
-
-gceSTATUS
-gckASYNC_COMMAND_Execute(
-    IN gckASYNC_COMMAND Command,
-    IN gctUINT32 Start,
-    IN gctUINT32 End
-    )
-{
-    gceSTATUS status;
-    gcsFEDescriptor descriptor;
-    gctBOOL available;
-
-    descriptor.start = Start;
-    descriptor.end   = End;
-
-    /* Acquire a slot. */
-    for(;;)
-    {
-        gcmkONERROR(gckFE_ReserveSlot(Command->hardware, &Command->fe, &available));
-
-        if (available)
-        {
-            break;
-        }
-        else
-        {
-            gckOS_Delay(Command->os, 1);
-        }
-    }
-
-    /* Send descriptor. */
-    gckFE_Execute(Command->hardware, &Command->fe, &descriptor);
-
-    return gcvSTATUS_OK;
-
-OnError:
-    return status;
-}
-
index a5e81c2..b6c8a95 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -81,7 +81,7 @@
 **      gckCOMMAND Command
 **          gckCOMMAND object has been updated with a new command queue.
 */
-gceSTATUS
+static gceSTATUS
 _NewQueue(
     IN OUT gckCOMMAND Command,
     IN gctBOOL Stalled
@@ -89,18 +89,15 @@ _NewQueue(
 {
     gceSTATUS status;
     gctINT currentIndex, newIndex;
-    gctPHYS_ADDR_T physical;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Switch to the next command buffer. */
     currentIndex = Command->index;
     newIndex     = (currentIndex + 1) % gcdCOMMAND_QUEUES;
 
     /* Wait for availability. */
-#if gcdDUMP_COMMAND
-    gcmkPRINT("@[kernel.waitsignal]");
-#endif
+    gcmkDUMP(Command->os, "#[kernel.waitsignal]");
 
     gcmkONERROR(gckOS_WaitSignal(
         Command->os,
@@ -138,42 +135,12 @@ _NewQueue(
 #endif
 
     /* Update gckCOMMAND object with new command queue. */
-    Command->index         = newIndex;
-    Command->newQueue      = gcvTRUE;
-#if USE_KERNEL_VIRTUAL_BUFFERS
-    if (Command->kernel->virtualCommandBuffer)
-    {
-        gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer = gcvNULL;
-
-        Command->virtualMemory = Command->queues[newIndex].physical;
-
-        commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR) Command->virtualMemory;
-
-        Command->physHandle = commandBuffer->virtualBuffer.physical;
-    }
-    else
-#endif
-    {
-        Command->physHandle = Command->queues[newIndex].physical;
-    }
-
-    Command->logical       = Command->queues[newIndex].logical;
-    Command->address       = Command->queues[newIndex].address;
-    Command->offset        = 0;
-
-    gcmkONERROR(gckOS_GetPhysicalAddress(
-        Command->os,
-        Command->logical,
-        &physical
-        ));
-
-    gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
-        Command->os,
-        physical,
-        &physical
-        ));
-
-    gcmkSAFECASTPHYSADDRT(Command->physical, physical);
+    Command->index    = newIndex;
+    Command->newQueue = gcvTRUE;
+    Command->videoMem = Command->queues[newIndex].videoMem;
+    Command->logical  = Command->queues[newIndex].logical;
+    Command->address  = Command->queues[newIndex].address;
+    Command->offset   = 0;
 
     if (currentIndex != -1)
     {
@@ -206,7 +173,7 @@ OnError:
     return status;
 }
 
-gceSTATUS
+static gceSTATUS
 _IncrementCommitAtom(
     IN gckCOMMAND Command,
     IN gctBOOL Increment
@@ -217,7 +184,7 @@ _IncrementCommitAtom(
     gctINT32 atomValue;
     gctBOOL powerAcquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Extract the gckHARDWARE and gckEVENT objects. */
     hardware = Command->kernel->hardware;
@@ -267,136 +234,10 @@ OnError:
     return status;
 }
 
-#if gcdSECURE_USER
-gceSTATUS
-_ProcessHints(
+static gceSTATUS
+_CheckFlushMMU(
     IN gckCOMMAND Command,
-    IN gctUINT32 ProcessID,
-    IN gcoCMDBUF CommandBuffer
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gckKERNEL kernel;
-    gctBOOL needCopy = gcvFALSE;
-    gcskSECURE_CACHE_PTR cache;
-    gctUINT8_PTR commandBufferLogical;
-    gctUINT8_PTR hintedData;
-    gctUINT32_PTR hintArray;
-    gctUINT i, hintCount;
-
-    gcmkHEADER_ARG(
-        "Command=0x%08X ProcessID=%d CommandBuffer=0x%08X",
-        Command, ProcessID, CommandBuffer
-        );
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
-
-    /* Reset state array pointer. */
-    hintArray = gcvNULL;
-
-    /* Get the kernel object. */
-    kernel = Command->kernel;
-
-    /* Get the cache form the database. */
-    gcmkONERROR(gckKERNEL_GetProcessDBCache(kernel, ProcessID, &cache));
-
-    /* Determine the start of the command buffer. */
-    commandBufferLogical
-        = (gctUINT8_PTR) CommandBuffer->logical
-        +                CommandBuffer->startOffset;
-
-    /* Determine the number of records in the state array. */
-    hintCount = CommandBuffer->hintArrayTail - CommandBuffer->hintArray;
-
-    /* Check wehther we need to copy the structures or not. */
-    gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
-
-    /* Get access to the state array. */
-    if (needCopy)
-    {
-        gctUINT copySize;
-
-        if (Command->hintArrayAllocated &&
-            (Command->hintArraySize < CommandBuffer->hintArraySize))
-        {
-            gcmkONERROR(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
-            Command->hintArraySize = gcvFALSE;
-        }
-
-        if (!Command->hintArrayAllocated)
-        {
-            gctPOINTER pointer = gcvNULL;
-
-            gcmkONERROR(gckOS_Allocate(
-                Command->os,
-                CommandBuffer->hintArraySize,
-                &pointer
-                ));
-
-            Command->hintArray          = gcmPTR_TO_UINT64(pointer);
-            Command->hintArrayAllocated = gcvTRUE;
-            Command->hintArraySize      = CommandBuffer->hintArraySize;
-        }
-
-        hintArray = gcmUINT64_TO_PTR(Command->hintArray);
-        copySize   = hintCount * gcmSIZEOF(gctUINT32);
-
-        gcmkONERROR(gckOS_CopyFromUserData(
-            Command->os,
-            hintArray,
-            gcmUINT64_TO_PTR(CommandBuffer->hintArray),
-            copySize
-            ));
-    }
-    else
-    {
-        gctPOINTER pointer = gcvNULL;
-
-        gcmkONERROR(gckOS_MapUserPointer(
-            Command->os,
-            gcmUINT64_TO_PTR(CommandBuffer->hintArray),
-            CommandBuffer->hintArraySize,
-            &pointer
-            ));
-
-        hintArray = pointer;
-    }
-
-    /* Scan through the buffer. */
-    for (i = 0; i < hintCount; i += 1)
-    {
-        /* Determine the location of the hinted data. */
-        hintedData = commandBufferLogical + hintArray[i];
-
-        /* Map handle into physical address. */
-        gcmkONERROR(gckKERNEL_MapLogicalToPhysical(
-            kernel, cache, (gctPOINTER) hintedData
-            ));
-    }
-
-OnError:
-    /* Get access to the state array. */
-    if (!needCopy && (hintArray != gcvNULL))
-    {
-        gcmkVERIFY_OK(gckOS_UnmapUserPointer(
-            Command->os,
-            gcmUINT64_TO_PTR(CommandBuffer->hintArray),
-            CommandBuffer->hintArraySize,
-            hintArray
-            ));
-    }
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-#endif
-
-#if !gcdNULL_DRIVER
-gceSTATUS
-_FlushMMU(
-    IN gckCOMMAND Command
+    IN gckHARDWARE Hardware
     )
 {
 #if gcdSECURITY
@@ -404,7 +245,6 @@ _FlushMMU(
 #else
     gceSTATUS status;
     gctUINT32 oldValue;
-    gckHARDWARE hardware = Command->kernel->hardware;
     gctBOOL pause = gcvFALSE;
 
     gctUINT8_PTR pointer;
@@ -413,20 +253,51 @@ _FlushMMU(
     gctUINT32 endBytes;
     gctUINT32 bufferSize;
     gctUINT32 executeBytes;
-    gctUINT32 waitLinkBytes;
 
-    gcmkONERROR(gckOS_AtomicExchange(Command->os,
-                                     hardware->pageTableDirty[gcvENGINE_RENDER],
-                                     0,
-                                     &oldValue));
+    gckOS_AtomicExchange(Command->os,
+                         Hardware->pageTableDirty[gcvENGINE_RENDER],
+                         0,
+                         &oldValue);
 
     if (oldValue)
     {
         /* Page Table is upated, flush mmu before commit. */
-        gcmkONERROR(gckHARDWARE_FlushMMU(hardware));
+        gctUINT32 flushBytes;
+
+        gcmkONERROR(gckHARDWARE_FlushMMU(
+            Hardware,
+            gcvNULL,
+            gcvINVALID_ADDRESS,
+            0,
+            &flushBytes
+            ));
+
+        gcmkONERROR(gckCOMMAND_Reserve(
+            Command,
+            flushBytes,
+            (gctPOINTER *)&pointer,
+            &bufferSize
+            ));
+
+        /* Pointer to reserved address. */
+        address = Command->address  + Command->offset;
+
+        /*
+         * subsequent 8 bytes are wait-link commands.
+         * Set more existed bytes for now.
+         */
+        gcmkONERROR(gckHARDWARE_FlushMMU(
+            Hardware,
+            pointer,
+            address,
+            (bufferSize - flushBytes),
+            &flushBytes
+            ));
+
+        gcmkONERROR(gckCOMMAND_Execute(Command, flushBytes));
 
         if ((oldValue & gcvPAGE_TABLE_DIRTY_BIT_FE)
-          && (!hardware->stallFEPrefetch)
+          && (!Hardware->stallFEPrefetch)
         )
         {
             pause = gcvTRUE;
@@ -436,21 +307,11 @@ _FlushMMU(
     if (pause)
     {
         /* Query size. */
-        gcmkONERROR(gckHARDWARE_Event(hardware, gcvNULL, 0, gcvKERNEL_PIXEL, &eventBytes));
-        gcmkONERROR(gckHARDWARE_End(hardware, gcvNULL, ~0U, &endBytes));
+        gcmkONERROR(gckWLFE_Event(Hardware, gcvNULL, 0, gcvKERNEL_PIXEL, &eventBytes));
+        gcmkONERROR(gckWLFE_End(Hardware, gcvNULL, ~0U, &endBytes));
 
         executeBytes = eventBytes + endBytes;
 
-        gcmkONERROR(gckHARDWARE_WaitLink(
-            hardware,
-            gcvNULL,
-            ~0U,
-            Command->offset + executeBytes,
-            &waitLinkBytes,
-            gcvNULL,
-            gcvNULL
-            ));
-
         /* Reserve space. */
         gcmkONERROR(gckCOMMAND_Reserve(
             Command,
@@ -463,8 +324,8 @@ _FlushMMU(
         address = Command->address  + Command->offset;
 
         /* Append EVENT(29). */
-        gcmkONERROR(gckHARDWARE_Event(
-            hardware,
+        gcmkONERROR(gckWLFE_Event(
+            Hardware,
             pointer,
             29,
             gcvKERNEL_PIXEL,
@@ -475,20 +336,7 @@ _FlushMMU(
         pointer += eventBytes;
         address += eventBytes;
 
-        gcmkONERROR(gckHARDWARE_End(hardware, pointer, address, &endBytes));
-
-#if USE_KERNEL_VIRTUAL_BUFFERS
-        if (hardware->kernel->virtualCommandBuffer)
-        {
-            gcmkONERROR(gckKERNEL_GetGPUAddress(
-                hardware->kernel,
-                pointer,
-                gcvFALSE,
-                Command->virtualMemory,
-                &hardware->lastEnd
-                ));
-        }
-#endif
+        gcmkONERROR(gckWLFE_End(Hardware, pointer, address, &endBytes));
 
         gcmkONERROR(gckCOMMAND_Execute(Command, executeBytes));
     }
@@ -499,7 +347,8 @@ OnError:
 #endif
 }
 
-gceSTATUS
+/* WaitLink FE only. */
+static gceSTATUS
 _DummyDraw(
     IN gckCOMMAND Command
     )
@@ -550,500 +399,923 @@ OnError:
 #endif
 }
 
-#endif
-
-static void
-_DumpBuffer(
-    IN gctPOINTER Buffer,
-    IN gctUINT32 GpuAddress,
-    IN gctSIZE_T Size
+/*
+ * Wait pending semaphores.
+ *
+ * next == free: full, no more semaphores.
+ * (free + 1) = next: empty
+ */
+static gcmINLINE gceSTATUS
+_WaitPendingMcfeSema(
+    gckCOMMAND Command
     )
 {
-    gctSIZE_T i, line, left;
-    gctUINT32_PTR data = Buffer;
+    gceSTATUS status;
+    const gctUINT count = gcmCOUNTOF(Command->pendingSema);
+    gctUINT32 nextFreePos;
+    gctUINT32 timeout = gcvINFINITE;
 
-    line = Size / 32;
-    left = Size % 32;
+    gcmkHEADER_ARG("freePendingPos=%u nextPendingPos=%u",
+                   Command->freePendingPos, Command->nextPendingPos);
 
-    for (i = 0; i < line; i++)
-    {
-        gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X %08X %08X",
-                  GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
-        data += 8;
-        GpuAddress += 8 * 4;
-    }
+    nextFreePos = (Command->freePendingPos + 1) % count;
 
-    switch(left)
+    if (nextFreePos == Command->nextPendingPos)
     {
-        case 28:
-            gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X %08X",
-                      GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
-            break;
-        case 24:
-            gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X",
-                      GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5]);
-            break;
-        case 20:
-            gcmkPRINT("%08X : %08X %08X %08X %08X %08X",
-                      GpuAddress, data[0], data[1], data[2], data[3], data[4]);
-            break;
-        case 16:
-            gcmkPRINT("%08X : %08X %08X %08X %08X",
-                      GpuAddress, data[0], data[1], data[2], data[3]);
-            break;
-        case 12:
-            gcmkPRINT("%08X : %08X %08X %08X",
-                      GpuAddress, data[0], data[1], data[2]);
-            break;
-        case 8:
-            gcmkPRINT("%08X : %08X %08X",
-                      GpuAddress, data[0], data[1]);
-            break;
-        case 4:
-            gcmkPRINT("%08X : %08X",
-                      GpuAddress, data[0]);
-            break;
-        default:
-            break;
+        /* No pendings. */
+        gcmkONERROR(gcvSTATUS_NOT_FOUND);
     }
-}
-
-void
-_DumpKernelCommandBuffer(
-    IN gckCOMMAND Command
-    )
-{
-    gctINT i;
-    gctUINT64 physical = 0;
-    gctUINT32 address;
-    gctPOINTER entry   = gcvNULL;
 
-    for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+    while (nextFreePos != Command->nextPendingPos)
     {
-        entry = Command->queues[i].logical;
+        /* Timeout is infinite in the first to at least free one slot. */
+        status = gckOS_WaitSignal(Command->os,
+                                  Command->pendingSema[nextFreePos].signal,
+                                  gcvFALSE,
+                                  timeout);
 
-        gckOS_GetPhysicalAddress(Command->os, entry, &physical);
+        if (status == gcvSTATUS_TIMEOUT)
+        {
+            /* Timeout out is OK for later pendings. */
+            break;
+        }
 
-        gckOS_CPUPhysicalToGPUPhysical(Command->os, physical, &physical);
+        gcmkONERROR(status);
 
-        gcmkPRINT("Kernel command buffer %d\n", i);
+        /* Do not wait for the later slots. */
+        timeout = 0;
 
-        gcmkSAFECASTPHYSADDRT(address, physical);
+        /* More free semaphores can be used. */
+        Command->freeSemaId = Command->pendingSema[nextFreePos].semaId;
 
-        _DumpBuffer(entry, address, Command->pageSize);
+        /* Advance free pos. */
+        Command->freePendingPos = nextFreePos;
+        nextFreePos = (nextFreePos + 1) % count;
     }
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
 }
 
-#if !gcdNULL_DRIVER
-gceSTATUS
-_HandlePatchList(
-    IN gckCOMMAND Command,
-    IN gcoCMDBUF CommandBuffer,
-    IN gctBOOL NeedCopy,
-    OUT gctUINT64 *AsyncCommandStamp
+static gctUINT32
+_GetFreeMcfeSemaNum(
+    gckCOMMAND Command
     )
 {
-    gceSTATUS status;
-    gcsPATCH_LIST * uList;
-    gcsPATCH_LIST * previous;
-    gcsPATCH_LIST * kList;
-    gctUINT64 asyncStamp = 0;
-
-    gcmkHEADER_ARG(
-        "Command=0x%x CommandBuffer=0x%x NeedCopy=%d",
-        Command, CommandBuffer, NeedCopy
-        );
+    gctUINT32 num = 0;
 
-    uList = gcmUINT64_TO_PTR(CommandBuffer->patchHead);
-
-    while (uList)
+    if (Command->nextSemaId <= Command->freeSemaId)
     {
-        gctUINT i;
+        num = Command->freeSemaId - Command->nextSemaId;
+    }
+    else
+    {
+        num = Command->totalSemaId - Command->nextSemaId + Command->freeSemaId;
+    }
 
-        kList = gcvNULL;
-        previous = uList;
+    return num;
+}
 
-        gcmkONERROR(gckKERNEL_OpenUserData(
-            Command->kernel,
-            NeedCopy,
-            Command->kList,
-            uList,
-            gcmSIZEOF(gcsPATCH_LIST),
-            (gctPOINTER *)&kList
-            ));
+/*
+ * Get next semaphore id in semaphore ring.
+ *
+ * There are semaMinThreshhold semaphores are reserved for system operations,
+ * such as _SyncToSystemChannel etc.
+ * The rest semaphores are regular ones.
+ */
+static gcmINLINE gceSTATUS
+_GetNextMcfeSemaId(
+    gckCOMMAND Command,
+    gctBOOL regularSema,
+    gctUINT32 * SemaId
+    )
+{
+    gctUINT32 freeSemaNum = 0;
 
-        for (i = 0; i < kList->count; i++)
-        {
-            gctUINT64 stamp = 0;
-            gcsPATCH * patch = &kList->patch[i];
+    gceSTATUS status = gcvSTATUS_OK;
 
-            /* Touch video memory node. */
-            gcmkVERIFY_OK(gckVIDMEM_SetCommitStamp(Command->kernel, gcvENGINE_RENDER, patch->handle, Command->commitStamp));
+    /*
+     * See the comments in struct definition.
+     * wait when run out of semaphores.
+     */
+    freeSemaNum = _GetFreeMcfeSemaNum(Command);
 
-            /* Get stamp touched async command buffer. */
-            gcmkVERIFY_OK(gckVIDMEM_GetCommitStamp(Command->kernel, gcvENGINE_BLT, patch->handle, &stamp));
+    if ((regularSema && (freeSemaNum <= Command->semaMinThreshhold)) ||
+        (!regularSema && (freeSemaNum == 0)))
+    {
+        gcmkONERROR(_WaitPendingMcfeSema(Command));
+    }
 
-            /* Find latest one. */
-            asyncStamp = gcmMAX(asyncStamp, stamp);
-        }
+    gcmkASSERT(Command->nextSemaId != Command->freeSemaId);
 
-        uList = kList->next;
+    /* Output the semaphore ID. */
+    *SemaId = Command->nextSemaId;
 
-        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
-            Command->kernel,
-            NeedCopy,
-            gcvFALSE,
-            previous,
-            gcmSIZEOF(gcsPATCH_LIST),
-            (gctPOINTER *)&kList
-            ));
+    /* Advance to next. */
+    if (++Command->nextSemaId == Command->totalSemaId)
+    {
+        Command->nextSemaId = 0;
     }
 
-    if ((Command->asyncCommand != gcvNULL)
-     && (*(gctUINT64 *)Command->asyncCommand->fence->logical > asyncStamp)
+OnError:
+    return status;
+}
+
+/*
+ * Get next pending pos in pending semaphore tracking ring.
+ */
+static gcmINLINE gceSTATUS
+_GetNextPendingPos(
+    gckCOMMAND Command,
+    gctUINT32 * Pos
     )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+
+    /* Wait when out of pending ring. */
+    if (Command->nextPendingPos == Command->freePendingPos)
     {
-        /* No need to wait for async command buffer. */
-        *AsyncCommandStamp = 0;
-    }
-    else
-    {
-        /* Need to add a fence wait. */
-        *AsyncCommandStamp = asyncStamp;
+        /* Run out of pending semaphore tracking ring. */
+        gcmkONERROR(_WaitPendingMcfeSema(Command));
     }
 
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
+    gcmkASSERT(Command->nextPendingPos != Command->freePendingPos);
 
-OnError:
-    if (kList)
+    *Pos = Command->nextPendingPos;
+
+    /* Advance to next. */
+    if (++Command->nextPendingPos == gcmCOUNTOF(Command->pendingSema))
     {
-        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
-            Command->kernel,
-            NeedCopy,
-            gcvFALSE,
-            previous,
-            gcmSIZEOF(gcsPATCH_LIST),
-            (gctPOINTER *)&kList
-            ));
+        Command->nextPendingPos = 0;
     }
 
-    gcmkFOOTER();
+OnError:
     return status;
 }
 
-gceSTATUS
-_WaitForAsyncCommandStamp(
-    IN gckCOMMAND Command,
-    IN gctUINT64 Stamp
+/*
+ * Sync specific channels to system channel.
+ * Record semaphores to pendingSema structure.
+ * 'SyncChannel' is cleared upon function return.
+ */
+static gceSTATUS
+_SyncToSystemChannel(
+    gckCOMMAND Command,
+    gctUINT64 SyncChannel[2]
     )
 {
-    gctUINT32 bytes;
     gceSTATUS status;
-    gctUINT32 fenceAddress;
-    gctUINT32 bufferSize;
-    gctPOINTER pointer;
-    gcmkHEADER_ARG("Stamp = 0x%llx", Stamp);
-
-    fenceAddress = Command->asyncCommand->fence->address;
+    gckKERNEL kernel = Command->kernel;
+    gckHARDWARE hardware = kernel->hardware;
+    gctUINT8 semaId[128];
+    gctUINT32 semaCount = 0;
+    gctUINT32 reqBytes = 0;
+    gctUINT32 bytes = 0;
+    gctUINT8_PTR buffer;
+    gctUINT32 i;
+    gctUINT32 pri;
 
-    gcmkONERROR(gckHARDWARE_WaitFence(Command->kernel->hardware,
-        gcvNULL,
-        Stamp,
-        fenceAddress,
-        &bytes
-        ));
+    /* Ignore system channel. */
+    SyncChannel[0] &= ~((gctUINT64)1ull);
+    SyncChannel[1] &= ~((gctUINT64)1ull);
+
+    if (!SyncChannel[0] && !SyncChannel[1])
+    {
+        return gcvSTATUS_OK;
+    }
+
+    /* Query SendSemaphore command size. */
+    gckMCFE_SendSemaphore(hardware, gcvNULL, 0, &reqBytes);
+
+    for (pri = 0; pri < 2; pri++)
+    {
+        for (i = 1; i < 64 && SyncChannel[pri]; i++)
+        {
+            gctUINT32 id;
+
+            if (!(SyncChannel[pri] & (1ull << i)))
+            {
+                continue;
+            }
+
+            /* Get a free semaphore id. */
+            gcmkONERROR(_GetNextMcfeSemaId(Command, gcvFALSE, &id));
+            semaId[semaCount++] = (gctUINT8)id;
+
+            gcmkONERROR(gckCOMMAND_Reserve(Command, reqBytes, (gctPOINTER *)&buffer, &bytes));
+
+            /* Send semaphore executed in specified channel. */
+            gckMCFE_SendSemaphore(hardware, buffer, id, &bytes);
+
+            gcmkONERROR(gckCOMMAND_ExecuteMultiChannel(Command, pri, i, reqBytes));
+
+            /* Remove the sync'ed channel. */
+            SyncChannel[pri] &= ~(1ull << i);
+        }
+    }
+
+    if (semaCount > 0)
+    {
+        gctUINT32 pos = 0;
+        gckEVENT eventObj = kernel->eventObj;
+        gctUINT32 bufferLen = 0;
+
+        /* Query WaitSemaphore command size. */
+        gckMCFE_WaitSemaphore(hardware, gcvNULL, 0, &reqBytes);
+        reqBytes *= semaCount;
+
+        gcmkONERROR(gckCOMMAND_Reserve(Command, reqBytes, (gctPOINTER *)&buffer, &bufferLen));
+
+        for (i = 0; i < semaCount; i++)
+        {
+            bytes = bufferLen;
+
+            /* Wait semaphores executed in fixed system channel. */
+            gckMCFE_WaitSemaphore(hardware, buffer, semaId[i], &bytes);
+
+            buffer    += bytes;
+            bufferLen -= bytes;
+        }
+
+        gcmkONERROR(gckCOMMAND_ExecuteMultiChannel(Command, 0, 0, reqBytes));
+
+        /* Now upload the pending semaphore tracking ring. */
+        gcmkONERROR(_GetNextPendingPos(Command, &pos));
+
+        /* Update latest pending semaphore id. */
+        Command->pendingSema[pos].semaId = (gctUINT32)semaId[semaCount - 1];
+
+        /* Send the signal by event. */
+        gcmkONERROR(gckEVENT_Signal(
+            eventObj,
+            Command->pendingSema[pos].signal,
+            gcvKERNEL_PIXEL
+            ));
+
+        gcmkONERROR(gckEVENT_Submit(
+            eventObj,
+            gcvTRUE,
+            gcvFALSE
+            ));
+    }
+
+    return gcvSTATUS_OK;
+
+OnError:
+    return status;
+}
+
+static gcmINLINE gceSTATUS
+_SyncFromSystemChannel(
+    gckCOMMAND Command,
+    gctBOOL Priority,
+    gctUINT32 ChannelId
+    )
+{
+    gceSTATUS status;
+    gckHARDWARE hardware = Command->kernel->hardware;
+    gctUINT32 reqBytes = 0;
+    gctUINT32 bytes = 0;
+    gctUINT8_PTR buffer;
+    gctUINT32 id;
+
+    if (!(Command->syncChannel[Priority ? 1 : 0] & (1ull << ChannelId)))
+    {
+        /* No need to sync. */
+        return gcvSTATUS_OK;
+    }
+
+    /* Get a semaphore. */
+    gcmkONERROR(_GetNextMcfeSemaId(Command, gcvFALSE, &id));
+
+    /* Send the semaphore in system channel. */
+    gckMCFE_SendSemaphore(hardware, gcvNULL, 0, &reqBytes);
 
     gcmkONERROR(gckCOMMAND_Reserve(
         Command,
-        bytes,
-        &pointer,
-        &bufferSize
+        reqBytes,
+        (gctPOINTER *)&buffer,
+        &bytes
         ));
 
-    gcmkONERROR(gckHARDWARE_WaitFence(
-        Command->kernel->hardware,
-        pointer,
-        Stamp,
-        fenceAddress,
+    gckMCFE_SendSemaphore(hardware, buffer, id, &bytes);
+
+    gcmkONERROR(gckCOMMAND_ExecuteMultiChannel(Command, gcvFALSE, 0, reqBytes));
+
+    /* Wait the semaphore in specific channel. */
+    gckMCFE_WaitSemaphore(hardware, gcvNULL, 0, &reqBytes);
+
+    gcmkONERROR(gckCOMMAND_Reserve(
+        Command,
+        reqBytes,
+        (gctPOINTER *)&buffer,
         &bytes
         ));
 
-    gcmkONERROR(gckCOMMAND_Execute(Command, bytes));
+    gckMCFE_WaitSemaphore(hardware, buffer, id, &bytes);
 
-    gcmkFOOTER_NO();
+    gcmkONERROR(gckCOMMAND_ExecuteMultiChannel(
+        Command,
+        Priority,
+        ChannelId,
+        reqBytes
+        ));
+
+    /* Clear the sync flag. */
+    Command->syncChannel[Priority ? 1 : 0] &= ~(1ull << ChannelId);
+
+    /* Can not track the semaphore here. */
     return gcvSTATUS_OK;
 
 OnError:
-    gcmkFOOTER();
     return status;
 }
 
-/******************************************************************************\
-**************** Helper functions for parsing gcoCMDBUF ************************
-\******************************************************************************/
-static void
-_GetCMDBUFSize(
-    IN gcoCMDBUF CommandBuffer,
-    OUT gctUINT_PTR CommandBufferSize
+static gceSTATUS
+_CheckFlushMcfeMMU(
+    IN gckCOMMAND Command,
+    IN gckHARDWARE Hardware
     )
 {
-    *CommandBufferSize
-        = CommandBuffer->offset
-        + CommandBuffer->reservedTail
-        - CommandBuffer->startOffset;
+    gceSTATUS status = gcvSTATUS_OK;
+    gctUINT32 oldValue;
+    gctUINT32 reqBytes;
+    gctUINT32 bytes;
+    gctUINT8_PTR buffer;
+    gctUINT32 id = 0;
+
+    gckOS_AtomicExchange(Command->os,
+                         Hardware->pageTableDirty[gcvENGINE_RENDER],
+                         0,
+                         &oldValue);
+
+    if (!oldValue)
+    {
+        return gcvSTATUS_OK;
+    }
+
+    /*
+     * We had sync'ed to system channel in every commit, see comments in Commit.
+     * It should not run into sync again here, unless there's some other place
+     * causes channels dirty. Let's check it here.
+     */
+    gcmkONERROR(_SyncToSystemChannel(Command, Command->dirtyChannel));
+
+    /* Query flush Mcfe MMU cache command bytes. */
+    gcmkONERROR(gckHARDWARE_FlushMcfeMMU(Hardware, gcvNULL, &reqBytes));
+
+    /* Query semaphore command bytes. */
+    gcmkONERROR(
+        gckMCFE_SendSemaphore(Hardware, gcvNULL, 0, &bytes));
+    reqBytes += bytes;
+
+    gcmkONERROR(
+        gckMCFE_WaitSemaphore(Hardware, gcvNULL, 0, &bytes));
+    reqBytes += bytes;
+
+    /* Get a semaphore. */
+    gcmkONERROR(_GetNextMcfeSemaId(Command, gcvFALSE, &id));
+
+    /* Request command buffer for system channel. */
+    gcmkONERROR(gckCOMMAND_Reserve(
+        Command,
+        reqBytes,
+        (gctPOINTER *)&buffer,
+        &bytes
+        ));
+
+    /* Do flush mmu. */
+    gckHARDWARE_FlushMcfeMMU(Hardware, buffer, &bytes);
+    buffer += bytes;
+
+    /* Send and wait semaphore in the system channel itself. */
+    gcmkONERROR(gckMCFE_SendSemaphore(Hardware, buffer, id, &bytes));
+    buffer += bytes;
+
+    gcmkONERROR(gckMCFE_WaitSemaphore(Hardware, buffer, id, &bytes));
+
+    /* Execute flush mmu and send semaphores. */
+    gckCOMMAND_ExecuteMultiChannel(Command, 0, 0, reqBytes);
+
+    /* Need sync from system channel. */
+    Command->syncChannel[0] = ~1ull;
+    Command->syncChannel[1] = ~1ull;
+
+    return gcvSTATUS_OK;
+
+OnError:
+    return status;
 }
 
-static void
-_GetCMDBUFTail(
-    IN gcoCMDBUF CommandBuffer,
-    OUT gctUINT8_PTR * Tail
+/*
+ * Find sema id from the map.
+ * Returns semaphore Id, ie the array index of semaHandleMap.
+ * -1 if not found.
+ */
+static gcmINLINE gctINT32
+_FindSemaIdFromMap(
+    IN gckCOMMAND Command,
+    IN gctUINT32 SemaHandle
     )
 {
-    gctUINT8_PTR commandBufferLogical;
-    gctUINT commandBufferSize;
+    gctUINT32 semaId = Command->nextSemaId;
 
-    commandBufferLogical
-        = (gctUINT8_PTR) gcmUINT64_TO_PTR(CommandBuffer->logical)
-        +                CommandBuffer->startOffset;
+    do
+    {
+        /*
+         * Only need to check semaId between signaledId (inclusive) and
+         * nextSemaId (exclusive).
+         */
+        semaId = (semaId == 0) ? (Command->totalSemaId - 1) : (semaId - 1);
 
-    _GetCMDBUFSize(CommandBuffer, &commandBufferSize);
+        if (Command->semaHandleMap[semaId] == SemaHandle)
+        {
+            return (gctINT32)semaId;
+        }
+    }
+    while (semaId != Command->freeSemaId);
 
-    *Tail
-        = commandBufferLogical
-        + commandBufferSize
-        - CommandBuffer->reservedTail;
+    return -1;
 }
 
-static void
-_ParseCMDBUFTail(
-    IN gckHARDWARE Hardware,
-    IN gcoCMDBUF CommandBuffer,
-    OUT gctUINT8_PTR * Fence,
-    OUT gctUINT8_PTR * Link
+/* Put together patch list handling variables. */
+typedef struct _gcsPATCH_LIST_VARIABLE
+{
+    /* gcvHAL_PATCH_VIDMEM_TIMESTAMP. */
+    gctUINT64 maxAsyncTimestamp;
+
+    /* gcvHAL_PATCH_MCFE_SEMAPHORE. */
+    gctBOOL semaUsed;
+}
+gcsPATCH_LIST_VARIABLE;
+
+/* Patch item handler typedef. */
+typedef gceSTATUS
+(* PATCH_ITEM_HANDLER)(
+    IN gckCOMMAND Command,
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer,
+    IN gctPOINTER Patch,
+    IN gcsPATCH_LIST_VARIABLE * PatchListVar
+    );
+
+static const gctUINT32 _PatchItemSize[] =
+{
+    0,
+    (gctUINT32)sizeof(gcsHAL_PATCH_VIDMEM_ADDRESS),
+    (gctUINT32)sizeof(gcsHAL_PATCH_MCFE_SEMAPHORE),
+    (gctUINT32)sizeof(gcsHAL_PATCH_VIDMEM_TIMESTAMP),
+};
+
+static gceSTATUS
+_HandleVidmemAddressPatch(
+    IN gckCOMMAND Command,
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer,
+    IN gctPOINTER Patch,
+    IN gcsPATCH_LIST_VARIABLE * PatchListVar
     )
 {
-    gctUINT8_PTR tail;
+    gceSTATUS status = gcvSTATUS_OK;
+    gcsHAL_PATCH_VIDMEM_ADDRESS * patch = Patch;
 
-    _GetCMDBUFTail(CommandBuffer, &tail);
+    gcmkHEADER_ARG("Command=%p location=0x%x node=0x%x offset=%x",
+                   Command, patch->location, patch->node, patch->offset);
 
-    if (gckHARDWARE_IsFeatureAvailable(Hardware, gcvFEATURE_FENCE_64BIT))
-    {
-        *Fence = tail;
-        *Link  = tail + gcdRENDER_FENCE_LENGTH;
-    }
-    else
-    {
-        *Fence = gcvNULL;
-        *Link  = tail;
-    }
+    (void)status;
+    (void)patch;
+
+    gcmkFOOTER();
+    return gcvSTATUS_OK;
 }
 
-gceSTATUS
-_GetCMDBUFEntry(
+static gceSTATUS
+_HandleMCFESemaphorePatch(
     IN gckCOMMAND Command,
-    IN gcoCMDBUF CommandBuffer,
-    OUT gctUINT32_PTR EntryAddress,
-    OUT gctUINT32_PTR EntryBytes
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer,
+    IN gctPOINTER Patch,
+    IN gcsPATCH_LIST_VARIABLE * PatchListVar
     )
 {
+    gckHARDWARE hardware = Command->kernel->hardware;
+    gctINT32 index;
+    gctUINT32 semaId;
     gceSTATUS status;
-    gctUINT8_PTR commandBufferLogical;
-    gctUINT commandBufferSize;
-    gckVIRTUAL_COMMAND_BUFFER_PTR virtualCommandBuffer;
-    gctUINT32 commandBufferAddress;
-    gctUINT offset;
+    gctUINT32 bytes = 8;
+    gctUINT32 buffer[2];
+    gctUINT8_PTR location;
+    gcsHAL_PATCH_MCFE_SEMAPHORE * patch = (gcsHAL_PATCH_MCFE_SEMAPHORE *)Patch;
 
-    commandBufferLogical
-        = (gctUINT8_PTR) gcmUINT64_TO_PTR(CommandBuffer->logical)
-        +                CommandBuffer->startOffset;
+    gcmkHEADER_ARG("Command=%p location=0x%x semaHandle=%d",
+                   Command, patch->location, patch->semaHandle);
 
-    /* Get the hardware address. */
-    if (Command->kernel->virtualCommandBuffer)
-    {
-        gckKERNEL kernel = Command->kernel;
+    index = _FindSemaIdFromMap(Command, patch->semaHandle);
 
-        virtualCommandBuffer = gcmNAME_TO_PTR(CommandBuffer->physical);
+    if (index < 0)
+    {
+        status = _GetNextMcfeSemaId(Command, gcvTRUE, &semaId);
 
-        if (virtualCommandBuffer == gcvNULL)
+        if (gcmIS_ERROR(status))
         {
-            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+            gcmkONERROR(_SyncToSystemChannel(Command, Command->dirtyChannel));
+            gcmkONERROR(_GetNextMcfeSemaId(Command, gcvTRUE, &semaId));
         }
 
-        gcmkONERROR(gckKERNEL_GetGPUAddress(
-            Command->kernel,
-            commandBufferLogical,
-            gcvTRUE,
-            virtualCommandBuffer,
-            &commandBufferAddress
-            ));
+        Command->semaHandleMap[semaId] = patch->semaHandle;
     }
     else
     {
-        gcmkONERROR(gckHARDWARE_ConvertLogical(
-            Command->kernel->hardware,
-            commandBufferLogical,
-            gcvTRUE,
-            &commandBufferAddress
-            ));
+        semaId = (gctUINT32)index;
+
+        /* One send must match one wait, will assign new id next time. */
+        Command->semaHandleMap[semaId] = 0;
     }
 
-    /* Get offset. */
-    gcmkONERROR(gckHARDWARE_PipeSelect(
-        Command->kernel->hardware, gcvNULL, gcvPIPE_3D, &offset
-        ));
+    if (patch->sendSema)
+    {
+        gcmkONERROR(gckMCFE_SendSemaphore(hardware, buffer, semaId, &bytes));
+    }
+    else
+    {
+        gcmkONERROR(gckMCFE_WaitSemaphore(hardware, buffer, semaId, &bytes));
+    }
+
+    gcmkASSERT(bytes == 8);
 
-    _GetCMDBUFSize(CommandBuffer, &commandBufferSize);
+    location = gcmUINT64_TO_PTR(CommandBuffer->logical + patch->location);
 
-    *EntryAddress = commandBufferAddress + offset;
-    *EntryBytes   = commandBufferSize    - offset;
+    /* Patch the command buffer. */
+    gckOS_WriteMemory(Command->os, location, buffer[0]);
+    gckOS_WriteMemory(Command->os, location + 4, buffer[1]);
 
+
+    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
+    gcmkFOOTER();
     return status;
 }
 
-/*******************************************************************************
-**
-**  Link a list of command buffer together to make them atomic.
-**  Fence will be added in the last command buffer.
-*/
-gceSTATUS
-_ProcessUserCommandBufferList(
+static gceSTATUS
+_HandleTimestampPatch(
     IN gckCOMMAND Command,
-    IN gcoCMDBUF CommandBufferListHead,
-    OUT gcoCMDBUF * CommandBufferListTail
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer,
+    IN gctPOINTER Patch,
+    IN gcsPATCH_LIST_VARIABLE * PatchListVar
     )
 {
-    gceSTATUS           status;
-    gctBOOL             needCopy;
+    gceSTATUS status;
+    gctUINT32 processID;
+    gckVIDMEM_NODE videoMem = gcvNULL;
+    gcsHAL_PATCH_VIDMEM_TIMESTAMP * patch = Patch;
+    gceENGINE engine = Command->feType == gcvHW_FE_ASYNC ? gcvENGINE_BLT
+                     : gcvENGINE_RENDER;
 
-    gcoCMDBUF           currentCMDBUF;
-    gcoCMDBUF           currentCMDBUFUser = CommandBufferListHead;
+    gcmkHEADER_ARG("Command=%p node=0x%x", Command, patch->handle);
 
-    gckOS_QueryNeedCopy(Command->os, 0, &needCopy);
+    /* Get the current process ID. */
+    gcmkONERROR(gckOS_GetProcessID(&processID));
 
-    /* Open first gcoCMDBUF object as currentCMDBUF. */
-    gcmkONERROR(gckKERNEL_OpenUserData(
-        Command->kernel,
-        needCopy,
-        &Command->_commandBufferObject,
-        currentCMDBUFUser,
-        gcmSIZEOF(struct _gcoCMDBUF),
-        (gctPOINTER *)&currentCMDBUF
-        ));
+    gcmkONERROR(
+        gckVIDMEM_HANDLE_Lookup(Command->kernel,
+                                processID,
+                                patch->handle,
+                                &videoMem));
 
-    /* Iterate the list. */
-    while (currentCMDBUF->nextCMDBUF != 0)
+    gcmkVERIFY_OK(gckVIDMEM_NODE_Reference(Command->kernel, videoMem));
+
+    /* Touch video memory node. */
+    gcmkVERIFY_OK(
+        gckVIDMEM_NODE_SetCommitStamp(Command->kernel,
+                                      engine,
+                                      videoMem,
+                                      Command->commitStamp));
+
+    if ((engine == gcvENGINE_RENDER) && Command->kernel->asyncCommand)
     {
-        gcoCMDBUF           nextCMDBUFUser;
-        gcoCMDBUF           nextCMDBUF;
-        gctUINT8_PTR        fenceLogical = gcvNULL;
-        gctUINT8_PTR        linkLogical;
-        gctUINT32           linkBytes = 8;
-        gctUINT32           linkLow;
-        gctUINT32           linkHigh;
+        /* Find the latest timestamp of the nodes used in async FE. */
+        gctUINT64 stamp = 0;
+
+        /* Get stamp touched async command buffer. */
+        gcmkVERIFY_OK(
+            gckVIDMEM_NODE_GetCommitStamp(Command->kernel,
+                                          gcvENGINE_BLT,
+                                          videoMem,
+                                          &stamp));
+
+        /* Find latest one. */
+        if (PatchListVar->maxAsyncTimestamp < stamp)
+        {
+            PatchListVar->maxAsyncTimestamp = stamp;
+        }
+    }
 
-        gctUINT32           entryAddress = 0;
-        gctUINT32           entryBytes = 0;
+OnError:
+    if (videoMem)
+    {
+        gckVIDMEM_NODE_Dereference(Command->kernel, videoMem);
+    }
 
-        nextCMDBUFUser
-            = gcmUINT64_TO_PTR(currentCMDBUF->nextCMDBUF);
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+}
 
-        /* Open next gcoCMDBUF object as nextCMDBUF. */
-        gcmkONERROR(gckKERNEL_OpenUserData(
-            Command->kernel,
-            needCopy,
-            &Command->_nextCMDBUF,
-            nextCMDBUFUser,
-            gcmSIZEOF(struct _gcoCMDBUF),
-            (gctPOINTER *)&nextCMDBUF
-            ));
+static gceSTATUS
+_HandlePatchListSingle(
+    IN gckCOMMAND Command,
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer,
+    IN gcsHAL_PATCH_LIST * PatchList,
+    IN gctBOOL NeedCopy,
+    IN gcsPATCH_LIST_VARIABLE * PatchListVar
+    )
+{
+    gceSTATUS status;
+    /* 256 bytes for storage. */
+    gctUINT64 storage[32];
+    gctPOINTER kArray = gcvNULL;
+    gctPOINTER userPtr = gcvNULL;
+    gctUINT32 index = 0;
+    gctUINT32 count = 0;
+    gctUINT32 itemSize = 0;
+    gctUINT32 batchCount = 0;
+
+    static const PATCH_ITEM_HANDLER patchHandler[] =
+    {
+        gcvNULL,
+        _HandleVidmemAddressPatch,
+        _HandleMCFESemaphorePatch,
+        _HandleTimestampPatch,
+    };
+    PATCH_ITEM_HANDLER handler;
 
-        /* Get the start hardware address of nextCMDBUF. */
-        gcmkONERROR(_GetCMDBUFEntry(Command,
-            nextCMDBUF,
-            &entryAddress,
-            &entryBytes
-            ));
+    gcmkHEADER_ARG("Command=%p CommandBuffer=%p PatchList=%p type=%d",
+                   Command, CommandBuffer, PatchList, PatchList->type);
 
-        /* Process current gcoCMDBUF object. */
-        _ParseCMDBUFTail(
-            Command->kernel->hardware,
-            currentCMDBUF,
-            &fenceLogical,
-            &linkLogical
-            );
+    if (PatchList->type >= gcmCOUNTOF(_PatchItemSize) || PatchList->type >= gcmCOUNTOF(patchHandler))
+    {
+        /* Exceeds buffer max size. */
+        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+    }
+
+    itemSize = _PatchItemSize[PatchList->type];
+
+    batchCount = (gctUINT32)(sizeof(storage) / itemSize);
+
+    handler = patchHandler[PatchList->type];
 
-        /* Don't send fence in the middle of gcoCMDBUF list. */
-        if (fenceLogical != gcvNULL)
+    while (index < PatchList->count)
+    {
+        gctUINT i;
+        gctUINT8_PTR ptr;
+
+        /* Determine batch count, don't handle too many in one batch. */
+        count = PatchList->count - index;
+
+        if (count > batchCount)
         {
-            gctUINT i = gcdRENDER_FENCE_LENGTH / gcmSIZEOF(gctUINT32) / 2;
+            count = batchCount;
+        }
 
-            /* Fill NOPs in space reserved for fence. */
-            while (i--)
-            {
-                gctSIZE_T nopBytes = 8;
-                gcmkONERROR(gckHARDWARE_Nop(Command->kernel->hardware, fenceLogical, &nopBytes));
-                fenceLogical += nopBytes;
-            }
+        userPtr = gcmUINT64_TO_PTR(PatchList->patchArray + itemSize * index);
+
+        /* Copy/map a patch array batch from user. */
+        if (NeedCopy)
+        {
+            kArray = storage;
+
+            status = gckOS_CopyFromUserData(
+                Command->os,
+                kArray,
+                userPtr,
+                itemSize * count
+                );
+        }
+        else
+        {
+            status = gckOS_MapUserPointer(
+                Command->os,
+                userPtr,
+                itemSize * count,
+                (gctPOINTER *)&kArray
+                );
         }
 
-        /* Generate a LINK from the end of current command buffer
-        ** to the start of next command buffer. */
-        gcmkONERROR(gckHARDWARE_Link(
-            Command->kernel->hardware,
-            linkLogical,
-            entryAddress,
-            entryBytes,
-            &linkBytes,
-            &linkLow,
-            &linkHigh
-            ));
+        if (gcmIS_ERROR(status))
+        {
+            userPtr = gcvNULL;
+            gcmkONERROR(status);
+        }
 
-        /* Close current gcoCMDBUF object which is processed. */
-        gcmkVERIFY_OK(gckKERNEL_CloseUserData(
-            Command->kernel,
-            needCopy,
-            gcvFALSE,
-            currentCMDBUFUser,
-            gcmSIZEOF(struct _gcoCMDBUF),
-            (gctPOINTER *)&currentCMDBUF
-            ));
+        /* Advance to next batch. */
+        index += count;
 
-        /* Advance to next gcoCMDBUF object. */
-        currentCMDBUFUser = nextCMDBUFUser;
-        currentCMDBUF     = nextCMDBUF;
-    }
+        ptr = (gctUINT8_PTR)kArray;
 
-    gcmkVERIFY_OK(gckKERNEL_CloseUserData(
-        Command->kernel,
-        needCopy,
-        gcvFALSE,
-        currentCMDBUFUser,
-        gcmSIZEOF(struct _gcoCMDBUF),
-        (gctPOINTER *)&currentCMDBUF
-        ));
+        for (i = 0; i < count; i++)
+        {
+            /* Call handler. */
+            gcmkONERROR(
+                handler(Command, CommandBuffer, ptr, PatchListVar));
+
+            /* Advance to next patch. */
+            ptr += itemSize;
+        }
 
-    /* Return the tail of the list. */
-    *CommandBufferListTail = currentCMDBUFUser;
+        /* Unmap user pointer if mapped. */
+        if (!NeedCopy)
+        {
+            gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+                Command->os,
+                userPtr,
+                itemSize * count,
+                kArray
+                ));
+        }
+    }
 
+    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
+    if (!NeedCopy && userPtr)
+    {
+        gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+            Command->os,
+            userPtr,
+            itemSize * count,
+            kArray
+            ));
+
+        userPtr = gcvNULL;
+    }
+
+    gcmkFOOTER();
     return status;
 }
-#endif
 
-/******************************************************************************\
-****************************** gckCOMMAND API Code ******************************
-\******************************************************************************/
-
-/*******************************************************************************
-**
-**  gckCOMMAND_Construct
-**
+static gceSTATUS
+_HandlePatchList(
+    IN gckCOMMAND Command,
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer,
+    OUT gcsPATCH_LIST_VARIABLE * PatchListVar
+    )
+{
+    gceSTATUS status;
+    gctBOOL needCopy = gcvFALSE;
+    gcsHAL_PATCH_LIST storage;
+    gcsHAL_PATCH_LIST * kPatchList = gcvNULL;
+    gctPOINTER userPtr = gcmUINT64_TO_PTR(CommandBuffer->patchHead);
+
+    gcmkHEADER_ARG("Command=%p CommandBuffer=%p", Command, CommandBuffer);
+
+    /* Check wehther we need to copy the structures or not. */
+    gcmkONERROR(gckOS_QueryNeedCopy(Command->os, 0, &needCopy));
+
+    while (userPtr)
+    {
+        gctUINT64 next;
+
+        /* Copy/map a patch from user. */
+        if (needCopy)
+        {
+            kPatchList = &storage;
+
+            status = gckOS_CopyFromUserData(
+                Command->os,
+                kPatchList,
+                userPtr,
+                sizeof(gcsHAL_PATCH_LIST)
+                );
+        }
+        else
+        {
+            status = gckOS_MapUserPointer(
+                Command->os,
+                userPtr,
+                sizeof(gcsHAL_PATCH_LIST),
+                (gctPOINTER *)&kPatchList
+                );
+        }
+
+        if (gcmIS_ERROR(status))
+        {
+            userPtr = gcvNULL;
+            gcmkONERROR(status);
+        }
+
+        /* Do handle patch. */
+        gcmkASSERT(kPatchList->type < gcvHAL_PATCH_TYPE_COUNT);
+
+        gcmkONERROR(
+            _HandlePatchListSingle(Command,
+                                   CommandBuffer,
+                                   kPatchList,
+                                   needCopy,
+                                   PatchListVar));
+
+        next = kPatchList->next;
+
+        /* Unmap user pointer if mapped. */
+        if (!needCopy)
+        {
+            gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+                Command->os,
+                userPtr,
+                sizeof(gcsHAL_PATCH_LIST),
+                kPatchList
+                ));
+        }
+
+        /* Advance to next patch from user. */
+        userPtr = gcmUINT64_TO_PTR(next);
+    }
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    if (!needCopy && userPtr)
+    {
+        gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+            Command->os,
+            userPtr,
+            sizeof(gcsHAL_PATCH_LIST),
+            kPatchList
+            ));
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_WaitForAsyncCommandStamp(
+    IN gckCOMMAND Command,
+    IN gctUINT64 Stamp
+    )
+{
+    gctUINT32 bytes;
+    gceSTATUS status;
+    gctUINT32 fenceAddress;
+    gctUINT32 bufferSize;
+    gctPOINTER pointer;
+    gckCOMMAND asyncCommand = Command->kernel->asyncCommand;
+
+    gcmkHEADER_ARG("Stamp = 0x%llx", Stamp);
+
+    if (*(gctUINT64 *)asyncCommand->fence->logical >= Stamp)
+    {
+        /* Already satisfied, skip. */
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
+
+    fenceAddress = asyncCommand->fence->address;
+
+    gcmkONERROR(gckHARDWARE_WaitFence(
+        Command->kernel->hardware,
+        gcvNULL,
+        Stamp,
+        fenceAddress,
+        &bytes
+        ));
+
+    gcmkONERROR(gckCOMMAND_Reserve(
+        Command,
+        bytes,
+        &pointer,
+        &bufferSize
+        ));
+
+    gcmkONERROR(gckHARDWARE_WaitFence(
+        Command->kernel->hardware,
+        pointer,
+        Stamp,
+        fenceAddress,
+        &bytes
+        ));
+
+    gcmkONERROR(gckCOMMAND_Execute(Command, bytes));
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+/******************************************************************************\
+****************************** gckCOMMAND API Code ******************************
+\******************************************************************************/
+
+/*******************************************************************************
+**
+**  gckCOMMAND_Construct
+**
 **  Construct a new gckCOMMAND object.
 **
 **  INPUT:
@@ -1060,6 +1332,7 @@ OnError:
 gceSTATUS
 gckCOMMAND_Construct(
     IN gckKERNEL Kernel,
+    IN gceHW_FE_TYPE FeType,
     OUT gckCOMMAND * Command
     )
 {
@@ -1070,7 +1343,7 @@ gckCOMMAND_Construct(
     gctPOINTER pointer = gcvNULL;
     gctSIZE_T pageSize;
 
-    gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+    gcmkHEADER_ARG("Kernel=%p", Kernel);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -1091,12 +1364,14 @@ gckCOMMAND_Construct(
     command->kernel         = Kernel;
     command->os             = os;
 
+    command->feType         = FeType;
+
     /* Get the command buffer requirements. */
     gcmkONERROR(gckHARDWARE_QueryCommandBuffer(
         Kernel->hardware,
         gcvENGINE_RENDER,
         &command->alignment,
-        &command->reservedHead,
+        gcvNULL,
         gcvNULL
         ));
 
@@ -1129,56 +1404,43 @@ gckCOMMAND_Construct(
     /* Pre-allocate the command queues. */
     for (i = 0; i < gcdCOMMAND_QUEUES; ++i)
     {
-#if USE_KERNEL_VIRTUAL_BUFFERS
-        if (Kernel->virtualCommandBuffer)
-        {
-            gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
-                Kernel,
-                gcvFALSE,
-                &pageSize,
-                &command->queues[i].physical,
-                &command->queues[i].logical
-                ));
-
-            gcmkONERROR(gckKERNEL_GetGPUAddress(
-                Kernel,
-                command->queues[i].logical,
-                gcvFALSE,
-                command->queues[i].physical,
-                &command->queues[i].address
-                ));
-        }
-        else
-#endif
-        {
-            gctUINT32 allocFlag;
+        gcePOOL pool = gcvPOOL_DEFAULT;
+        gctSIZE_T size = pageSize;
+        gckVIDMEM_NODE videoMem = gcvNULL;
+        gctUINT32 allocFlag = 0;
 
 #if gcdENABLE_CACHEABLE_COMMAND_BUFFER
-            allocFlag = gcvALLOC_FLAG_CACHEABLE | gcvALLOC_FLAG_CONTIGUOUS;
-#else
-            allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+        allocFlag = gcvALLOC_FLAG_CACHEABLE;
 #endif
 
-            gcmkONERROR(gckOS_AllocateNonPagedMemory(
-                os,
-                gcvFALSE,
-                allocFlag,
-                &pageSize,
-                &command->queues[i].physical,
-                &command->queues[i].logical
-                ));
+        /* Allocate video memory node for command buffers. */
+        gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+            Kernel,
+            64,
+            gcvVIDMEM_TYPE_COMMAND,
+            allocFlag,
+            &size,
+            &pool,
+            &videoMem
+            ));
 
-            gcmkONERROR(gckHARDWARE_ConvertLogical(
-                Kernel->hardware,
-                command->queues[i].logical,
-                gcvFALSE,
-                &command->queues[i].address
-                ));
+        command->queues[i].videoMem = videoMem;
 
-            gcmkONERROR(gckMMU_FillFlatMapping(
-                Kernel->mmu, command->queues[i].address, pageSize
-                ));
-        }
+        /* Lock for GPU access. */
+        gcmkONERROR(gckVIDMEM_NODE_Lock(
+            Kernel,
+            videoMem,
+            &command->queues[i].address
+            ));
+
+        /* Lock for kernel side CPU access. */
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+            Kernel,
+            videoMem,
+            gcvFALSE,
+            gcvFALSE,
+            &command->queues[i].logical
+            ));
 
         gcmkONERROR(gckOS_CreateSignal(
             os, gcvFALSE, &command->queues[i].signal
@@ -1193,8 +1455,6 @@ gckCOMMAND_Construct(
     gcmkONERROR(gckRECORDER_Construct(os, Kernel->hardware, &command->recorder));
 #endif
 
-    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsPATCH_LIST), &command->kList));
-
     gcmkONERROR(gckFENCE_Create(
         os, Kernel, &command->fence
         ));
@@ -1204,6 +1464,46 @@ gckCOMMAND_Construct(
     command->logical  = gcvNULL;
     command->newQueue = gcvFALSE;
 
+    /* Query mcfe semaphore count. */
+    if (FeType == gcvHW_FE_MULTI_CHANNEL)
+    {
+        command->totalSemaId = 128;
+
+        /* Empty sema id ring. */
+        command->nextSemaId = 0;
+        command->freeSemaId = command->totalSemaId - 1;
+
+        command->semaMinThreshhold = 16;
+
+        /* Create signals. */
+        for (i = 0; i < (gctINT)gcmCOUNTOF(command->pendingSema); i++)
+        {
+            gcmkONERROR(gckOS_CreateSignal(
+                os,
+                gcvFALSE,
+                &command->pendingSema[i].signal
+                ));
+        }
+
+        /* Empty pending sema tracking ring. */
+        command->nextPendingPos = 0;
+        command->freePendingPos = gcmCOUNTOF(command->pendingSema) - 1;
+
+        /* Allocate sema handle mapping. */
+        gcmkONERROR(gckOS_Allocate(
+            os,
+            command->totalSemaId * sizeof(gctUINT32),
+            &pointer
+            ));
+
+        command->semaHandleMap = (gctUINT32 *)pointer;
+
+        gcmkVERIFY_OK(gckOS_ZeroMemory(
+            command->semaHandleMap,
+            command->totalSemaId * sizeof(gctUINT32)
+            ));
+    }
+
     /* Command is not yet running. */
     command->running = gcvFALSE;
 
@@ -1213,9 +1513,6 @@ gckCOMMAND_Construct(
     /* Commit stamp start from 1. */
     command->commitStamp = 1;
 
-    /* END event signal not created. */
-    command->endEventSignal = gcvNULL;
-
     command->dummyDraw = gcvTRUE;
 
     /* Return pointer to the gckCOMMAND object. */
@@ -1259,7 +1556,7 @@ gckCOMMAND_Destroy(
 {
     gctINT i;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
@@ -1278,35 +1575,28 @@ gckCOMMAND_Destroy(
 
         if (Command->queues[i].logical)
         {
-#if USE_KERNEL_VIRTUAL_BUFFERS
-            if (Command->kernel->virtualCommandBuffer)
-            {
-                gcmkVERIFY_OK(gckKERNEL_DestroyVirtualCommandBuffer(
-                    Command->kernel,
-                    Command->pageSize,
-                    Command->queues[i].physical,
-                    Command->queues[i].logical
-                    ));
-            }
-            else
-#endif
-            {
-                gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(
-                    Command->os,
-                    Command->pageSize,
-                    Command->queues[i].physical,
-                    Command->queues[i].logical
-                    ));
-            }
-        }
-    }
+            gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+                Command->kernel,
+                Command->queues[i].videoMem,
+                0,
+                gcvFALSE
+                ));
 
-    /* END event signal. */
-    if (Command->endEventSignal != gcvNULL)
-    {
-        gcmkVERIFY_OK(gckOS_DestroySignal(
-            Command->os, Command->endEventSignal
-            ));
+            gcmkVERIFY_OK(gckVIDMEM_NODE_Unlock(
+                Command->kernel,
+                Command->queues[i].videoMem,
+                0,
+                gcvNULL
+                ));
+
+            gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+                Command->kernel,
+                Command->queues[i].videoMem
+                ));
+
+            Command->queues[i].videoMem = gcvNULL;
+            Command->queues[i].logical  = gcvNULL;
+        }
     }
 
     if (Command->mutexContext)
@@ -1336,15 +1626,6 @@ gckCOMMAND_Destroy(
         gcmkVERIFY_OK(gckOS_AtomDestroy(Command->os, Command->atomCommit));
     }
 
-#if gcdSECURE_USER
-    /* Free state array. */
-    if (Command->hintArrayAllocated)
-    {
-        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Command->os, gcmUINT64_TO_PTR(Command->hintArray)));
-        Command->hintArrayAllocated = gcvFALSE;
-    }
-#endif
-
 #if gcdRECORD_COMMAND
     gckRECORDER_Destory(Command->os, Command->recorder);
 #endif
@@ -1354,9 +1635,9 @@ gckCOMMAND_Destroy(
         gcmkOS_SAFE_FREE(Command->os, Command->stateMap);
     }
 
-    if (Command->kList)
+    if (Command->semaHandleMap)
     {
-        gcmkOS_SAFE_FREE(Command->os, Command->kList);
+        gcmkOS_SAFE_FREE(Command->os, Command->semaHandleMap);
     }
 
     if (Command->fence)
@@ -1405,7 +1686,7 @@ gckCOMMAND_EnterCommit(
     gctBOOL atomIncremented = gcvFALSE;
     gctBOOL semaAcquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Extract the gckHARDWARE and gckEVENT objects. */
     hardware = Command->kernel->hardware;
@@ -1487,7 +1768,7 @@ gckCOMMAND_ExitCommit(
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Release the power mutex. */
     gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexQueue));
@@ -1512,23 +1793,8 @@ OnError:
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckCOMMAND_Start
-**
-**  Start up the command queue.
-**
-**  INPUT:
-**
-**      gckCOMMAND Command
-**          Pointer to an gckCOMMAND object to start.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckCOMMAND_Start(
+static gceSTATUS
+_StartWaitLinkFE(
     IN gckCOMMAND Command
     )
 {
@@ -1537,10 +1803,9 @@ gckCOMMAND_Start(
     gctUINT32 waitOffset = 0;
     gctUINT32 waitLinkBytes;
     gctPOINTER logical;
-    gctUINT32 physical;
     gctUINT32 address;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
@@ -1557,7 +1822,7 @@ gckCOMMAND_Start(
     gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
 
     /* Query the size of WAIT/LINK command sequence. */
-    gcmkONERROR(gckHARDWARE_WaitLink(
+    gcmkONERROR(gckWLFE_WaitLink(
         hardware,
         gcvNULL,
         ~0U,
@@ -1576,30 +1841,28 @@ gckCOMMAND_Start(
     }
 
     logical  = (gctUINT8_PTR) Command->logical + Command->offset;
-    physical =                Command->physical + Command->offset;
     address  =                Command->address + Command->offset;
 
     /* Append WAIT/LINK. */
-    gcmkONERROR(gckHARDWARE_WaitLink(
+    gcmkONERROR(gckWLFE_WaitLink(
         hardware,
         logical,
         address,
         0,
         &waitLinkBytes,
         &waitOffset,
-        &Command->waitSize
+        &Command->waitPos.size
         ));
 
-    Command->waitLogical  = (gctUINT8_PTR) logical  + waitOffset;
-    Command->waitPhysical =                physical + waitOffset;
-    Command->waitAddress  =                address  + waitOffset;
-    Command->waitOffset   =                waitOffset;
+    /* Update wait command position. */
+    Command->waitPos.videoMem = Command->videoMem;
+    Command->waitPos.offset   = Command->offset + waitOffset;
+    Command->waitPos.logical  = (gctUINT8_PTR) logical  + waitOffset;
+    Command->waitPos.address  =                address  + waitOffset;
 
-    /* Flush the cache for the wait/link. */
-    gcmkONERROR(gckOS_CacheClean(
-        Command->os,
-        0,
-        Command->physHandle,
+    gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+        Command->kernel,
+        Command->videoMem,
         Command->offset,
         logical,
         waitLinkBytes
@@ -1609,6 +1872,15 @@ gckCOMMAND_Start(
     Command->offset   += waitLinkBytes;
     Command->newQueue = gcvFALSE;
 
+    gcmkDUMP(Command->os, "#[wait-link: fe start]");
+    gcmkDUMP_BUFFER(
+        Command->os,
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
+        logical,
+        address,
+        waitLinkBytes
+        );
+
 #if gcdSECURITY
     /* Start FE by calling security service. */
     gckKERNEL_SecurityStartCommand(
@@ -1616,7 +1888,7 @@ gckCOMMAND_Start(
         );
 #else
     /* Enable command processor. */
-    gcmkONERROR(gckHARDWARE_Execute(
+    gcmkONERROR(gckWLFE_Execute(
         hardware,
         address,
         waitLinkBytes
@@ -1636,114 +1908,211 @@ OnError:
     return status;
 }
 
+static gceSTATUS
+_StartAsyncFE(
+    IN gckCOMMAND Command
+    )
+{
+    if ((Command->pageSize <= Command->offset) ||
+        (Command->logical == gcvNULL))
+    {
+        /* Start at beginning of a new queue. */
+        gcmkVERIFY_OK(_NewQueue(Command, gcvTRUE));
+    }
+
+    /* Command queue is running. */
+    Command->running = gcvTRUE;
+
+    /* Nothing to do. */
+    return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_StartMCFE(
+    IN gckCOMMAND Command
+    )
+{
+    if ((Command->pageSize <= Command->offset) ||
+        (Command->logical == gcvNULL))
+    {
+        /* Start at beginning of a new queue. */
+        gcmkVERIFY_OK(_NewQueue(Command, gcvTRUE));
+    }
+
+    /* Command queue is running. */
+    Command->running = gcvTRUE;
+
+    /* Nothing to do. */
+    return gcvSTATUS_OK;
+}
+
 /*******************************************************************************
 **
-**  gckCOMMAND_Stop
+**  gckCOMMAND_Start
 **
-**  Stop the command queue.
+**  Start up the command queue.
 **
 **  INPUT:
 **
 **      gckCOMMAND Command
-**          Pointer to an gckCOMMAND object to stop.
+**          Pointer to an gckCOMMAND object to start.
 **
 **  OUTPUT:
 **
 **      Nothing.
 */
 gceSTATUS
-gckCOMMAND_Stop(
+gckCOMMAND_Start(
     IN gckCOMMAND Command
     )
 {
-    gckHARDWARE hardware;
     gceSTATUS status;
-    gctUINT32 idle;
-
-    gcmkHEADER_ARG("Command=0x%x", Command);
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+    gcmkHEADER_ARG("Command=%p", Command);
 
-    if (!Command->running)
+    if (Command->feType == gcvHW_FE_WAIT_LINK)
     {
-        /* Command queue is not running. */
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
+        gcmkONERROR(_StartWaitLinkFE(Command));
     }
-
-    /* Extract the gckHARDWARE object. */
-    hardware = Command->kernel->hardware;
-    gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
-
-    if (gckHARDWARE_IsFeatureAvailable(hardware,
-                                       gcvFEATURE_END_EVENT) == gcvSTATUS_TRUE)
+    else if (Command->feType == gcvHW_FE_MULTI_CHANNEL)
     {
-        /* Allocate the signal. */
-        if (Command->endEventSignal == gcvNULL)
-        {
-            gcmkONERROR(gckOS_CreateSignal(Command->os,
-                                           gcvTRUE,
-                                           &Command->endEventSignal));
-        }
-
-        /* Append the END EVENT command to trigger the signal. */
-        gcmkONERROR(gckEVENT_Stop(Command->kernel->eventObj,
-                                  Command->kernelProcessID,
-                                  Command->physHandle,
-                                  Command->offset + Command->waitOffset,
-                                  Command->waitLogical,
-                                  Command->waitAddress,
-                                  Command->endEventSignal,
-                                  &Command->waitSize));
+        gcmkONERROR(_StartMCFE(Command));
     }
     else
     {
-        /* Replace last WAIT with END. */
-        gcmkONERROR(gckHARDWARE_End(
-            hardware,
-            Command->waitLogical,
-            Command->waitAddress,
-            &Command->waitSize
-            ));
+        gcmkONERROR(_StartAsyncFE(Command));
+    }
 
-#if USE_KERNEL_VIRTUAL_BUFFERS
-        if (hardware->kernel->virtualCommandBuffer)
-        {
-            gcmkONERROR(gckKERNEL_GetGPUAddress(
-                hardware->kernel,
-                Command->waitLogical,
-                gcvFALSE,
-                Command->virtualMemory,
-                &hardware->lastEnd
-                ));
-        }
-#endif
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+
+}
+
+static gceSTATUS
+_StopWaitLinkFE(
+    IN gckCOMMAND Command
+    )
+{
+    gckHARDWARE hardware;
+    gceSTATUS status;
+    gctUINT32 idle;
+
+    gcmkHEADER_ARG("Command=%p", Command);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
+
+    /* Extract the gckHARDWARE object. */
+    hardware = Command->kernel->hardware;
+    gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
+
+    /* Replace last WAIT with END. */
+    gcmkONERROR(gckWLFE_End(
+        hardware,
+        Command->waitPos.logical,
+        Command->waitPos.address,
+        &Command->waitPos.size
+        ));
+
+    gcmkDUMP(Command->os, "#[end: fe stop]");
+    gcmkDUMP_BUFFER(
+        Command->os,
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
+        Command->waitPos.logical,
+        Command->waitPos.address,
+        Command->waitPos.size
+        );
 
 #if gcdSECURITY
-        gcmkONERROR(gckKERNEL_SecurityExecute(
-            Command->kernel, Command->waitLogical, 8
-            ));
+    gcmkONERROR(gckKERNEL_SecurityExecute(
+        Command->kernel, Command->waitPos.logical, 8
+        ));
 #endif
 
-        /* Update queue tail pointer. */
-        gcmkONERROR(gckHARDWARE_UpdateQueueTail(Command->kernel->hardware,
-                                                Command->logical,
-                                                Command->offset));
+    /* Update queue tail pointer. */
+    gcmkONERROR(gckHARDWARE_UpdateQueueTail(Command->kernel->hardware,
+                                            Command->logical,
+                                            Command->offset));
 
-        /* Flush the cache for the END. */
-        gcmkONERROR(gckOS_CacheClean(
-            Command->os,
-            0,
-            Command->physHandle,
-            Command->offset + Command->waitOffset,
-            Command->waitLogical,
-            Command->waitSize
-            ));
+    gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+        Command->kernel,
+        Command->waitPos.videoMem,
+        Command->waitPos.offset,
+        Command->waitPos.logical,
+        Command->waitPos.size
+        ));
 
-        /* Wait for idle. */
-        gcmkONERROR(gckHARDWARE_GetIdle(hardware, gcvTRUE, &idle));
-    }
+    /* Wait for idle. */
+    gcmkONERROR(gckHARDWARE_GetIdle(hardware, gcvTRUE, &idle));
+
+    /* Command queue is no longer running. */
+    Command->running = gcvFALSE;
+
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_StopAsyncFE(
+    IN gckCOMMAND Command
+    )
+{
+    gckHARDWARE hardware;
+    gceSTATUS status;
+    gctUINT32 idle;
+
+    gcmkHEADER_ARG("Command=%p", Command);
+
+    hardware = Command->kernel->hardware;
+
+    /* Update queue tail pointer. */
+    gcmkONERROR(gckHARDWARE_UpdateQueueTail(hardware,
+                                            Command->logical,
+                                            Command->offset));
+
+    /* Wait for idle. */
+    gcmkONERROR(gckHARDWARE_GetIdle(hardware, gcvTRUE, &idle));
+
+    /* Command queue is no longer running. */
+    Command->running = gcvFALSE;
+
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_StopMCFE(
+    IN gckCOMMAND Command
+    )
+{
+    gceSTATUS status;
+    gckHARDWARE hardware;
+
+    gcmkHEADER_ARG("Command=%p", Command);
+
+    hardware = Command->kernel->hardware;
+
+    /* Update queue tail pointer. */
+    gcmkONERROR(gckHARDWARE_UpdateQueueTail(hardware,
+                                            Command->logical,
+                                            Command->offset));
 
     /* Command queue is no longer running. */
     Command->running = gcvFALSE;
@@ -1760,74 +2129,74 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckCOMMAND_Commit
+**  gckCOMMAND_Stop
 **
-**  Commit a command buffer to the command queue.
+**  Stop the command queue.
 **
 **  INPUT:
 **
 **      gckCOMMAND Command
-**          Pointer to a gckCOMMAND object.
-**
-**      gckCONTEXT Context
-**          Pointer to a gckCONTEXT object.
-**
-**      gcoCMDBUF CommandBuffer
-**          Pointer to a gcoCMDBUF object.
-**
-**      gcsSTATE_DELTA_PTR StateDelta
-**          Pointer to the state delta.
-**
-**      gctUINT32 ProcessID
-**          Current process ID.
+**          Pointer to an gckCOMMAND object to stop.
 **
 **  OUTPUT:
 **
 **      Nothing.
 */
 gceSTATUS
-gckCOMMAND_Commit(
+gckCOMMAND_Stop(
+    IN gckCOMMAND Command
+    )
+{
+    if (!Command->running)
+    {
+        /* Command queue is not running. */
+        return gcvSTATUS_OK;
+    }
+
+    if (Command->feType == gcvHW_FE_WAIT_LINK)
+    {
+        return _StopWaitLinkFE(Command);
+    }
+    else if (Command->feType == gcvHW_FE_MULTI_CHANNEL)
+    {
+        return _StopMCFE(Command);
+    }
+    else
+    {
+        return _StopAsyncFE(Command);
+    }
+}
+
+static gceSTATUS
+_CommitWaitLinkOnce(
     IN gckCOMMAND Command,
     IN gckCONTEXT Context,
-    IN gcoCMDBUF CommandBuffer,
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer,
     IN gcsSTATE_DELTA_PTR StateDelta,
     IN gctUINT32 ProcessID,
-    IN gctBOOL Shared,
-    IN gctUINT32 Index,
-    OUT gctUINT64_PTR CommitStamp,
-    OUT gctBOOL_PTR ContextSwitched
+    IN gctBOOL Shared
     )
 {
     gceSTATUS status;
     gctBOOL commitEntered = gcvFALSE;
     gctBOOL contextAcquired = gcvFALSE;
     gckHARDWARE hardware;
-    gctBOOL needCopy = gcvFALSE;
-    gctBOOL commandBufferMapped = gcvFALSE;
-    gcoCMDBUF commandBufferObject = gcvNULL;
-    gctBOOL stall = gcvFALSE;
-    gctBOOL contextSwitched = gcvFALSE;
+    gcsPATCH_LIST_VARIABLE patchListVar = {0, 0};
 
-#if !gcdNULL_DRIVER
     gcsCONTEXT_PTR contextBuffer;
-    gctPHYS_ADDR_T commandBufferPhysical;
     gctUINT8_PTR commandBufferLogical = gcvNULL;
     gctUINT32 commandBufferAddress = 0;
+    gckVIDMEM_NODE commandBufferVideoMem = gcvNULL;
     gctUINT8_PTR commandBufferTail = gcvNULL;
     gctUINT commandBufferSize;
-    gctSIZE_T nopBytes;
-    gctUINT32 pipeBytes;
     gctUINT32 linkBytes;
     gctSIZE_T bytes;
     gctUINT32 offset;
     gctPOINTER entryLogical;
     gctUINT32 entryAddress;
     gctUINT32 entryBytes;
-    gctUINT32 exitOffset;
-    gctPOINTER exitLogical;
     gctUINT32 exitAddress;
     gctUINT32 exitBytes;
-    gctUINT32 waitLinkPhysical;
     gctPOINTER waitLinkLogical;
     gctUINT32 waitLinkAddress;
     gctUINT32 waitLinkBytes;
@@ -1839,61 +2208,26 @@ gckCOMMAND_Commit(
     gctBOOL    userCommandBufferLogicalMapped = gcvFALSE;
 #endif
 
-#if gcdPROCESS_ADDRESS_SPACE
-    gckMMU mmu;
-    gctUINT32 oldValue;
-#endif
-
-#if gcdDUMP_COMMAND
+#if gcdDUMP_IN_KERNEL
     gctPOINTER contextDumpLogical = gcvNULL;
-    gctSIZE_T contextDumpBytes = 0;
-    gctPOINTER bufferDumpLogical = gcvNULL;
-    gctSIZE_T bufferDumpBytes = 0;
 # endif
     gctUINT32 exitLinkLow = 0, exitLinkHigh = 0;
     gctUINT32 entryLinkLow = 0, entryLinkHigh = 0;
     gctUINT32 commandLinkLow = 0, commandLinkHigh = 0;
 
-    gckVIRTUAL_COMMAND_BUFFER_PTR virtualCommandBuffer = gcvNULL;
-    gctUINT64 asyncCommandStamp = 0;
-    gcoCMDBUF lastCommandBuffer = gcvNULL;
-    gctPOINTER pointer = gcvNULL;
-    gckKERNEL kernel = Command->kernel;
-
-    gctPHYS_ADDR contextPhysHandle = gcvNULL;
-    gctPHYS_ADDR physHandle = gcvNULL;
-#endif
-
-    gcmkHEADER_ARG(
-        "Command=0x%x CommandBuffer=0x%x ProcessID=%d",
+    gcmkHEADER_ARG("Command=%p CommandBuffer=%p ProcessID=%d",
         Command, CommandBuffer, ProcessID
         );
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
 
-#if gcdPROCESS_ADDRESS_SPACE
-    gcmkONERROR(gckKERNEL_GetProcessMMU(Command->kernel, &mmu));
-
-    gcmkONERROR(gckOS_AtomicExchange(Command->os,
-                                     mmu->pageTableDirty[Command->kernel->core],
-                                     0,
-                                     &oldValue));
-#else
-#endif
+    gcmkASSERT(Command->feType == gcvHW_FE_WAIT_LINK);
 
     /* Acquire the command queue. */
     gcmkONERROR(gckCOMMAND_EnterCommit(Command, gcvFALSE));
     commitEntered = gcvTRUE;
 
-#if !gcdNULL_DRIVER
-    gcmkONERROR(_ProcessUserCommandBufferList(
-        Command,
-        CommandBuffer,
-        &lastCommandBuffer
-        ));
-#endif
-
     /* Acquire the context switching mutex. */
     gcmkONERROR(gckOS_AcquireMutex(
         Command->os, Command->mutexContext, gcvINFINITE
@@ -1903,138 +2237,46 @@ gckCOMMAND_Commit(
     /* Extract the gckHARDWARE and gckEVENT objects. */
     hardware = Command->kernel->hardware;
 
-    /* Check wehther we need to copy the structures or not. */
-    gcmkONERROR(gckOS_QueryNeedCopy(Command->os, ProcessID, &needCopy));
-
-#if gcdNULL_DRIVER
-    /* Context switch required? */
-    if ((Context != gcvNULL) && (Command->currContext != Context))
-    {
-        /* Yes, merge in the deltas. */
-        gckCONTEXT_Update(Context, ProcessID, StateDelta);
-
-        /* Update the current context. */
-        Command->currContext = Context;
-
-        contextSwitched = gcvTRUE;
-    }
-#else
-    if (needCopy)
-    {
-        commandBufferObject = &Command->_commandBufferObject;
-
-        gcmkONERROR(gckOS_CopyFromUserData(
-            Command->os,
-            commandBufferObject,
-            CommandBuffer,
-            gcmSIZEOF(struct _gcoCMDBUF)
-            ));
-
-        gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
-    }
-    else
-    {
-        gcmkONERROR(gckOS_MapUserPointer(
-            Command->os,
-            CommandBuffer,
-            gcmSIZEOF(struct _gcoCMDBUF),
-            &pointer
-            ));
-
-        commandBufferObject = pointer;
-
-        gcmkVERIFY_OBJECT(commandBufferObject, gcvOBJ_COMMANDBUFFER);
-        commandBufferMapped = gcvTRUE;
-    }
 
-    gcmkONERROR(_HandlePatchList(Command, commandBufferObject, needCopy, &asyncCommandStamp));
-
-    /* Query the size of NOP command. */
-    gcmkONERROR(gckHARDWARE_Nop(
-        hardware, gcvNULL, &nopBytes
-        ));
-
-    /* Query the size of pipe select command sequence. */
-    gcmkONERROR(gckHARDWARE_PipeSelect(
-        hardware, gcvNULL, gcvPIPE_3D, &pipeBytes
-        ));
+    gcmkONERROR(
+        _HandlePatchList(Command, CommandBuffer, &patchListVar));
 
     /* Query the size of LINK command. */
-    gcmkONERROR(gckHARDWARE_Link(
+    gcmkONERROR(gckWLFE_Link(
         hardware, gcvNULL, 0, 0, &linkBytes, gcvNULL, gcvNULL
         ));
 
     /* Compute the command buffer entry and the size. */
     commandBufferLogical
-        = (gctUINT8_PTR) gcmUINT64_TO_PTR(commandBufferObject->logical)
-        +                commandBufferObject->startOffset;
-
-
-    /* Get the hardware address. */
-    if (Command->kernel->virtualCommandBuffer)
-    {
-        virtualCommandBuffer = gcmNAME_TO_PTR(commandBufferObject->physical);
-        physHandle = virtualCommandBuffer->virtualBuffer.physical;
-
-        if (virtualCommandBuffer == gcvNULL)
-        {
-            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-        }
-
-        gcmkONERROR(gckKERNEL_GetGPUAddress(
-            Command->kernel,
-            commandBufferLogical,
-            gcvTRUE,
-            virtualCommandBuffer,
-            &commandBufferAddress
-            ));
-    }
-    else
-    {
-        physHandle = gcmNAME_TO_PTR(commandBufferObject->physical);
+        = (gctUINT8_PTR) gcmUINT64_TO_PTR(CommandBuffer->logical)
+        +                CommandBuffer->startOffset;
 
-        gcmkONERROR(gckHARDWARE_ConvertLogical(
-            hardware,
-            commandBufferLogical,
-            gcvTRUE,
-            &commandBufferAddress
-            ));
-    }
+    commandBufferAddress = CommandBuffer->address
+                         + CommandBuffer->startOffset;
 
 #ifdef __QNXNTO__
-    userCommandBufferLogical = (gctPOINTER) commandBufferLogical;
-
-    gcmkONERROR(gckOS_MapUserPointer(
-        Command->os,
-        userCommandBufferLogical,
-        0,
-        &pointer));
-
-    commandBufferLogical = pointer;
-
-    userCommandBufferLogicalMapped = gcvTRUE;
-
-    gcmkONERROR(gckOS_GetPhysicalAddress(
-        Command->os,
-        commandBufferLogical,
-        &commandBufferPhysical
+    gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+        Command->kernel,
+        ProcessID,
+        CommandBuffer->videoMemNode,
+        &commandBufferVideoMem
         ));
 
-#else
-    /* Get the physical address. */
-    gcmkONERROR(gckOS_UserLogicalToPhysical(
-        Command->os,
-        commandBufferLogical,
-        &commandBufferPhysical
+    gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+        Command->kernel,
+        commandBufferVideoMem,
+        gcvFALSE,
+        gcvFALSE,
+        &userCommandBufferLogical
         ));
+
+    commandBufferLogical = (gctUINT8_PTR)userCommandBufferLogical + CommandBuffer->startOffset;
+    userCommandBufferLogicalMapped =gcvTRUE;
 #endif
 
-    commandBufferSize
-        = commandBufferObject->offset
-        + commandBufferObject->reservedTail
-        - commandBufferObject->startOffset;
+    commandBufferSize = CommandBuffer->size;
 
-    gcmkONERROR(_FlushMMU(Command));
+    gcmkONERROR(_CheckFlushMMU(Command, hardware));
 
     if (Command->dummyDraw == gcvTRUE &&
         Context != gcvNULL)
@@ -2043,9 +2285,14 @@ gckCOMMAND_Commit(
         gcmkONERROR(_DummyDraw(Command));
     }
 
-    if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_FENCE_64BIT) && asyncCommandStamp != 0)
+    if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_FENCE_64BIT) &&
+        Command->kernel->asyncCommand &&
+        patchListVar.maxAsyncTimestamp != 0)
     {
-        gcmkONERROR(_WaitForAsyncCommandStamp(Command, asyncCommandStamp));
+        gcmkONERROR(_WaitForAsyncCommandStamp(
+            Command,
+            patchListVar.maxAsyncTimestamp
+            ));
     }
 
     /* Get the current offset. */
@@ -2055,7 +2302,7 @@ gckCOMMAND_Commit(
     bytes = Command->pageSize - offset;
 
     /* Query the size of WAIT/LINK command sequence. */
-    gcmkONERROR(gckHARDWARE_WaitLink(
+    gcmkONERROR(gckWLFE_WaitLink(
         hardware,
         gcvNULL,
         ~0U,
@@ -2080,7 +2327,6 @@ gckCOMMAND_Commit(
     }
 
     /* Compute the location if WAIT/LINK command sequence. */
-    waitLinkPhysical =                Command->physical + offset;
     waitLinkLogical  = (gctUINT8_PTR) Command->logical  + offset;
     waitLinkAddress  =                Command->address  + offset;
 
@@ -2088,24 +2334,29 @@ gckCOMMAND_Commit(
     if (Context == gcvNULL)
     {
         /* See if we have to switch pipes for the command buffer. */
-        if (commandBufferObject->entryPipe == Command->pipeSelect)
+        if (CommandBuffer->entryPipe == (gctUINT32)(Command->pipeSelect))
         {
-            /* Skip pipe switching sequence. */
-            offset = pipeBytes;
+            /* Skip reserved head bytes. */
+            offset = CommandBuffer->reservedHead;
         }
         else
         {
+            gctUINT32 pipeBytes = CommandBuffer->reservedHead;
+
             /* The current hardware and the entry command buffer pipes
             ** are different, switch to the correct pipe. */
             gcmkONERROR(gckHARDWARE_PipeSelect(
                 Command->kernel->hardware,
                 commandBufferLogical,
-                commandBufferObject->entryPipe,
+                CommandBuffer->entryPipe,
                 &pipeBytes
                 ));
 
             /* Do not skip pipe switching sequence. */
             offset = 0;
+
+            /* Reserved bytes in userspace must be exact for a pipeSelect. */
+            gcmkASSERT(pipeBytes == CommandBuffer->reservedHead);
         }
 
         /* Compute the entry. */
@@ -2127,8 +2378,6 @@ gckCOMMAND_Commit(
         /* Yes, merge in the deltas. */
         gcmkONERROR(gckCONTEXT_Update(Context, ProcessID, StateDelta));
 
-        contextSwitched = gcvTRUE;
-
         /***************************************************************
         ** SWITCHING CONTEXT.
         */
@@ -2149,29 +2398,34 @@ gckCOMMAND_Commit(
 
         /* See if we have to switch pipes between the context
             and command buffers. */
-        if (commandBufferObject->entryPipe == gcvPIPE_3D)
+        if (CommandBuffer->entryPipe == gcvPIPE_3D)
         {
-            /* Skip pipe switching sequence. */
-            offset = pipeBytes;
+            /* Skip reserved head bytes. */
+            offset = CommandBuffer->reservedHead;
         }
         else
         {
+            gctUINT32 pipeBytes = CommandBuffer->reservedHead;
+
             /* The current hardware and the initial context pipes are
                 different, switch to the correct pipe. */
             gcmkONERROR(gckHARDWARE_PipeSelect(
                 Command->kernel->hardware,
                 commandBufferLogical,
-                commandBufferObject->entryPipe,
+                CommandBuffer->entryPipe,
                 &pipeBytes
                 ));
 
             /* Do not skip pipe switching sequence. */
             offset = 0;
+
+            /* Reserved bytes in userspace must be exact for a pipeSelect. */
+            gcmkASSERT(pipeBytes == CommandBuffer->reservedHead);
         }
 
         /* Generate a LINK from the context buffer to
             the command buffer. */
-        gcmkONERROR(gckHARDWARE_Link(
+        gcmkONERROR(gckWLFE_Link(
             hardware,
             contextBuffer->link3D,
             commandBufferAddress + offset,
@@ -2181,24 +2435,9 @@ gckCOMMAND_Commit(
             &commandLinkHigh
             ));
 
-#if USE_KERNEL_VIRTUAL_BUFFERS
-        if (Command->kernel->virtualCommandBuffer)
-        {
-            gckVIRTUAL_COMMAND_BUFFER_PTR commandBuffer = (gckVIRTUAL_COMMAND_BUFFER_PTR) contextBuffer->physical;
-
-            contextPhysHandle = commandBuffer->virtualBuffer.physical;
-        }
-        else
-#endif
-        {
-            contextPhysHandle = contextBuffer->physical;
-        }
-
-        /* Flush the context buffer cache. */
-        gcmkONERROR(gckOS_CacheClean(
-            Command->os,
-            0,
-            contextPhysHandle,
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            contextBuffer->videoMem,
             entryAddress - contextBuffer->address,
             entryLogical,
             entryBytes
@@ -2207,9 +2446,8 @@ gckCOMMAND_Commit(
         /* Update the current context. */
         Command->currContext = Context;
 
-#if gcdDUMP_COMMAND
+#if gcdDUMP_IN_KERNEL
         contextDumpLogical = entryLogical;
-        contextDumpBytes   = entryBytes;
 #endif
 
 #if gcdSECURITY
@@ -2236,24 +2474,29 @@ gckCOMMAND_Commit(
     else
     {
         /* See if we have to switch pipes for the command buffer. */
-        if (commandBufferObject->entryPipe == Command->pipeSelect)
+        if (CommandBuffer->entryPipe == (gctUINT32)(Command->pipeSelect))
         {
-            /* Skip pipe switching sequence. */
-            offset = pipeBytes;
+            /* Skip reserved head bytes. */
+            offset = CommandBuffer->reservedHead;
         }
         else
         {
+            gctUINT32 pipeBytes = CommandBuffer->reservedHead;
+
             /* The current hardware and the entry command buffer pipes
             ** are different, switch to the correct pipe. */
             gcmkONERROR(gckHARDWARE_PipeSelect(
                 Command->kernel->hardware,
                 commandBufferLogical,
-                commandBufferObject->entryPipe,
+                CommandBuffer->entryPipe,
                 &pipeBytes
                 ));
 
             /* Do not skip pipe switching sequence. */
             offset = 0;
+
+            /* Reserved bytes in userspace must be exact for a pipeSelect. */
+            gcmkASSERT(pipeBytes == CommandBuffer->reservedHead);
         }
 
         /* Compute the entry. */
@@ -2262,23 +2505,14 @@ gckCOMMAND_Commit(
         entryBytes    =                commandBufferSize     - offset;
     }
 
-#if gcdDUMP_COMMAND
-    bufferDumpLogical = commandBufferLogical + offset;
-    bufferDumpBytes   = commandBufferSize    - offset;
-#endif
-
-#if gcdSECURE_USER
-    /* Process user hints. */
-    gcmkONERROR(_ProcessHints(Command, ProcessID, commandBufferObject));
-#endif
+    (void)entryLogical;
 
     /* Determine the location to jump to for the command buffer being
     ** scheduled. */
     if (Command->newQueue)
     {
         /* New command queue, jump to the beginning of it. */
-        exitOffset   = 0;
-        exitLogical  = Command->logical;
+        /* Some extra commands (at beginning) are required for new queue. */
         exitAddress  = Command->address;
         exitBytes    = Command->offset + waitLinkBytes;
     }
@@ -2286,8 +2520,6 @@ gckCOMMAND_Commit(
     {
         /* Still within the preexisting command queue, jump to the new
            WAIT/LINK command sequence. */
-        exitOffset   = offset;
-        exitLogical  = waitLinkLogical;
         exitAddress  = waitLinkAddress;
         exitBytes    = waitLinkBytes;
     }
@@ -2295,7 +2527,7 @@ gckCOMMAND_Commit(
     /* Add a new WAIT/LINK command sequence. When the command buffer which is
        currently being scheduled is fully executed by the GPU, the FE will
        jump to this WAIT/LINK sequence. */
-    gcmkONERROR(gckHARDWARE_WaitLink(
+    gcmkONERROR(gckWLFE_WaitLink(
         hardware,
         waitLinkLogical,
         waitLinkAddress,
@@ -2305,21 +2537,32 @@ gckCOMMAND_Commit(
         &waitSize
         ));
 
-    /* Flush the command queue cache. */
-    gcmkONERROR(gckOS_CacheClean(
-        Command->os,
-        0,
-        Command->physHandle,
-        exitOffset,
-        exitLogical,
-        exitBytes
-        ));
+    if (Command->newQueue)
+    {
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            Command->videoMem,
+            0,
+            Command->logical,
+            exitBytes
+            ));
+    }
+    else
+    {
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            Command->videoMem,
+            Command->offset,
+            waitLinkLogical,
+            exitBytes
+            ));
+    }
 
     /* Determine the location of the TAIL in the command buffer. */
     commandBufferTail
         = commandBufferLogical
         + commandBufferSize
-        - commandBufferObject->reservedTail;
+        - CommandBuffer->reservedTail;
 
     /* Generate command which writes out commit stamp. */
     if (gckHARDWARE_IsFeatureAvailable(hardware, gcvFEATURE_FENCE_64BIT))
@@ -2335,7 +2578,7 @@ gckCOMMAND_Commit(
             &bytes
             ));
 
-        commandBufferTail += gcdRENDER_FENCE_LENGTH;
+        commandBufferTail += bytes;
     }
 
     /* Generate a LINK from the end of the command buffer being scheduled
@@ -2343,7 +2586,7 @@ gckCOMMAND_Commit(
 #if !gcdSECURITY
     if (Shared == gcvFALSE)
     {
-        gcmkONERROR(gckHARDWARE_Link(
+        gcmkONERROR(gckWLFE_Link(
             hardware,
             commandBufferTail,
             exitAddress,
@@ -2355,10 +2598,10 @@ gckCOMMAND_Commit(
     }
     else
     {
-        gctUINT8_PTR link = commandBufferTail + Index * 16;
+        gctUINT8_PTR link = commandBufferTail + CommandBuffer->exitIndex * 16;
         gctSIZE_T bytes = 8;
 
-        gcmkONERROR(gckHARDWARE_ChipEnable(
+        gcmkONERROR(gckWLFE_ChipEnable(
             hardware,
             link,
             (gceCORE_3D_MASK)(1 << hardware->kernel->chipID),
@@ -2367,7 +2610,7 @@ gckCOMMAND_Commit(
 
         link += bytes;
 
-        gcmkONERROR(gckHARDWARE_Link(
+        gcmkONERROR(gckWLFE_Link(
             hardware,
             link,
             exitAddress,
@@ -2381,12 +2624,17 @@ gckCOMMAND_Commit(
     }
 #endif
 
-    /* Flush the command buffer cache. */
-    gcmkONERROR(gckOS_CacheClean(
-        Command->os,
+    gcmkONERROR(gckVIDMEM_HANDLE_Lookup(
+        Command->kernel,
         ProcessID,
-        physHandle,
-        commandBufferObject->startOffset,
+        CommandBuffer->videoMemNode,
+        &commandBufferVideoMem
+        ));
+
+    gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+        Command->kernel,
+        commandBufferVideoMem,
+        CommandBuffer->startOffset,
         commandBufferLogical,
         commandBufferSize
         ));
@@ -2411,23 +2659,40 @@ gckCOMMAND_Commit(
         commandBufferSize    - offset - 8
         );
 #else
+#if gcdNULL_DRIVER
+    /*
+     * Skip link to entryAddress.
+     * Instead, we directly link to final wait link position.
+     */
+    gcmkONERROR(gckWLFE_Link(
+        hardware,
+        Command->waitPos.logical,
+        waitLinkAddress,
+        waitLinkBytes,
+        &Command->waitPos.size,
+        &entryLinkLow,
+        &entryLinkHigh
+        ));
+#  else
     /* Generate a LINK from the previous WAIT/LINK command sequence to the
        entry determined above (either the context or the command buffer).
        This LINK replaces the WAIT instruction from the previous WAIT/LINK
        pair, therefore we use WAIT metrics for generation of this LINK.
        This action will execute the entire sequence. */
-    gcmkONERROR(gckHARDWARE_Link(
+    gcmkONERROR(gckWLFE_Link(
         hardware,
-        Command->waitLogical,
+        Command->waitPos.logical,
         entryAddress,
         entryBytes,
-        &Command->waitSize,
+        &Command->waitPos.size,
         &entryLinkLow,
         &entryLinkHigh
         ));
+#  endif
 #endif
 
 #if gcdLINK_QUEUE_SIZE
+    /* TODO: What's it? */
     if (Command->kernel->stuckDump >= gcvSTUCK_DUMP_USER_COMMAND)
     {
         gcuQUEUEDATA data;
@@ -2464,185 +2729,641 @@ gckCOMMAND_Commit(
     }
 #endif
 
-    /* Flush the cache for the link. */
-    gcmkONERROR(gckOS_CacheClean(
-        Command->os,
-        0,
-        Command->physHandle,
-        Command->offset + waitOffset,
-        Command->waitLogical,
-        Command->waitSize
+    gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+        Command->kernel,
+        Command->waitPos.videoMem,
+        Command->waitPos.offset,
+        Command->waitPos.logical,
+        Command->waitPos.size
         ));
 
-    gcmkDUMPCOMMAND(
+    if (entryAddress != commandBufferAddress + offset)
+    {
+        gcmkDUMP(Command->os, "#[context]");
+        gcmkDUMP_BUFFER(
+            Command->os,
+            gcvDUMP_BUFFER_KERNEL_CONTEXT,
+            contextDumpLogical,
+            entryAddress,
+            entryBytes
+            );
+
+        /* execute context. */
+        gcmkDUMP(Command->os,
+            "@[execute 0 0 0x%08X 0x%08X]",
+            entryAddress + offset,
+            entryBytes - offset - 8
+            );
+    }
+
+    gcmkDUMP(Command->os, "#[command: user]");
+    gcmkDUMP_BUFFER(
         Command->os,
-        Command->waitLogical,
-        Command->waitSize,
-        gcvDUMP_BUFFER_LINK,
-        gcvFALSE
+        gcvDUMP_BUFFER_COMMAND,
+        commandBufferLogical + offset,
+        commandBufferAddress + offset,
+        commandBufferSize - offset
+        );
+
+    /* execute user commands. */
+    gcmkDUMP(
+        Command->os,
+        "@[execute 0 0 0x%08X 0x%08X]",
+        commandBufferAddress
+            + CommandBuffer->reservedHead,
+        commandBufferSize
+            - CommandBuffer->reservedHead
+            - CommandBuffer->reservedTail
         );
 
-    gcmkDUMPCOMMAND(
+    gcmkDUMP(Command->os, "#[wait-link]");
+    gcmkDUMP_BUFFER(
         Command->os,
-        contextDumpLogical,
-        contextDumpBytes,
-        gcvDUMP_BUFFER_CONTEXT,
-        gcvFALSE
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
+        waitLinkLogical,
+        waitLinkAddress,
+        waitLinkBytes
         );
 
-    gcmkDUMPCOMMAND(
+#if gcdNULL_DRIVER
+    gcmkDUMP(
         Command->os,
-        bufferDumpLogical,
-        bufferDumpBytes,
-        gcvDUMP_BUFFER_USER,
-        gcvFALSE
+        "#[null driver: below command skipped link to 0x%08X 0x%08X]",
+        entryAddress,
+        entryBytes
         );
+#endif
 
-    gcmkDUMPCOMMAND(
+    gcmkDUMP(Command->os, "#[link: break prev wait-link]");
+    gcmkDUMP_BUFFER(
         Command->os,
-        waitLinkLogical,
-        waitLinkBytes,
-        gcvDUMP_BUFFER_WAITLINK,
-        gcvFALSE
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
+        Command->waitPos.logical,
+        Command->waitPos.address,
+        Command->waitPos.size
         );
 
     /* Update the current pipe. */
-    Command->pipeSelect = commandBufferObject->exitPipe;
+    Command->pipeSelect = CommandBuffer->exitPipe;
 
     /* Update command queue offset. */
     Command->offset  += waitLinkBytes;
     Command->newQueue = gcvFALSE;
 
     /* Update address of last WAIT. */
-    Command->waitPhysical = waitLinkPhysical + waitOffset;
-    Command->waitLogical  = (gctUINT8_PTR)waitLinkLogical  + waitOffset;
-    Command->waitAddress  = waitLinkAddress  + waitOffset;
-    Command->waitSize     = waitSize;
+    Command->waitPos.videoMem = Command->videoMem;
+    Command->waitPos.offset   = Command->offset - waitLinkBytes + waitOffset;
+    Command->waitPos.logical  = (gctUINT8_PTR)waitLinkLogical  + waitOffset;
+    Command->waitPos.address  = waitLinkAddress  + waitOffset;
+    Command->waitPos.size     = waitSize;
 
     /* Update queue tail pointer. */
     gcmkONERROR(gckHARDWARE_UpdateQueueTail(
         hardware, Command->logical, Command->offset
         ));
 
-#if gcdDUMP_COMMAND
-    gcmkPRINT("@[kernel.commit]");
-#endif
-#endif /* gcdNULL_DRIVER */
-
     /* Release the context switching mutex. */
     gcmkONERROR(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
     contextAcquired = gcvFALSE;
 
-    *CommitStamp = Command->commitStamp;
-    *ContextSwitched = contextSwitched;
+    /* Release the command queue. */
+    gcmkONERROR(gckCOMMAND_ExitCommit(Command, gcvFALSE));
+    commitEntered = gcvFALSE;
 
-    Command->commitStamp++;
+    if (status == gcvSTATUS_INTERRUPTED)
+    {
+        gcmkTRACE(
+            gcvLEVEL_INFO,
+            "%s(%d): Intterupted in gckEVENT_Submit",
+            __FUNCTION__, __LINE__
+            );
+        status = gcvSTATUS_OK;
+    }
+    else
+    {
+        gcmkONERROR(status);
+    }
+
+#ifdef __QNXNTO__
+    if(userCommandBufferLogicalMapped)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+            Command->kernel,
+            commandBufferVideoMem,
+            ProcessID,
+            gcvFALSE
+            ));
+
+        userCommandBufferLogicalMapped =gcvFALSE;
+    }
+#endif
+
+    /* Return status. */
+    gcmkFOOTER();
+    return gcvSTATUS_OK;
+
+OnError:
+    if (contextAcquired)
+    {
+        /* Release the context switching mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
+    }
+
+    if (commitEntered)
+    {
+        /* Release the command queue mutex. */
+        gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Command, gcvFALSE));
+    }
+
+#ifdef __QNXNTO__
+    if (userCommandBufferLogicalMapped)
+    {
+        gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+            Command->os,
+            userCommandBufferLogical,
+            0,
+            commandBufferLogical));
+    }
+#endif
+
+    /* Return status. */
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_CommitAsyncOnce(
+    IN gckCOMMAND Command,
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer
+    )
+{
+    gceSTATUS       status;
+    gckHARDWARE     hardware = Command->kernel->hardware;
+    gctBOOL         available = gcvFALSE;
+    gctBOOL         acquired = gcvFALSE;
+    gctUINT8_PTR    commandBufferLogical;
+    gctUINT8_PTR    commandBufferTail;
+    gctUINT         commandBufferSize;
+    gctUINT32       commandBufferAddress;
+    gctUINT32       fenceBytes;
+    gctUINT32       oldValue;
+    gctUINT32       flushBytes;
+    gcsPATCH_LIST_VARIABLE patchListVar = {0, 0};
+
+    gcmkHEADER();
+
+    gcmkVERIFY_OK(
+        _HandlePatchList(Command, CommandBuffer, &patchListVar));
+
+    gckOS_AtomicExchange(Command->os,
+                         hardware->pageTableDirty[gcvENGINE_BLT],
+                         0,
+                         &oldValue);
+
+    if (oldValue)
+    {
+        gckHARDWARE_FlushAsyncMMU(hardware, gcvNULL, &flushBytes);
+
+        gcmkASSERT(flushBytes <= CommandBuffer->reservedHead);
+
+        /* Compute the command buffer entry to insert the flushMMU commands. */
+        commandBufferLogical = (gctUINT8_PTR)gcmUINT64_TO_PTR(CommandBuffer->logical)
+                             + CommandBuffer->startOffset
+                             + CommandBuffer->reservedHead
+                             - flushBytes;
+
+        commandBufferAddress = CommandBuffer->address
+                             + CommandBuffer->startOffset
+                             + CommandBuffer->reservedHead
+                             - flushBytes;
+
+        gckHARDWARE_FlushAsyncMMU(hardware, commandBufferLogical, &flushBytes);
+    }
+    else
+    {
+        /* Compute the command buffer entry. */
+        commandBufferLogical = (gctUINT8_PTR)gcmUINT64_TO_PTR(CommandBuffer->logical)
+                             + CommandBuffer->startOffset
+                             + CommandBuffer->reservedHead;
+
+        commandBufferAddress = CommandBuffer->address
+                             + CommandBuffer->startOffset
+                             + CommandBuffer->reservedHead;
+
+        flushBytes = 0;
+    }
+
+    commandBufferTail = (gctUINT8_PTR)gcmUINT64_TO_PTR(CommandBuffer->logical)
+                      + CommandBuffer->startOffset
+                      + CommandBuffer->size
+                      - CommandBuffer->reservedTail;
+
+    gcmkONERROR(gckHARDWARE_Fence(
+        hardware,
+        gcvENGINE_BLT,
+        commandBufferTail,
+        Command->fence->address,
+        Command->commitStamp,
+        &fenceBytes
+        ));
+
+    gcmkASSERT(fenceBytes <= CommandBuffer->reservedTail);
+
+    commandBufferSize = CommandBuffer->size
+                      - CommandBuffer->reservedHead
+                      - CommandBuffer->reservedTail
+                      + flushBytes
+                      + fenceBytes;
+
+    gckOS_AcquireMutex(Command->os, Command->mutexContext, gcvINFINITE);
+    acquired = gcvTRUE;
+
+    /* Acquire a slot. */
+    for (;;)
+    {
+        gcmkONERROR(gckASYNC_FE_ReserveSlot(hardware, &available));
+
+        if (available)
+        {
+            break;
+        }
+        else
+        {
+            gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "No available slot, have to wait");
+
+            gckOS_Delay(Command->os, 1);
+        }
+    }
+
+#if gcdNULL_DRIVER
+    /* Skip submit to hardware for NULL driver. */
+    gcmkDUMP(Command->os, "#[null driver: below command is skipped]");
+#endif
+
+    gcmkDUMP(Command->os, "#[async-command: user]");
+    gcmkDUMP_BUFFER(
+        Command->os,
+        gcvDUMP_BUFFER_ASYNC_COMMAND,
+        commandBufferLogical,
+        commandBufferAddress,
+        commandBufferSize
+        );
+
+    gcmkDUMP(
+        Command->os,
+        "@[execute 1 0 0x%08X 0x%08X]",
+        commandBufferAddress
+            + CommandBuffer->reservedHead,
+        CommandBuffer->size
+            - CommandBuffer->reservedHead
+            - CommandBuffer->reservedTail
+        );
+
+#if !gcdNULL_DRIVER
+    /* Execute command buffer. */
+    gckASYNC_FE_Execute(hardware, commandBufferAddress, commandBufferSize);
+#endif
+
+    gckOS_ReleaseMutex(Command->os, Command->mutexContext);
+    acquired = gcvFALSE;
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    if (acquired)
+    {
+        gckOS_ReleaseMutex(Command->os, Command->mutexContext);
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_CommitMultiChannelOnce(
+    IN gckCOMMAND Command,
+    IN gcsHAL_COMMAND_LOCATION * CommandBuffer
+    )
+{
+    gceSTATUS    status;
+    gctBOOL      acquired = gcvFALSE;
+    gctUINT8_PTR commandBufferLogical;
+    gctUINT      commandBufferSize;
+    gctUINT32    commandBufferAddress;
+    gckHARDWARE  hardware;
+    gctUINT64    bit;
+    gcsPATCH_LIST_VARIABLE patchListVar = {0, 0};
+
+    gcmkHEADER_ARG("priority=%d channelId=%d videoMemNode=%u size=0x%x patchHead=%p",
+                   CommandBuffer->priority, CommandBuffer->channelId,
+                   CommandBuffer->videoMemNode, CommandBuffer->size,
+                   gcmUINT64_TO_PTR(CommandBuffer->patchHead));
+
+    gcmkASSERT(Command->feType == gcvHW_FE_MULTI_CHANNEL);
+
+    hardware = Command->kernel->hardware;
+
+    gcmkVERIFY_OK(
+        _HandlePatchList(Command, CommandBuffer, &patchListVar));
+
+    /* Check flush mcfe MMU cache. */
+    gcmkONERROR(_CheckFlushMcfeMMU(Command, hardware));
+
+    /* Compute the command buffer entry and the size. */
+    commandBufferLogical
+        = (gctUINT8_PTR) gcmUINT64_TO_PTR(CommandBuffer->logical)
+        +                CommandBuffer->startOffset
+        +                CommandBuffer->reservedHead;
+
+    commandBufferAddress = CommandBuffer->address
+                         + CommandBuffer->startOffset
+                         + CommandBuffer->reservedHead;
+
+    /* reservedTail bytes are not used, because fence not enable. */
+    commandBufferSize
+        = CommandBuffer->size
+        - CommandBuffer->reservedHead
+        - CommandBuffer->reservedTail;
+
+    if (commandBufferSize & 8)
+    {
+        /*
+         * Need 16 byte alignment for MCFE command size.
+         * command is already 8 byte aligned, if not 16 byte aligned,
+         * we need append 8 bytes.
+         */
+        gctUINT32 nop[2];
+        gctSIZE_T bytes = 8;
+        gctUINT8_PTR tail = commandBufferLogical + commandBufferSize;
+
+        gckMCFE_Nop(hardware, nop, &bytes);
+        gcmkASSERT(bytes == 8);
+
+        gckOS_WriteMemory(Command->os, tail, nop[0]);
+        gckOS_WriteMemory(Command->os, tail + 4, nop[1]);
+
+        commandBufferSize += 8;
+    }
+
+    /* Large command buffer size does not make sense. */
+    gcmkASSERT(commandBufferSize < 0x800000);
+
+
+    if (CommandBuffer->channelId != 0)
+    {
+        /* Sync from the system channel. */
+        gcmkONERROR(_SyncFromSystemChannel(
+            Command,
+            (gctBOOL)CommandBuffer->priority,
+            (gctUINT32)CommandBuffer->channelId
+            ));
+    }
+
+    gckOS_AcquireMutex(Command->os, Command->mutexQueue, gcvINFINITE);
+    acquired = gcvTRUE;
+
+#if gcdNULL_DRIVER
+    /* Skip submit to hardware for NULL driver. */
+    gcmkDUMP(Command->os, "#[null driver: below command is skipped]");
+#endif
+
+    gcmkDUMP(Command->os, "#[mcfe-command: user]");
+    gcmkDUMP_BUFFER(
+        Command->os,
+        gcvDUMP_BUFFER_COMMAND,
+        commandBufferLogical,
+        commandBufferAddress,
+        commandBufferSize
+        );
+
+    gcmkDUMP(Command->os,
+             "@[execute %d %d 0x%08X 0x%08X]",
+             CommandBuffer->channelId,
+             CommandBuffer->priority,
+             commandBufferAddress,
+             commandBufferSize);
+
+#if !gcdNULL_DRIVER
+    /* Execute command buffer. */
+    gcmkONERROR(gckMCFE_Execute(
+        hardware,
+        (gctBOOL)CommandBuffer->priority,
+        (gctUINT32)CommandBuffer->channelId,
+        commandBufferAddress,
+        commandBufferSize
+        ));
+#endif
+
+    bit = 1ull << CommandBuffer->channelId;
+
+    /* This channel is dirty. */
+    Command->dirtyChannel[CommandBuffer->priority ? 1 : 0] |= bit;
+
+    gckOS_ReleaseMutex(Command->os, Command->mutexQueue);
+    acquired = gcvFALSE;
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    if (acquired)
+    {
+        gckOS_ReleaseMutex(Command->os, Command->mutexQueue);
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+
+/*******************************************************************************
+**
+**  gckCOMMAND_Commit
+**
+**  Commit command buffers to the command queue.
+**
+**  INPUT:
+**
+**      gckCOMMAND Command
+**          Pointer to a gckCOMMAND object.
+**
+**      gcsHAL_SUBCOMMIT * SubCommit
+**          Commit information, includes context, delta, and command buffer
+*           locations.
+**
+**      gctUINT32 ProcessID
+**          Current process ID.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Commit(
+    IN gckCOMMAND Command,
+    IN gcsHAL_SUBCOMMIT * SubCommit,
+    IN gctUINT32 ProcessId,
+    IN gctBOOL Shared,
+    OUT gctUINT64_PTR CommitStamp
+    )
+{
+    gceSTATUS status;
+    gcsSTATE_DELTA_PTR delta = gcmUINT64_TO_PTR(SubCommit->delta);
+    gckCONTEXT context = gcvNULL;
+    gcsHAL_COMMAND_LOCATION *cmdLoc = &SubCommit->commandBuffer;
+    gcsHAL_COMMAND_LOCATION _cmdLoc;
+    gctPOINTER userPtr = gcvNULL;
+    gctBOOL needCopy = gcvFALSE;
+
+    gcmkHEADER_ARG("Command=%p SubCommit=%p delta=%p context=%u pid=%u",
+                   Command, SubCommit, delta, SubCommit->context, ProcessId);
+
+    gcmkVERIFY_OK(gckOS_QueryNeedCopy(Command->os, ProcessId, &needCopy));
+
+    if (SubCommit->context)
+    {
+        context = gckKERNEL_QueryPointerFromName(
+            Command->kernel,
+            (gctUINT32)(SubCommit->context)
+            );
+    }
+
+    do
+    {
+        gctUINT64 next;
+
+        /* Skip the first nested one. */
+        if (userPtr)
+        {
+            /* Copy/map command buffer location from user. */
+            if (needCopy)
+            {
+                cmdLoc = &_cmdLoc;
+
+                status = gckOS_CopyFromUserData(
+                    Command->os,
+                    cmdLoc,
+                    userPtr,
+                    gcmSIZEOF(gcsHAL_COMMAND_LOCATION)
+                    );
+            }
+            else
+            {
+                status = gckOS_MapUserPointer(
+                    Command->os,
+                    userPtr,
+                    gcmSIZEOF(gcsHAL_COMMAND_LOCATION),
+                    (gctPOINTER *)&cmdLoc
+                    );
+            }
+
+            if (gcmIS_ERROR(status))
+            {
+                userPtr = gcvNULL;
+
+                gcmkONERROR(status);
+            }
+        }
+
+        if (Command->feType == gcvHW_FE_WAIT_LINK)
+        {
+            /* Commit command buffers. */
+            status = _CommitWaitLinkOnce(Command,
+                                         context,
+                                         cmdLoc,
+                                         delta,
+                                         ProcessId,
+                                         Shared);
+        }
+        else if (Command->feType == gcvHW_FE_MULTI_CHANNEL)
+        {
+            status = _CommitMultiChannelOnce(Command, cmdLoc);
+        }
+        else
+        {
+            gcmkASSERT(Command->feType == gcvHW_FE_ASYNC);
 
-    stall = gcvFALSE;
+            status = _CommitAsyncOnce(Command, cmdLoc);
+        }
 
-#if gcdLINK_QUEUE_SIZE
-    if (Command->kernel->stuckDump == gcvSTUCK_DUMP_STALL_COMMAND)
-    {
-        if ((Command->commitStamp % (gcdLINK_QUEUE_SIZE/2)) == 0)
+        if (status != gcvSTATUS_INTERRUPTED)
         {
-            /* If only context buffer and command buffer is recorded,
-            ** each commit costs 2 slot in queue, to make sure command
-            ** causing stuck is recorded, number of pending command buffer
-            ** is limited to (gckLINK_QUEUE_SIZE/2)
-            */
-            stall = gcvTRUE;
+            gcmkONERROR(status);
         }
-    }
-#endif
 
-    /* Release the command queue. */
-    gcmkONERROR(gckCOMMAND_ExitCommit(Command, gcvFALSE));
-    commitEntered = gcvFALSE;
+        /* Do not need context or delta for later commands. */
+        context = gcvNULL;
+        delta   = gcvNULL;
 
-    if (status == gcvSTATUS_INTERRUPTED)
-    {
-        gcmkTRACE(
-            gcvLEVEL_INFO,
-            "%s(%d): Intterupted in gckEVENT_Submit",
-            __FUNCTION__, __LINE__
-            );
-        status = gcvSTATUS_OK;
-    }
-    else
-    {
-        gcmkONERROR(status);
-    }
+        next    = cmdLoc->next;
 
-#ifdef __QNXNTO__
-    if (userCommandBufferLogicalMapped)
-    {
-        gcmkONERROR(gckOS_UnmapUserPointer(
-            Command->os,
-            userCommandBufferLogical,
-            0,
-            commandBufferLogical));
+        /* Unmap user pointer if mapped. */
+        if (!needCopy && userPtr)
+        {
+            gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+                Command->os,
+                userPtr,
+                gcmSIZEOF(gcsHAL_COMMAND_LOCATION),
+                cmdLoc
+                ));
+        }
 
-        userCommandBufferLogicalMapped = gcvFALSE;
+        /* Advance to next command buffer location from user. */
+        userPtr = gcmUINT64_TO_PTR(next);
     }
-#endif
+    while (userPtr);
 
-    /* Unmap the command buffer pointer. */
-    if (commandBufferMapped)
+    if (Command->feType == gcvHW_FE_MULTI_CHANNEL)
     {
-        gcmkONERROR(gckOS_UnmapUserPointer(
-            Command->os,
-            CommandBuffer,
-            gcmSIZEOF(struct _gcoCMDBUF),
-            commandBufferObject
-            ));
-
-        commandBufferMapped = gcvFALSE;
+        /*
+         * Semphore synchronization.
+         *
+         * Here we blindly sync dirty other channels to the system channel.
+         * The scenario to sync channels to the system channel:
+         * 1. Need to sync channels who sent semaphores.
+         * 2. Need to sync dirty channels when event(interrupt) is to sent.
+         * 3. Need to sync dirty channels when system channel need run something
+         *    such as flush mmu.
+         *
+         * When power management is on, blindly sync dirty channels is OK because
+         * there's always a event(intrrupt).
+         *
+         * The only condition we sync more than needed is:
+         * a. power manangement is off.
+         * b. no user event is attached when commit.
+         * c. no user event is to be submitted in next ioctl.
+         * That's a rare condition.
+         *
+         * Conclusion is that, blindly sync dirty channels is a good choice for
+         * now.
+         */
+        gcmkONERROR(_SyncToSystemChannel(Command, Command->dirtyChannel));
     }
 
-    /* Return status. */
-    gcmkFOOTER();
+    /* Output commit stamp. */
+    *CommitStamp = Command->commitStamp;
+    Command->commitStamp++;
+
+    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if (contextAcquired)
-    {
-        /* Release the context switching mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(Command->os, Command->mutexContext));
-    }
-
-    if (commitEntered)
-    {
-        /* Release the command queue mutex. */
-        gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Command, gcvFALSE));
-    }
-
-#ifdef __QNXNTO__
-    if (userCommandBufferLogicalMapped)
-    {
-        gcmkVERIFY_OK(gckOS_UnmapUserPointer(
-            Command->os,
-            userCommandBufferLogical,
-            0,
-            commandBufferLogical));
-    }
-#endif
-
-    /* Unmap the command buffer pointer. */
-    if (commandBufferMapped)
+    if (!needCopy && userPtr)
     {
-        gcmkVERIFY_OK(gckOS_UnmapUserPointer(
+        gckOS_UnmapUserPointer(
             Command->os,
-            CommandBuffer,
-            gcmSIZEOF(struct _gcoCMDBUF),
-            commandBufferObject
-            ));
+            userPtr,
+            gcmSIZEOF(gcsHAL_COMMAND_LOCATION),
+            cmdLoc
+            );
     }
 
-    /* Return status. */
     gcmkFOOTER();
     return status;
 }
 
+
 /*******************************************************************************
 **
 **  gckCOMMAND_Reserve
@@ -2680,29 +3401,36 @@ gckCOMMAND_Reserve(
     gctUINT32 requiredBytes;
     gctUINT32 requestedAligned;
 
-    gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
+    gcmkHEADER_ARG("Command=%p RequestedBytes=%lu", Command, RequestedBytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
 
-    /* Compute aligned number of reuested bytes. */
-    requestedAligned = gcmALIGN(RequestedBytes, Command->alignment);
+    if (Command->feType == gcvHW_FE_WAIT_LINK)
+    {
+        /* Compute aligned number of reuested bytes. */
+        requestedAligned = gcmALIGN(RequestedBytes, Command->alignment);
 
-    /* Another WAIT/LINK command sequence will have to be appended after
-       the requested area being reserved. Compute the number of bytes
-       required for WAIT/LINK at the location after the reserved area. */
-    gcmkONERROR(gckHARDWARE_WaitLink(
-        Command->kernel->hardware,
-        gcvNULL,
-        ~0U,
-        Command->offset + requestedAligned,
-        &requiredBytes,
-        gcvNULL,
-        gcvNULL
-        ));
+        /* Another WAIT/LINK command sequence will have to be appended after
+           the requested area being reserved. Compute the number of bytes
+           required for WAIT/LINK at the location after the reserved area. */
+        gcmkONERROR(gckWLFE_WaitLink(
+            Command->kernel->hardware,
+            gcvNULL,
+            ~0U,
+            Command->offset + requestedAligned,
+            &requiredBytes,
+            gcvNULL,
+            gcvNULL
+            ));
 
-    /* Compute total number of bytes required. */
-    requiredBytes += requestedAligned;
+        /* Compute total number of bytes required. */
+        requiredBytes += requestedAligned;
+    }
+    else
+    {
+        requiredBytes = gcmALIGN(RequestedBytes, 8);
+    }
 
     /* Compute number of bytes available in command queue. */
     bytes = Command->pageSize - Command->offset;
@@ -2768,26 +3496,21 @@ gckCOMMAND_Execute(
 {
     gceSTATUS status;
 
-    gctUINT32 waitLinkPhysical;
     gctUINT8_PTR waitLinkLogical;
     gctUINT32 waitLinkAddress;
     gctUINT32 waitLinkOffset;
     gctUINT32 waitLinkBytes;
 
-    gctUINT32 waitPhysical;
-    gctPOINTER waitLogical;
-    gctUINT32 waitAddress;
     gctUINT32 waitOffset;
     gctUINT32 waitBytes;
 
     gctUINT32 linkLow, linkHigh;
 
-    gctUINT32 execOffset;
     gctPOINTER execLogical;
     gctUINT32 execAddress;
     gctUINT32 execBytes;
 
-    gcmkHEADER_ARG("Command=0x%x RequestedBytes=%lu", Command, RequestedBytes);
+    gcmkHEADER_ARG("Command=%p RequestedBytes=%lu", Command, RequestedBytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
@@ -2799,12 +3522,11 @@ gckCOMMAND_Execute(
     waitLinkBytes = Command->pageSize - waitLinkOffset;
 
     /* Compute the location if WAIT/LINK command sequence. */
-    waitLinkPhysical =                Command->physical + waitLinkOffset;
     waitLinkLogical  = (gctUINT8_PTR) Command->logical  + waitLinkOffset;
     waitLinkAddress  =                Command->address  + waitLinkOffset;
 
     /* Append WAIT/LINK in command queue. */
-    gcmkONERROR(gckHARDWARE_WaitLink(
+    gcmkONERROR(gckWLFE_WaitLink(
         Command->kernel->hardware,
         waitLinkLogical,
         waitLinkAddress,
@@ -2814,60 +3536,74 @@ gckCOMMAND_Execute(
         &waitBytes
         ));
 
-    /* Compute the location if WAIT command. */
-    waitPhysical = waitLinkPhysical + waitOffset;
-    waitLogical  = waitLinkLogical  + waitOffset;
-    waitAddress  = waitLinkAddress  + waitOffset;
 
     /* Determine the location to jump to for the command buffer being
     ** scheduled. */
     if (Command->newQueue)
     {
         /* New command queue, jump to the beginning of it. */
-        execOffset   = 0;
         execLogical  = Command->logical;
         execAddress  = Command->address;
-        execBytes    = waitLinkOffset + waitLinkBytes;
+        execBytes    = Command->offset + RequestedBytes + waitLinkBytes;
+
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            Command->videoMem,
+            0,
+            execLogical,
+            execBytes
+            ));
     }
     else
     {
         /* Still within the preexisting command queue, jump directly to the
            reserved area. */
-        execOffset   = Command->offset;
         execLogical  = (gctUINT8 *) Command->logical  + Command->offset;
         execAddress  =              Command->address  + Command->offset;
         execBytes    = RequestedBytes + waitLinkBytes;
+
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            Command->videoMem,
+            Command->offset,
+            execLogical,
+            execBytes
+            ));
     }
 
-    /* Flush the cache. */
-    gcmkONERROR(gckOS_CacheClean(
-        Command->os,
-        0,
-        Command->physHandle,
-        execOffset,
-        execLogical,
-        execBytes
+#if gcdNULL_DRIVER
+    /*
+     * Skip link to execAddress.
+     * Instead, we directly link to final wait link position.
+     */
+    gcmkONERROR(gckWLFE_Link(
+        Command->kernel->hardware,
+        Command->waitPos.logical,
+        waitLinkAddress,
+        waitLinkBytes,
+        &Command->waitPos.size,
+        &linkLow,
+        &linkHigh
         ));
-
+#else
     /* Convert the last WAIT into a LINK. */
-    gcmkONERROR(gckHARDWARE_Link(
+    gcmkONERROR(gckWLFE_Link(
         Command->kernel->hardware,
-        Command->waitLogical,
+        Command->waitPos.logical,
         execAddress,
         execBytes,
-        &Command->waitSize,
+        &Command->waitPos.size,
         &linkLow,
         &linkHigh
         ));
+#endif
 
-    /* Flush the cache. */
-    gcmkONERROR(gckOS_CacheClean(
-        Command->os,
-        0,
-        Command->physHandle,
-        waitLinkOffset + waitOffset,
-        Command->waitLogical,
-        Command->waitSize
+    gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+        Command->kernel,
+        Command->waitPos.videoMem,
+        Command->waitPos.offset,
+        Command->waitPos.logical,
+        Command->waitPos.size
         ));
 
 #if gcdLINK_QUEUE_SIZE
@@ -2884,50 +3620,251 @@ gckCOMMAND_Execute(
 
         gckQUEUE_Enqueue(&Command->kernel->hardware->linkQueue, &data);
     }
-#endif
+#endif
+
+    gcmkDUMP(Command->os, "#[command: kernel execute]");
+    gcmkDUMP_BUFFER(
+        Command->os,
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
+        execLogical,
+        execAddress,
+        execBytes
+        );
+
+#if gcdNULL_DRIVER
+    gcmkDUMP(Command->os,
+             "#[null driver: below command skipped link to 0x%08X 0x%08X]",
+             execAddress,
+             execBytes);
+#endif
+
+    gcmkDUMP(Command->os, "#[link: break prev wait-link]");
+    gcmkDUMP_BUFFER(
+        Command->os,
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
+        Command->waitPos.logical,
+        Command->waitPos.address,
+        Command->waitPos.size
+        );
+
+    /* Update the pointer to the last WAIT. */
+    Command->waitPos.videoMem = Command->videoMem;
+    Command->waitPos.offset  = waitLinkOffset + waitOffset;
+    Command->waitPos.logical = (gctUINT8_PTR)waitLinkLogical  + waitOffset;
+    Command->waitPos.address = waitLinkAddress  + waitOffset;
+    Command->waitPos.size    = waitBytes;
+
+    /* Update the command queue. */
+    Command->offset  += RequestedBytes + waitLinkBytes;
+    Command->newQueue = gcvFALSE;
+
+    /* Update queue tail pointer. */
+    gcmkONERROR(gckHARDWARE_UpdateQueueTail(
+        Command->kernel->hardware, Command->logical, Command->offset
+        ));
+
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckCOMMAND_ExecuteAsync(
+    IN gckCOMMAND Command,
+    IN gctUINT32 RequestedBytes
+    )
+{
+    gceSTATUS status;
+    gckHARDWARE hardware;
+    gctBOOL available;
+    gctPOINTER execLogical;
+    gctUINT32 execAddress;
+    gctUINT32 execBytes;
+
+    hardware = Command->kernel->hardware;
+
+    /* Determine the location to jump to for the command buffer being
+    ** scheduled. */
+    if (Command->newQueue)
+    {
+        /* New command queue, jump to the beginning of it. */
+        execLogical  = Command->logical;
+        execAddress  = Command->address;
+        execBytes    = Command->offset + RequestedBytes;
+
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            Command->videoMem,
+            0,
+            execLogical,
+            execBytes
+            ));
+    }
+    else
+    {
+        /* Still within the preexisting command queue, jump directly to the
+           reserved area. */
+        execLogical  = (gctUINT8 *) Command->logical  + Command->offset;
+        execAddress  =              Command->address  + Command->offset;
+        execBytes    = RequestedBytes;
+
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            Command->videoMem,
+            Command->offset,
+            execLogical,
+            execBytes
+            ));
+    }
+
+    /* Acquire a slot. */
+    for (;;)
+    {
+        gcmkONERROR(gckASYNC_FE_ReserveSlot(hardware, &available));
+
+        if (available)
+        {
+            break;
+        }
+        else
+        {
+            gckOS_Delay(Command->os, 1);
+        }
+    }
+
+#if gcdNULL_DRIVER
+    /* Skip submit to hardware for NULL driver. */
+    gcmkDUMP(Command->os, "#[null driver: below command is skipped]");
+#endif
+
+    gcmkDUMP(Command->os, "#[async-command: kernel execute]");
+    gcmkDUMP_BUFFER(
+        Command->os,
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
+        execLogical,
+        execAddress,
+        execBytes
+        );
+
+#if !gcdNULL_DRIVER
+    /* Send descriptor. */
+    gckASYNC_FE_Execute(hardware, execAddress, execBytes);
+#endif
+
+    /* Update the command queue. */
+    Command->offset   += RequestedBytes;
+    Command->newQueue  = gcvFALSE;
+
+    return gcvSTATUS_OK;
+
+OnError:
+    return status;
+}
+
+gceSTATUS
+gckCOMMAND_ExecuteMultiChannel(
+    IN gckCOMMAND Command,
+    IN gctBOOL Priority,
+    IN gctUINT32 ChannelId,
+    IN gctUINT32 RequestedBytes
+    )
+{
+    gceSTATUS status;
+    gctPOINTER execLogical;
+    gctUINT32 execAddress;
+    gctUINT32 execBytes;
+
+    /* Determine the location to jump to for the command buffer being
+    ** scheduled. */
+    if (Command->newQueue)
+    {
+        /* New command queue, jump to the beginning of it. */
+        execLogical  = Command->logical;
+        execAddress  = Command->address;
+        execBytes    = Command->offset + RequestedBytes;
+    }
+    else
+    {
+        /* Still within the preexisting command queue, jump directly to the
+           reserved area. */
+        execLogical  = (gctUINT8 *) Command->logical  + Command->offset;
+        execAddress  =              Command->address  + Command->offset;
+        execBytes    = RequestedBytes;
+    }
+
+    if (execBytes & 8)
+    {
+        gctSIZE_T bytes = 8;
+        gctUINT8_PTR tail = (gctUINT8_PTR)execLogical + execBytes;
+
+        gckMCFE_Nop(Command->kernel->hardware, tail, &bytes);
+        gcmkASSERT(bytes == 8);
+
+        execBytes += 8;
+        RequestedBytes += 8;
+    }
+
+    if (Command->newQueue)
+    {
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            Command->videoMem,
+            0,
+            execLogical,
+            execBytes
+            ));
+    }
+    else
+    {
+        gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+            Command->kernel,
+            Command->videoMem,
+            Command->offset,
+            execLogical,
+            execBytes
+            ));
+    }
 
-    gcmkDUMPCOMMAND(
-        Command->os,
-        Command->waitLogical,
-        Command->waitSize,
-        gcvDUMP_BUFFER_LINK,
-        gcvFALSE
-        );
+#if gcdNULL_DRIVER
+    /* Skip submit to hardware for NULL driver. */
+    gcmkDUMP(Command->os, "#[null driver: below command is skipped]");
+#endif
 
-    gcmkDUMPCOMMAND(
+    gcmkDUMP(Command->os, "#[mcfe-command: kernel execute]");
+    gcmkDUMP_BUFFER(
         Command->os,
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
         execLogical,
-        execBytes,
-        gcvDUMP_BUFFER_KERNEL,
-        gcvFALSE
+        execAddress,
+        execBytes
         );
 
-    /* Update the pointer to the last WAIT. */
-    Command->waitPhysical = waitPhysical;
-    Command->waitLogical  = waitLogical;
-    Command->waitAddress  = waitAddress;
-    Command->waitSize     = waitBytes;
-
-    /* Update the command queue. */
-    Command->offset  += RequestedBytes + waitLinkBytes;
-    Command->newQueue = gcvFALSE;
-
-    /* Update queue tail pointer. */
-    gcmkONERROR(gckHARDWARE_UpdateQueueTail(
-        Command->kernel->hardware, Command->logical, Command->offset
-        ));
+    gcmkDUMP(Command->os,
+             "@[execute %u %u 0x%08X 0x%08X]",
+             ChannelId, Priority, execAddress, execBytes);
 
-#if gcdDUMP_COMMAND
-    gcmkPRINT("@[kernel.execute]");
+#if !gcdNULL_DRIVER
+    /* Send descriptor. */
+    gcmkONERROR(
+        gckMCFE_Execute(Command->kernel->hardware,
+                        Priority,
+                        ChannelId,
+                        execAddress,
+                        execBytes));
 #endif
 
-    /* Success. */
-    gcmkFOOTER_NO();
+    /* Update the command queue. */
+    Command->offset   += RequestedBytes;
+    Command->newQueue  = gcvFALSE;
+
     return gcvSTATUS_OK;
 
 OnError:
-    /* Return the status. */
-    gcmkFOOTER();
     return status;
 }
 
@@ -2957,10 +3894,6 @@ gckCOMMAND_Stall(
     IN gctBOOL FromPower
     )
 {
-#if gcdNULL_DRIVER
-    /* Do nothing with infinite hardware. */
-    return gcvSTATUS_OK;
-#else
     gckOS os;
     gckHARDWARE hardware;
     gckEVENT eventObject;
@@ -2968,7 +3901,7 @@ gckCOMMAND_Stall(
     gctSIGNAL signal = gcvNULL;
     gctUINT timer = 0;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
@@ -2994,9 +3927,7 @@ gckCOMMAND_Stall(
     /* Submit the event queue. */
     gcmkONERROR(gckEVENT_Submit(eventObject, gcvTRUE, FromPower));
 
-#if gcdDUMP_COMMAND
-    gcmkPRINT("@[kernel.stall]");
-#endif
+    gcmkDUMP(Command->os, "#[kernel.stall]");
 
     if (status == gcvSTATUS_CHIP_NOT_READY)
     {
@@ -3065,36 +3996,11 @@ OnError:
     /* Return the status. */
     gcmkFOOTER();
     return status;
-#endif
 }
 
-/*******************************************************************************
-**
-**  gckCOMMAND_Attach
-**
-**  Attach user process.
-**
-**  INPUT:
-**
-**      gckCOMMAND Command
-**          Pointer to a gckCOMMAND object.
-**
-**      gctUINT32 ProcessID
-**          Current process ID.
-**
-**  OUTPUT:
-**
-**      gckCONTEXT * Context
-**          Pointer to a variable that will receive a pointer to a new
-**          gckCONTEXT object.
-**
-**      gctSIZE_T * StateCount
-**          Pointer to a variable that will receive the number of states
-**          in the context buffer.
-*/
 #if (gcdENABLE_3D || gcdENABLE_2D)
-gceSTATUS
-gckCOMMAND_Attach(
+static gceSTATUS
+_AttachWaitLinkFECommand(
     IN gckCOMMAND Command,
     OUT gckCONTEXT * Context,
     OUT gctSIZE_T * MaxState,
@@ -3105,7 +4011,7 @@ gckCOMMAND_Attach(
     gceSTATUS status;
     gctBOOL acquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
@@ -3149,28 +4055,62 @@ OnError:
     gcmkFOOTER();
     return status;
 }
-#endif
 
 /*******************************************************************************
 **
-**  gckCOMMAND_Detach
+**  gckCOMMAND_Attach
 **
-**  Detach user process.
+**  Attach user process.
 **
 **  INPUT:
 **
 **      gckCOMMAND Command
 **          Pointer to a gckCOMMAND object.
 **
-**      gckCONTEXT Context
-**          Pointer to a gckCONTEXT object to be destroyed.
+**      gctUINT32 ProcessID
+**          Current process ID.
 **
 **  OUTPUT:
 **
-**      Nothing.
+**      gckCONTEXT * Context
+**          Pointer to a variable that will receive a pointer to a new
+**          gckCONTEXT object.
+**
+**      gctSIZE_T * StateCount
+**          Pointer to a variable that will receive the number of states
+**          in the context buffer.
 */
 gceSTATUS
-gckCOMMAND_Detach(
+gckCOMMAND_Attach(
+    IN gckCOMMAND Command,
+    OUT gckCONTEXT * Context,
+    OUT gctSIZE_T * MaxState,
+    OUT gctUINT32 * NumStates,
+    IN gctUINT32 ProcessID
+    )
+{
+    if (Command->feType == gcvHW_FE_WAIT_LINK)
+    {
+        return _AttachWaitLinkFECommand(Command,
+                                        Context,
+                                        MaxState,
+                                        NumStates,
+                                        ProcessID);
+    }
+    else
+    {
+        /* Nothing to do. */
+        *Context   = gcvNULL;
+        *MaxState  = 0;
+        *NumStates = 0;
+
+        return gcvSTATUS_OK;
+    }
+}
+#endif
+
+static gceSTATUS
+_DetachWaitLinkFECommand(
     IN gckCOMMAND Command,
     IN gckCONTEXT Context
     )
@@ -3178,7 +4118,7 @@ gckCOMMAND_Detach(
     gceSTATUS status;
     gctBOOL acquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Command=0x%x Context=0x%x", Command, Context);
+    gcmkHEADER_ARG("Command=%p Context=%p", Command, Context);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
@@ -3220,6 +4160,97 @@ OnError:
     return status;
 }
 
+/*******************************************************************************
+**
+**  gckCOMMAND_Detach
+**
+**  Detach user process.
+**
+**  INPUT:
+**
+**      gckCOMMAND Command
+**          Pointer to a gckCOMMAND object.
+**
+**      gckCONTEXT Context
+**          Pointer to a gckCONTEXT object to be destroyed.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gckCOMMAND_Detach(
+    IN gckCOMMAND Command,
+    IN gckCONTEXT Context
+    )
+{
+    if (Command->feType == gcvHW_FE_WAIT_LINK)
+    {
+        return _DetachWaitLinkFECommand(Command, Context);
+    }
+    else
+    {
+        /* Nothing to do. */
+        return gcvSTATUS_OK;
+    }
+}
+
+static void
+_DumpBuffer(
+    IN gctPOINTER Buffer,
+    IN gctUINT32 GpuAddress,
+    IN gctSIZE_T Size
+    )
+{
+    gctSIZE_T i, line, left;
+    gctUINT32_PTR data = Buffer;
+
+    line = Size / 32;
+    left = Size % 32;
+
+    for (i = 0; i < line; i++)
+    {
+        gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X %08X %08X",
+                  GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
+        data += 8;
+        GpuAddress += 8 * 4;
+    }
+
+    switch(left)
+    {
+        case 28:
+            gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X %08X",
+                      GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
+            break;
+        case 24:
+            gcmkPRINT("%08X : %08X %08X %08X %08X %08X %08X",
+                      GpuAddress, data[0], data[1], data[2], data[3], data[4], data[5]);
+            break;
+        case 20:
+            gcmkPRINT("%08X : %08X %08X %08X %08X %08X",
+                      GpuAddress, data[0], data[1], data[2], data[3], data[4]);
+            break;
+        case 16:
+            gcmkPRINT("%08X : %08X %08X %08X %08X",
+                      GpuAddress, data[0], data[1], data[2], data[3]);
+            break;
+        case 12:
+            gcmkPRINT("%08X : %08X %08X %08X",
+                      GpuAddress, data[0], data[1], data[2]);
+            break;
+        case 8:
+            gcmkPRINT("%08X : %08X %08X",
+                      GpuAddress, data[0], data[1]);
+            break;
+        case 4:
+            gcmkPRINT("%08X : %08X",
+                      GpuAddress, data[0]);
+            break;
+        default:
+            break;
+    }
+}
+
 /*******************************************************************************
 **
 **  gckCOMMAND_DumpExecutingBuffer
@@ -3241,23 +4272,17 @@ gckCOMMAND_DumpExecutingBuffer(
     )
 {
     gceSTATUS status;
-    gckVIRTUAL_COMMAND_BUFFER_PTR buffer = gcvNULL;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
     gctUINT32 gpuAddress;
-    gctSIZE_T pageCount;
     gctPOINTER entry = gcvNULL;
     gckOS os = Command->os;
     gckKERNEL kernel = Command->kernel;
     gctUINT32 i;
-    gctUINT32 dumpRear;
     gckQUEUE queue = &kernel->hardware->linkQueue;
     gctSIZE_T bytes;
-    gckLINKDATA linkData;
-    gcuQUEUEDATA * queueData;
     gctUINT32 offset;
     gctPOINTER entryDump;
-    gctUINT32 pid;
     gctUINT8 processName[24] = {0};
-    gctPHYS_ADDR_T cpuPhysical;
 
     gcmkPRINT("**************************\n");
     gcmkPRINT("**** COMMAND BUF DUMP ****\n");
@@ -3269,204 +4294,139 @@ gckCOMMAND_DumpExecutingBuffer(
     gcmkVERIFY_OK(gckOS_ReadRegisterEx(os, kernel->core, 0x664, &gpuAddress));
     gcmkVERIFY_OK(gckOS_ReadRegisterEx(os, kernel->core, 0x664, &gpuAddress));
 
-    gcmkPRINT("DMA Address 0x%08X, memory around:", gpuAddress);
+    gcmkPRINT("DMA Address 0x%08X", gpuAddress);
 
-    /* Search and dump memory around DMA address. */
-    if (kernel->virtualCommandBuffer)
-    {
-        status = gckDEVICE_QueryGPUAddress(kernel->device, kernel, gpuAddress, &buffer);
-    }
-    else
-    {
-        status = gcvSTATUS_OK;
-    }
+    /* Find GPU address in video memory list. */
+    status = gckVIDMEM_NODE_Find(kernel, gpuAddress, &nodeObject, &offset);
 
-    if (gcmIS_SUCCESS(status))
+    if (gcmIS_SUCCESS(status) && nodeObject->type == gcvVIDMEM_TYPE_COMMAND)
     {
-        if (kernel->virtualCommandBuffer)
-        {
-            gcmkVERIFY_OK(gckOS_CreateKernelVirtualMapping(
-                os, buffer->virtualBuffer.physical, buffer->virtualBuffer.bytes, &entry, &pageCount));
-
-            offset = gpuAddress - buffer->virtualBuffer.gpuAddress;
-
-            entryDump  = entry;
-
-            /* Dump one pages. */
-            bytes = 4096;
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+            kernel,
+            nodeObject,
+            gcvFALSE,
+            gcvFALSE,
+            &entryDump
+            ));
 
-            /* Align to page. */
-            offset &= 0xfffff000;
+        gcmkVERIFY_OK(gckVIDMEM_NODE_GetSize(
+            kernel,
+            nodeObject,
+            &bytes
+            ));
 
-            /* Kernel address of page where stall point stay. */
-            entryDump = (gctUINT8_PTR)entryDump + offset;
+        gcmkPRINT("Command buffer around 0x%08X:", gpuAddress);
 
-            /* Align to page. */
-            gpuAddress &= 0xfffff000;
-        }
-        else
-        {
-            gcmkVERIFY_OK(gckOS_GPUPhysicalToCPUPhysical(os, gpuAddress, &cpuPhysical));
+        /* Align to 4096. */
+        offset &= 0xfffff000;
+        gpuAddress &= 0xfffff000;
 
-            gcmkVERIFY_OK(gckOS_MapPhysical(os, (gctUINT32) cpuPhysical, 4096, &entry));
+        /* Dump max 4096 bytes. */
+        bytes = (bytes - offset) > 1024 ? 1024 : (bytes - offset);
 
-            /* Align to page start. */
-            entryDump  = (gctPOINTER)((gctUINTPTR_T)entry & ~0xFFF);
-            gpuAddress = gpuAddress & ~0xFFF;
-            bytes      = 4096;
-        }
+        /* Kernel address of page where stall point stay. */
+        entryDump = (gctUINT8_PTR)entryDump + offset;
 
-        gcmkPRINT("User Command Buffer:\n");
         _DumpBuffer(entryDump, gpuAddress, bytes);
 
-        if (kernel->virtualCommandBuffer)
-        {
-            gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(
-                os, buffer->virtualBuffer.physical, buffer->virtualBuffer.bytes, entry));
-        }
-        else
-        {
-             gcmkVERIFY_OK(gckOS_UnmapPhysical(os, entry, 4096));
-        }
+        gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+            kernel,
+            nodeObject,
+            0,
+            gcvFALSE
+            ));
     }
     else
     {
-        _DumpKernelCommandBuffer(Command);
+        gcmkPRINT("Can not find command buffer around 0x%08X.\n", gpuAddress);
+    }
+
+    /* new line. */
+    gcmkPRINT("");
+
+    gcmkPRINT("Kernel command buffers:");
+
+    for (i = 0; i < gcdCOMMAND_QUEUES; i++)
+    {
+        entry = Command->queues[i].logical;
+        gpuAddress = Command->queues[i].address;
+
+        gcmkPRINT("command buffer %d at 0x%08X size %u",
+                  i, gpuAddress, Command->pageSize);
+        _DumpBuffer(entry, gpuAddress, Command->pageSize);
     }
 
-    /* Dump link queue. */
+    /* new line. */
+    gcmkPRINT("");
+
     if (queue->count)
     {
         gcmkPRINT("Dump Level is %d, dump %d valid record in link queue:",
                   Command->kernel->stuckDump, queue->count);
+    }
 
-        dumpRear  = queue->count;
+    for (i = 0; i < queue->count; i++)
+    {
+        gcuQUEUEDATA * queueData;
+        gckLINKDATA linkData;
 
-        for (i = 0; i < dumpRear; i++)
-        {
-            gckQUEUE_GetData(queue, i, &queueData);
+        gckQUEUE_GetData(queue, i, &queueData);
 
-            linkData = &queueData->linkData;
+        linkData = &queueData->linkData;
 
-            /* Get gpu address of this command buffer. */
-            gpuAddress = linkData->start;
-            bytes = linkData->end - gpuAddress;
+        /* Get gpu address of this command buffer. */
+        gpuAddress = linkData->start;
+        bytes = linkData->end - gpuAddress;
 
-            pid = linkData->pid;
+        processName[0] = '\0';
+        gckOS_GetProcessNameByPid(linkData->pid, sizeof(processName), processName);
 
-            gckOS_GetProcessNameByPid(pid, 16, processName);
+        gcmkPRINT("Link record %d: [%08X - %08X] from command %08X %08X pid %u (%s):",
+                  i,
+                  linkData->start,
+                  linkData->end,
+                  linkData->linkLow,
+                  linkData->linkHigh,
+                  linkData->pid,
+                  processName);
 
-            if (kernel->virtualCommandBuffer)
-            {
-                buffer = gcvNULL;
-
-                /* Get the whole buffer. */
-                status = gckDEVICE_QueryGPUAddress(kernel->device, kernel, gpuAddress, &buffer);
-
-                if (gcmIS_ERROR(status))
-                {
-                    /* Get kernel address of kernel command buffer. */
-                    status = gckCOMMAND_AddressInKernelCommandBuffer(
-                             kernel->command, gpuAddress, &entry);
-
-                    if (gcmIS_ERROR(status))
-                    {
-                        status = gckHARDWARE_AddressInHardwareFuncions(
-                                 kernel->hardware, gpuAddress, &entry);
-
-                        if (gcmIS_ERROR(status))
-                        {
-                            gcmkPRINT("Buffer [%08X - %08X] not found, may be freed",
-                                      linkData->start,
-                                      linkData->end);
-                            continue;
-                        }
-                    }
-
-                    offset = 0;
-                    gcmkPRINT("Kernel Command Buffer: %08X, %08X", linkData->linkLow, linkData->linkHigh);
-                }
-                else
-                {
-                    /* Get kernel logical for dump. */
-                    if (buffer->virtualBuffer.kernelLogical)
-                    {
-                        /* Get kernel logical directly if it is a context buffer. */
-                        entry = buffer->virtualBuffer.kernelLogical;
-                        gcmkPRINT("Context Buffer: %08X, %08X PID:%d %s",
-                                  linkData->linkLow, linkData->linkHigh, linkData->pid, processName);
-                    }
-                    else
-                    {
-                        /* Make it accessiable by kernel if it is a user command buffer. */
-                        gcmkVERIFY_OK(
-                            gckOS_CreateKernelVirtualMapping(os,
-                                                             buffer->virtualBuffer.physical,
-                                                             buffer->virtualBuffer.bytes,
-                                                             &entry,
-                                                             &pageCount));
-                         gcmkPRINT("User Command Buffer: %08X, %08X PID:%d %s",
-                                   linkData->linkLow, linkData->linkHigh, linkData->pid, processName);
-                    }
-
-                    offset = gpuAddress - buffer->virtualBuffer.gpuAddress;
-                }
-
-                /* Dump from the entry. */
-                _DumpBuffer((gctUINT8_PTR)entry + offset, gpuAddress, bytes);
-
-                /* Release kernel logical address if neccessary. */
-                if (buffer && !buffer->virtualBuffer.kernelLogical)
-                {
-                    gcmkVERIFY_OK(
-                        gckOS_DestroyKernelVirtualMapping(os,
-                                                          buffer->virtualBuffer.physical,
-                                                          buffer->virtualBuffer.bytes,
-                                                          entry));
-                }
-            }
-            else
-            {
-                gcmkVERIFY_OK(gckOS_GPUPhysicalToCPUPhysical(os, gpuAddress, &cpuPhysical));
+        /* Find GPU address in video memory list. */
+        status = gckVIDMEM_NODE_Find(kernel, gpuAddress, &nodeObject, &offset);
 
-                gcmkVERIFY_OK(gckOS_MapPhysical(os, (gctUINT32) cpuPhysical, bytes, &entry));
+        if (gcmIS_SUCCESS(status) && nodeObject->type == gcvVIDMEM_TYPE_COMMAND)
+        {
+            gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+                kernel,
+                nodeObject,
+                gcvFALSE,
+                gcvFALSE,
+                &entryDump
+                ));
 
-                gcmkPRINT("Command Buffer: %08X, %08X PID:%d %s",
-                          linkData->linkLow, linkData->linkHigh, linkData->pid, processName);
+            /* Kernel address of page where stall point stay. */
+            entryDump = (gctUINT8_PTR)entryDump + offset;
 
-                _DumpBuffer((gctUINT8_PTR)entry, gpuAddress, bytes);
+            _DumpBuffer(entryDump, gpuAddress, bytes);
 
-                gcmkVERIFY_OK(gckOS_UnmapPhysical(os, entry, bytes));
-            }
+            gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+                kernel,
+                nodeObject,
+                0,
+                gcvFALSE
+                ));
         }
-    }
-
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckCOMMAND_AddressInKernelCommandBuffer(
-    IN gckCOMMAND Command,
-    IN gctUINT32 Address,
-    OUT gctPOINTER * Pointer
-    )
-{
-    gctINT i;
-
-    for (i = 0; i < gcdCOMMAND_QUEUES; i++)
-    {
-        if ((Address >= Command->queues[i].address)
-         && (Address < (Command->queues[i].address + Command->pageSize))
-        )
+        else
         {
-            *Pointer = (gctUINT8_PTR)Command->queues[i].logical
-                     + (Address - Command->queues[i].address)
-                     ;
-
-            return gcvSTATUS_OK;
+            gcmkPRINT("Not found");
         }
+
+        /* new line. */
+        gcmkPRINT("");
     }
 
-    return gcvSTATUS_NOT_FOUND;
+    return gcvSTATUS_OK;
+
+OnError:
+    return status;
 }
 
index 6c30ceb..f039679 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -473,7 +473,7 @@ _AllocateTaskContainer(
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Command=0x%x Size=0x%x, Buffer ==0x%x", Command, Size, Buffer);
+    gcmkHEADER_ARG("Command=%p Size=0x%x, Buffer =%p", Command, Size, Buffer);
 
     /* Verify arguments. */
     gcmkVERIFY_ARGUMENT(Buffer != gcvNULL);
@@ -1046,11 +1046,11 @@ _HardwareToKernel(
     gctSIZE_T bytes;
     status = gcvSTATUS_OK;
 
-    memory = Node->VidMem.memory;
+    memory = Node->VidMem.parent;
 
     if (memory->object.type == gcvOBJ_VIDMEM)
     {
-        nodePhysical = memory->baseAddress
+        nodePhysical = (gctUINT32)memory->physicalBase
                      + (gctUINT32)Node->VidMem.offset
                      + Node->VidMem.alignment;
         bytes = Node->VidMem.bytes;
@@ -1177,15 +1177,16 @@ _AllocateLinear(
 
     do
     {
-        gcmkERR_BREAK(gckOS_AllocateContiguous(
+        gcmkERR_BREAK(gckOS_AllocateNonPagedMemory(
             Command->os,
             gcvFALSE,
+            gcvALLOC_FLAG_CONTIGUOUS,
             &size,
             &physical,
             &logical
             ));
 
-        gcmkERR_BREAK(gckOS_GetPhysicalAddress(Command->os, logical, &paddr));
+        gcmkERR_BREAK(gckOS_GetPhysicalFromHandle(Command->os, physical, 0, &paddr));
 
         gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Command->os, paddr, &paddr));
 
@@ -1205,7 +1206,7 @@ _AllocateLinear(
     if (physical != gcvNULL)
     {
         /* Free the command buffer. */
-        gcmkCHECK_STATUS(gckOS_FreeContiguous(Command->os, physical, logical, size));
+        gcmkCHECK_STATUS(gckOS_FreeNonPagedMemory(Command->os, physical, logical, size));
     }
 
     /* Return status. */
@@ -1223,7 +1224,7 @@ _FreeLinear(
 
     do
     {
-        gcmkERR_BREAK(gckOS_FreeContiguous(Kernel->os, Node, Logical, 1));
+        gcmkERR_BREAK(gckOS_FreeNonPagedMemory(Kernel->os, Node, Logical, 1));
     }
     while (gcvFALSE);
 
@@ -1454,12 +1455,6 @@ _TaskFreeContiguousMemory(
     gcsBLOCK_TASK_ENTRY_PTR TaskHeader
     );
 
-static gceSTATUS
-_TaskUnmapUserMemory(
-    gckVGCOMMAND Command,
-    gcsBLOCK_TASK_ENTRY_PTR TaskHeader
-    );
-
 static gctTASKROUTINE _taskRoutine[] =
 {
     _TaskLink,                  /* gcvTASK_LINK                   */
@@ -1471,7 +1466,6 @@ static gctTASKROUTINE _taskRoutine[] =
     _TaskUnlockVideoMemory,     /* gcvTASK_UNLOCK_VIDEO_MEMORY    */
     _TaskFreeVideoMemory,       /* gcvTASK_FREE_VIDEO_MEMORY      */
     _TaskFreeContiguousMemory,  /* gcvTASK_FREE_CONTIGUOUS_MEMORY */
-    _TaskUnmapUserMemory,       /* gcvTASK_UNMAP_USER_MEMORY      */
 };
 
 static gceSTATUS
@@ -1791,15 +1785,19 @@ _TaskUnlockVideoMemory(
 
     do
     {
+        gctUINT32 processID;
+
         /* Cast the task pointer. */
         gcsTASK_UNLOCK_VIDEO_MEMORY_PTR task
             = (gcsTASK_UNLOCK_VIDEO_MEMORY_PTR) TaskHeader->task;
 
+        gckOS_GetProcessID(&processID);
+
         /* Unlock video memory. */
-        gcmkERR_BREAK(gckVIDMEM_Unlock(
+        gcmkERR_BREAK(gckVIDMEM_NODE_Unlock(
             Command->kernel->kernel,
             (gckVIDMEM_NODE)gcmUINT64_TO_PTR(task->node),
-            gcvSURF_TYPE_UNKNOWN,
+            processID,
             gcvNULL));
 
         gcmkERR_BREAK(gckVIDMEM_NODE_Dereference(
@@ -1864,7 +1862,7 @@ _TaskFreeContiguousMemory(
             = (gcsTASK_FREE_CONTIGUOUS_MEMORY_PTR) TaskHeader->task;
 
         /* Free contiguous memory. */
-        gcmkERR_BREAK(gckOS_FreeContiguous(
+        gcmkERR_BREAK(gckOS_FreeNonPagedMemory(
             Command->os, task->physical, task->logical, task->bytes
             ));
 
@@ -1880,41 +1878,6 @@ _TaskFreeContiguousMemory(
     return status;
 }
 
-static gceSTATUS
-_TaskUnmapUserMemory(
-    gckVGCOMMAND Command,
-    gcsBLOCK_TASK_ENTRY_PTR TaskHeader
-    )
-{
-    gceSTATUS status;
-    gctPOINTER info;
-
-    do
-    {
-        /* Cast the task pointer. */
-        gcsTASK_UNMAP_USER_MEMORY_PTR task
-            = (gcsTASK_UNMAP_USER_MEMORY_PTR) TaskHeader->task;
-
-        info = gckKERNEL_QueryPointerFromName(
-                Command->kernel->kernel, gcmALL_TO_UINT32(task->info));
-
-        /* Unmap the user memory. */
-        gcmkERR_BREAK(gckOS_UnmapUserMemory(
-            Command->os, gcvCORE_VG, task->memory, task->size, info, task->address
-            ));
-
-        /* Update the reference counter. */
-        TaskHeader->container->referenceCount -= 1;
-
-        /* Update the task pointer. */
-        TaskHeader->task = (gcsTASK_HEADER_PTR) (task + 1);
-    }
-    while (gcvFALSE);
-
-    /* Return status. */
-    return status;
-}
-
 /******************************************************************************\
 ************ Hardware Block Interrupt Handlers For Scheduled Events ************
 \******************************************************************************/
@@ -1928,7 +1891,7 @@ _EventHandler_Block(
 {
     gceSTATUS status = gcvSTATUS_OK, last;
 
-    gcmkHEADER_ARG("Kernel=0x%x TaskHeader=0x%x ProcessAll=0x%x", Kernel, TaskHeader, ProcessAll);
+    gcmkHEADER_ARG("Kernel=%p TaskHeader=%p ProcessAll=0x%x", Kernel, TaskHeader, ProcessAll);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
 
@@ -2003,7 +1966,7 @@ gcmDECLARE_INTERRUPT_HANDLER(COMMAND, 0)
 {
     gceSTATUS status, last;
 
-    gcmkHEADER_ARG("Kernel=0x%x ", Kernel);
+    gcmkHEADER_ARG("Kernel=%p ", Kernel);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -2134,7 +2097,7 @@ gcmDECLARE_INTERRUPT_HANDLER(COMMAND, 0)
                 }
                 else
                 {
-                    status = gckVGHARDWARE_SetPowerManagementState(
+                    status = gckVGHARDWARE_SetPowerState(
                                 Kernel->command->hardware, gcvPOWER_IDLE_BROADCAST
                                 );
                 }
@@ -2889,7 +2852,7 @@ gckVGCOMMAND_Construct(
     gcsKERNEL_QUEUE_HEADER_PTR queue;
     gctUINT i, j;
 
-    gcmkHEADER_ARG("Kernel=0x%x TaskGranularity=0x%x QueueSize=0x%x Command=0x%x",
+    gcmkHEADER_ARG("Kernel=%p TaskGranularity=0x%x QueueSize=0x%x Command=%p",
         Kernel, TaskGranularity, QueueSize, Command);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -3204,7 +3167,7 @@ gckVGCOMMAND_Destroy(
 {
     gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Command=0x%x", Command);
+    gcmkHEADER_ARG("Command=%p", Command);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
@@ -3385,7 +3348,7 @@ gckVGCOMMAND_QueryCommandBuffer(
     OUT gcsCOMMAND_BUFFER_INFO_PTR Information
     )
 {
-    gcmkHEADER_ARG("Command=0x%x Information=0x%x", Command, Information);
+    gcmkHEADER_ARG("Command=%p Information=%p", Command, Information);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Command, gcvOBJ_COMMAND);
     gcmkVERIFY_ARGUMENT(Information != gcvNULL);
@@ -3410,7 +3373,7 @@ gckVGCOMMAND_Allocate(
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Command=0x%x Size=0x%x CommandBuffer=0x%x Data=0x%x",
+    gcmkHEADER_ARG("Command=%p Size=0x%x CommandBuffer=%p Data=0x%x",
         Command, Size, CommandBuffer, Data);
 
     /* Verify the arguments. */
@@ -3440,7 +3403,7 @@ gckVGCOMMAND_Free(
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
+    gcmkHEADER_ARG("Command=%p CommandBuffer=%p",
         Command, CommandBuffer);
 
     /* Verify the arguments. */
@@ -3463,7 +3426,7 @@ gckVGCOMMAND_Execute(
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Command=0x%x CommandBuffer=0x%x",
+    gcmkHEADER_ARG("Command=%p CommandBuffer=%p",
         Command, CommandBuffer);
 
     /* Verify the arguments. */
@@ -3555,7 +3518,7 @@ gckVGCOMMAND_Commit(
     struct _gcsVGCONTEXT  _Context;
     gctBOOL needCopy = gcvFALSE;
 
-    gcmkHEADER_ARG("Command=0x%x Context=0x%x Queue=0x%x EntryCount=0x%x TaskTable=0x%x",
+    gcmkHEADER_ARG("Command=%p Context=%p Queue=%p EntryCount=0x%x TaskTable=%p",
             Command, Context, Queue, EntryCount, TaskTable);
 
     /* Verify the arguments. */
@@ -3633,7 +3596,7 @@ gckVGCOMMAND_Commit(
             Context = &_Context;
         }
 
-        gcmkERR_BREAK(gckVGHARDWARE_SetPowerManagementState(
+        gcmkERR_BREAK(gckVGHARDWARE_SetPowerState(
                     Command->hardware, gcvPOWER_ON_AUTO
                     ));
 
@@ -3873,8 +3836,17 @@ gckVGCOMMAND_Commit(
                                 Command->os,
                                 Command->queueMutex
                                 ));
+                    /* Add a semaphore stall after PE EVENT (Before the END). */
+                    {
+                        gctUINT32_PTR memory = (gctUINT32_PTR)(previousEnd - 0x10);
+                        *memory++ = 0x10000007;
+                        *memory++ = 0;
+
+                        *memory++ = 0x20000007;
+                        *memory++ = 0;
+                    }
                     /* Schedule tasks. */
-                    gcmkERR_BREAK(_ScheduleTasks(Command, TaskTable, previousEnd));
+                    gcmkERR_BREAK(_ScheduleTasks(Command, TaskTable, previousEnd - 0x10));
 
                     /* Acquire the mutex. */
                     gcmkERR_BREAK(gckOS_AcquireMutex(
index 49c261a..ff360f0 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -101,7 +101,7 @@ gckKERNEL_FindDatabase(
     gctSIZE_T slot;
     gctBOOL acquired = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d LastProcessID=%d",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d LastProcessID=%d",
                    Kernel, ProcessID, LastProcessID);
 
     /* Compute the hash for the database. */
@@ -200,7 +200,7 @@ gckKERNEL_DeinitDatabase(
     IN gcsDATABASE_PTR Database
     )
 {
-    gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
+    gcmkHEADER_ARG("Kernel=%p Database=%p", Kernel, Database);
 
     if (Database)
     {
@@ -224,14 +224,6 @@ gckKERNEL_DeinitDatabase(
             gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Database->handleDatabaseMutex));
             Database->handleDatabaseMutex = gcvNULL;
         }
-
-#if gcdPROCESS_ADDRESS_SPACE
-        if (Database->mmu)
-        {
-            gcmkONERROR(gckEVENT_DestroyMmu(Kernel->eventObj, Database->mmu, gcvKERNEL_PIXEL));
-            Database->mmu = gcvNULL;
-        }
-#endif
     }
 
     gcmkFOOTER_NO();
@@ -270,7 +262,7 @@ gckKERNEL_NewRecord(
     gctBOOL acquired = gcvFALSE;
     gcsDATABASE_RECORD_PTR record = gcvNULL;
 
-    gcmkHEADER_ARG("Kernel=0x%x Database=0x%x", Kernel, Database);
+    gcmkHEADER_ARG("Kernel=%p Database=%p", Kernel, Database);
 
     /* Acquire the database mutex. */
     gcmkONERROR(
@@ -364,7 +356,7 @@ gckKERNEL_DeleteRecord(
     gcsDATABASE_RECORD_PTR record, previous;
     gctUINT32 slot = _GetSlot(Database, Data);
 
-    gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
+    gcmkHEADER_ARG("Kernel=%p Database=%p Type=%d Data=%p",
                    Kernel, Database, Type, Data);
 
     /* Acquire the database mutex. */
@@ -473,7 +465,7 @@ gckKERNEL_FindRecord(
     gcsDATABASE_RECORD_PTR record;
     gctUINT32 slot = _GetSlot(Database, Data);
 
-    gcmkHEADER_ARG("Kernel=0x%x Database=0x%x Type=%d Data=0x%x",
+    gcmkHEADER_ARG("Kernel=%p Database=%p Type=%d Data=%p",
                    Kernel, Database, Type, Data);
 
     /* Acquire the database mutex. */
@@ -561,7 +553,7 @@ gckKERNEL_CreateProcessDB(
     gctSIZE_T slot;
     gctUINT32 i;
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d", Kernel, ProcessID);
 
     /* Compute the hash for the database. */
     slot = ProcessID % gcmCOUNTOF(Kernel->db->db);
@@ -621,22 +613,16 @@ gckKERNEL_CreateProcessDB(
     database->nonPaged.bytes            = 0;
     database->nonPaged.maxBytes         = 0;
     database->nonPaged.totalBytes       = 0;
-    database->contiguous.bytes          = 0;
-    database->contiguous.maxBytes       = 0;
-    database->contiguous.totalBytes     = 0;
     database->mapMemory.bytes           = 0;
     database->mapMemory.maxBytes        = 0;
     database->mapMemory.totalBytes      = 0;
-    database->mapUserMemory.bytes       = 0;
-    database->mapUserMemory.maxBytes    = 0;
-    database->mapUserMemory.totalBytes  = 0;
 
     for (i = 0; i < gcmCOUNTOF(database->list); i++)
     {
         database->list[i] = gcvNULL;
     }
 
-    for (i = 0; i < gcvSURF_NUM_TYPES; i++)
+    for (i = 0; i < gcvVIDMEM_TYPE_COUNT; i++)
     {
         database->vidMemType[i].bytes = 0;
         database->vidMemType[i].maxBytes = 0;
@@ -655,63 +641,11 @@ gckKERNEL_CreateProcessDB(
     gcmkONERROR(gckOS_AtomSet(Kernel->os, database->refs, 1));
 
     gcmkASSERT(database->handleDatabase == gcvNULL);
-    gcmkONERROR(gckKERNEL_CreateIntegerDatabase(Kernel, &database->handleDatabase));
+    gcmkONERROR(gckKERNEL_CreateIntegerDatabase(Kernel, 64, &database->handleDatabase));
 
     gcmkASSERT(database->handleDatabaseMutex == gcvNULL);
     gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->handleDatabaseMutex));
 
-#if gcdPROCESS_ADDRESS_SPACE
-    gcmkASSERT(database->mmu == gcvNULL);
-    gcmkONERROR(gckMMU_Construct(Kernel, gcdMMU_SIZE, &database->mmu));
-#endif
-
-#if gcdSECURE_USER
-    {
-        gctINT idx;
-        gcskSECURE_CACHE * cache = &database->cache;
-
-        /* Setup the linked list of cache nodes. */
-        for (idx = 1; idx <= gcdSECURE_CACHE_SLOTS; ++idx)
-        {
-            cache->cache[idx].logical = gcvNULL;
-
-#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
-            cache->cache[idx].prev = &cache->cache[idx - 1];
-            cache->cache[idx].next = &cache->cache[idx + 1];
-#   endif
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-            cache->cache[idx].nextHash = gcvNULL;
-            cache->cache[idx].prevHash = gcvNULL;
-#   endif
-        }
-
-#if gcdSECURE_CACHE_METHOD != gcdSECURE_CACHE_TABLE
-        /* Setup the head and tail of the cache. */
-        cache->cache[0].next    = &cache->cache[1];
-        cache->cache[0].prev    = &cache->cache[gcdSECURE_CACHE_SLOTS];
-        cache->cache[0].logical = gcvNULL;
-
-        /* Fix up the head and tail pointers. */
-        cache->cache[0].next->prev = &cache->cache[0];
-        cache->cache[0].prev->next = &cache->cache[0];
-#   endif
-
-#if gcdSECURE_CACHE_METHOD == gcdSECURE_CACHE_HASH
-        /* Zero out the hash table. */
-        for (idx = 0; idx < gcmCOUNTOF(cache->hash); ++idx)
-        {
-            cache->hash[idx].logical  = gcvNULL;
-            cache->hash[idx].nextHash = gcvNULL;
-        }
-#   endif
-
-        /* Initialize cache index. */
-        cache->cacheIndex = gcvNULL;
-        cache->cacheFree  = 1;
-        cache->cacheStamp = 0;
-    }
-#endif
-
     /* Insert the database into the hash. */
     database->next = Kernel->db->db[slot];
     Kernel->db->db[slot] = database;
@@ -788,8 +722,8 @@ gckKERNEL_AddProcessDB(
     gctUINT32 vidMemType;
     gcePOOL vidMemPool;
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x "
-                   "Physical=0x%x Size=%lu",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d Type=%d Pointer=%p "
+                   "Physical=%p Size=%lu",
                    Kernel, ProcessID, Type, Pointer, Physical, Size);
 
     /* Verify the arguments. */
@@ -888,18 +822,10 @@ gckKERNEL_AddProcessDB(
         count = &database->nonPaged;
         break;
 
-    case gcvDB_CONTIGUOUS:
-        count = &database->contiguous;
-        break;
-
     case gcvDB_MAP_MEMORY:
         count = &database->mapMemory;
         break;
 
-    case gcvDB_MAP_USER_MEMORY:
-        count = &database->mapUserMemory;
-        break;
-
     default:
         count = gcvNULL;
         break;
@@ -996,7 +922,7 @@ gckKERNEL_RemoveProcessDB(
     gctUINT32 vidMemType;
     gcePOOL vidMemPool;
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d Type=%d Pointer=%p",
                    Kernel, ProcessID, Type, Pointer);
 
     /* Verify the arguments. */
@@ -1035,21 +961,11 @@ gckKERNEL_RemoveProcessDB(
         database->nonPaged.freeCount++;
         break;
 
-    case gcvDB_CONTIGUOUS:
-        database->contiguous.bytes -= bytes;
-        database->contiguous.freeCount++;
-        break;
-
     case gcvDB_MAP_MEMORY:
         database->mapMemory.bytes -= bytes;
         database->mapMemory.freeCount++;
         break;
 
-    case gcvDB_MAP_USER_MEMORY:
-        database->mapUserMemory.bytes -= bytes;
-        database->mapUserMemory.freeCount++;
-        break;
-
     default:
         break;
     }
@@ -1103,7 +1019,7 @@ gckKERNEL_FindProcessDB(
     gceSTATUS status;
     gcsDATABASE_PTR database;
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Pointer=0x%x",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d Type=%d Pointer=%p",
                    Kernel, ProcessID, ThreadID, Type, Pointer);
 
     /* Verify the arguments. */
@@ -1161,7 +1077,7 @@ gckKERNEL_DestroyProcessDB(
     gctSIZE_T slot;
     gctUINT32 i;
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d", Kernel, ProcessID);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -1219,10 +1135,6 @@ gckKERNEL_DestroyProcessDB(
                    "DB(%d): NonPaged: total=%lu max=%lu",
                    ProcessID, database->nonPaged.totalBytes,
                    database->nonPaged.maxBytes);
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
-                   "DB(%d): Contiguous: total=%lu max=%lu",
-                   ProcessID, database->contiguous.totalBytes,
-                   database->contiguous.maxBytes);
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
                    "DB(%d): Idle time=%llu",
                    ProcessID, Kernel->db->idleTime);
@@ -1230,12 +1142,7 @@ gckKERNEL_DestroyProcessDB(
                    "DB(%d): Map: total=%lu max=%lu",
                    ProcessID, database->mapMemory.totalBytes,
                    database->mapMemory.maxBytes);
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DATABASE,
-                   "DB(%d): Map: total=%lu max=%lu",
-                   ProcessID, database->mapUserMemory.totalBytes,
-                   database->mapUserMemory.maxBytes);
 
-    if (database->list != gcvNULL)
     {
         gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
                        "Process %d has entries in its database:",
@@ -1281,57 +1188,17 @@ gckKERNEL_DestroyProcessDB(
 
             case gcvDB_NON_PAGED:
                 physical = gcmNAME_TO_PTR(record->physical);
-                /* Unmap user logical memory first. */
-                status = gckOS_UnmapUserLogical(Kernel->os,
-                                                physical,
-                                                record->bytes,
-                                                record->data);
 
                 /* Free the non paged memory. */
-                status = gckEVENT_FreeNonPagedMemory(record->kernel->eventObj,
-                                                     record->bytes,
-                                                     physical,
-                                                     record->data,
-                                                     gcvKERNEL_PIXEL);
-                gcmRELEASE_NAME(record->physical);
-
-                gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
-                               "DB: NON_PAGED 0x%x, bytes=%lu (status=%d)",
-                               record->data, record->bytes, status);
-                break;
+                status = gckOS_FreeNonPagedMemory(Kernel->os,
+                                                  physical,
+                                                  record->data,
+                                                  record->bytes);
 
-            case gcvDB_COMMAND_BUFFER:
-                /* Free the command buffer. */
-                status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj,
-                                                              record->bytes,
-                                                              gcmNAME_TO_PTR(record->physical),
-                                                              record->data,
-                                                              gcvKERNEL_PIXEL);
                 gcmRELEASE_NAME(record->physical);
 
                 gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
-                               "DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)",
-                               record->data, record->bytes, status);
-                break;
-
-            case gcvDB_CONTIGUOUS:
-                physical = gcmNAME_TO_PTR(record->physical);
-                /* Unmap user logical memory first. */
-                status = gckOS_UnmapUserLogical(Kernel->os,
-                                                physical,
-                                                record->bytes,
-                                                record->data);
-
-                /* Free the contiguous memory. */
-                status = gckEVENT_FreeContiguousMemory(record->kernel->eventObj,
-                                                       record->bytes,
-                                                       physical,
-                                                       record->data,
-                                                       gcvKERNEL_PIXEL);
-                gcmRELEASE_NAME(record->physical);
-
-                gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
-                               "DB: CONTIGUOUS 0x%x bytes=%lu (status=%d)",
+                               "DB: NON_PAGED 0x%x, bytes=%lu (status=%d)",
                                record->data, record->bytes, status);
                 break;
 
@@ -1357,46 +1224,54 @@ gckKERNEL_DestroyProcessDB(
                                                       handle,
                                                       &nodeObject));
 
+                /* Unlock CPU. */
+                gcmkVERIFY_OK(gckVIDMEM_NODE_UnlockCPU(
+                    record->kernel, nodeObject, ProcessID, gcvTRUE));
+
                 /* Unlock what we still locked */
-                status = gckVIDMEM_Unlock(record->kernel,
-                                          nodeObject,
-                                          nodeObject->type,
-                                          &asynchronous);
+                status = gckVIDMEM_NODE_Unlock(record->kernel,
+                                               nodeObject,
+                                               ProcessID,
+                                               &asynchronous);
 
 #if gcdENABLE_VG
                 if (record->kernel->core == gcvCORE_VG)
                 {
                     if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
                     {
-                        status = gckVIDMEM_Unlock(record->kernel,
-                                                  nodeObject,
-                                                  nodeObject->type,
-                                                  gcvNULL);
+                        status = gckVIDMEM_NODE_Unlock(record->kernel,
+                                                       nodeObject,
+                                                       ProcessID,
+                                                       gcvNULL);
                     }
 
+                    /* Deref handle. */
                     gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel,
                                                                ProcessID,
                                                                handle));
 
+                    /* Deref node. */
                     gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel,
                                                              nodeObject));
                 }
                 else
 #endif
                 {
+                    /* Deref handle. */
                     gcmkVERIFY_OK(gckVIDMEM_HANDLE_Dereference(record->kernel,
                                                                ProcessID,
                                                                handle));
 
                     if (gcmIS_SUCCESS(status) && (gcvTRUE == asynchronous))
                     {
+                        /* Schedule unlock: will unlock and deref node later. */
                         status = gckEVENT_Unlock(record->kernel->eventObj,
                                                  gcvKERNEL_PIXEL,
-                                                 nodeObject,
-                                                 nodeObject->type);
+                                                 nodeObject);
                     }
                     else
                     {
+                        /* Deref node */
                         gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(record->kernel,
                                                                  nodeObject));
                     }
@@ -1429,20 +1304,6 @@ gckKERNEL_DestroyProcessDB(
                                gcmPTR2INT32(record->data), status);
                 break;
 
-            case gcvDB_MAP_USER_MEMORY:
-                status = gckOS_UnmapUserMemory(Kernel->os,
-                                               Kernel->core,
-                                               record->physical,
-                                               record->bytes,
-                                               gcmNAME_TO_PTR(record->data),
-                                               0);
-                gcmRELEASE_NAME(record->data);
-
-                gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
-                               "DB: MAP USER MEMORY %d (status=%d)",
-                               gcmPTR2INT32(record->data), status);
-                break;
-
             case gcvDB_SHBUF:
                 /* Free shared buffer. */
                 status = gckKERNEL_DestroyShBuffer(record->kernel,
@@ -1566,7 +1427,7 @@ gckKERNEL_QueryProcessDB(
     gcsDATABASE_PTR database;
     gcePOOL vidMemPool;
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d Type=%d Info=0x%x",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d Type=%d Info=%p",
                    Kernel, ProcessID, Type, Info);
 
     /* Verify the arguments. */
@@ -1607,12 +1468,6 @@ gckKERNEL_QueryProcessDB(
                                   gcmSIZEOF(database->vidMem));
         break;
 
-    case gcvDB_CONTIGUOUS:
-        gckOS_MemCopy(&Info->counters,
-                                  &database->contiguous,
-                                  gcmSIZEOF(database->vidMem));
-        break;
-
     case gcvDB_IDLE:
         Info->time           = Kernel->db->idleTime;
         Kernel->db->idleTime = 0;
@@ -1624,12 +1479,6 @@ gckKERNEL_QueryProcessDB(
                                   gcmSIZEOF(database->mapMemory));
         break;
 
-    case gcvDB_MAP_USER_MEMORY:
-        gckOS_MemCopy(&Info->counters,
-                                  &database->mapUserMemory,
-                                  gcmSIZEOF(database->mapUserMemory));
-        break;
-
     default:
         break;
     }
@@ -1657,7 +1506,7 @@ gckKERNEL_FindHandleDatbase(
     gceSTATUS status;
     gcsDATABASE_PTR database;
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d",
                    Kernel, ProcessID);
 
     /* Verify the arguments. */
@@ -1679,82 +1528,6 @@ OnError:
     return status;
 }
 
-#if gcdPROCESS_ADDRESS_SPACE
-gceSTATUS
-gckKERNEL_GetProcessMMU(
-    IN gckKERNEL Kernel,
-    OUT gckMMU * Mmu
-    )
-{
-    gceSTATUS status;
-    gcsDATABASE_PTR database;
-    gctUINT32 processID;
-
-    gcmkONERROR(gckOS_GetProcessID(&processID));
-
-    gcmkONERROR(gckKERNEL_FindDatabase(Kernel, processID, gcvFALSE, &database));
-
-    *Mmu = database->mmu;
-
-    return gcvSTATUS_OK;
-
-OnError:
-    return status;
-}
-#endif
-
-#if gcdSECURE_USER
-/*******************************************************************************
-**  gckKERNEL_GetProcessDBCache
-**
-**  Get teh secure cache from a process database.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to a gckKERNEL object.
-**
-**      gctUINT32 ProcessID
-**          Process ID used to identify the database.
-**
-**  OUTPUT:
-**
-**      gcskSECURE_CACHE_PTR * Cache
-**          Pointer to a variable that receives the secure cache pointer.
-*/
-gceSTATUS
-gckKERNEL_GetProcessDBCache(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    OUT gcskSECURE_CACHE_PTR * Cache
-    )
-{
-    gceSTATUS status;
-    gcsDATABASE_PTR database;
-
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d", Kernel, ProcessID);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-    gcmkVERIFY_ARGUMENT(Cache != gcvNULL);
-
-    /* Find the database. */
-    gcmkONERROR(gckKERNEL_FindDatabase(Kernel, ProcessID, gcvFALSE, &database));
-
-    /* Return the pointer to the cache. */
-    *Cache = &database->cache;
-
-    /* Success. */
-    gcmkFOOTER_ARG("*Cache=0x%x", *Cache);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-#endif
-
 gceSTATUS
 gckKERNEL_DumpProcessDB(
     IN gckKERNEL Kernel
@@ -1764,7 +1537,7 @@ gckKERNEL_DumpProcessDB(
     gctINT i, pid;
     gctUINT8 name[24];
 
-    gcmkHEADER_ARG("Kernel=0x%x", Kernel);
+    gcmkHEADER_ARG("Kernel=%p", Kernel);
 
     /* Acquire the database mutex. */
     gcmkVERIFY_OK(
@@ -1823,8 +1596,8 @@ gckKERNEL_DumpVidMemUsage(
     gcsDATABASE_COUNTERS * counter;
     gctUINT32 i = 0;
 
-    static gctCONST_STRING surfaceTypes[] = {
-        "UNKNOWN",
+    static gctCONST_STRING vidmemTypes[] = {
+        "GENERIC",
         "INDEX",
         "VERTEX",
         "TEXTURE",
@@ -1840,11 +1613,15 @@ gckKERNEL_DumpVidMemUsage(
         "TXDESC",
         "FENCE",
         "TFBHEADER",
+        "COMMAND",
     };
 
-    gcmkHEADER_ARG("Kernel=0x%x ProcessID=%d",
+    gcmkHEADER_ARG("Kernel=%p ProcessID=%d",
                    Kernel, ProcessID);
 
+    gcmSTATIC_ASSERT(gcmCOUNTOF(vidmemTypes) == gcvVIDMEM_TYPE_COUNT,
+                     "Video memory type mismatch");
+
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
 
@@ -1859,11 +1636,11 @@ gckKERNEL_DumpVidMemUsage(
 
     _DumpCounter(counter, "Total Video Memory");
 
-    for (i = 0; i < gcvSURF_NUM_TYPES; i++)
+    for (i = 0; i < gcvVIDMEM_TYPE_COUNT; i++)
     {
         counter = &database->vidMemType[i];
 
-        _DumpCounter(counter, surfaceTypes[i]);
+        _DumpCounter(counter, vidmemTypes[i]);
     }
 
     /* Success. */
index 78ead5d..b8a24c8 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -66,40 +66,12 @@ static gctUINT32 _debugLevel = gcvLEVEL_ERROR;
 _debugZones config value
 Please Reference define in gc_hal_base.h
 */
-static gctUINT32 _debugZones = gcvZONE_NONE;
+static gctUINT32 _debugZones = gcdZONE_NONE;
 
 /******************************************************************************\
 ********************************* Debug Switches *******************************
 \******************************************************************************/
 
-/*
-    gcdBUFFERED_OUTPUT
-
-    When set to non-zero, all output is collected into a buffer with the
-    specified size.  Once the buffer gets full, the debug buffer will be
-    printed to the console. gcdBUFFERED_SIZE determines the size of the buffer.
-*/
-#define gcdBUFFERED_OUTPUT  0
-
-/*
-    gcdBUFFERED_SIZE
-
-    When set to non-zero, all output is collected into a buffer with the
-    specified size.  Once the buffer gets full, the debug buffer will be
-    printed to the console.
-*/
-#define gcdBUFFERED_SIZE    (1024 * 1024 * 2)
-
-/*
-    gcdDMA_BUFFER_COUNT
-
-    If greater then zero, the debugger will attempt to find the command buffer
-    where DMA is currently executing and then print this buffer and
-    (gcdDMA_BUFFER_COUNT - 1) buffers before the current one. If set to zero
-    or the current buffer is not found, all buffers are printed.
-*/
-#define gcdDMA_BUFFER_COUNT 0
-
 /*
     gcdTHREAD_BUFFERS
 
@@ -108,14 +80,6 @@ static gctUINT32 _debugZones = gcvZONE_NONE;
 */
 #define gcdTHREAD_BUFFERS   1
 
-/*
-    gcdENABLE_OVERFLOW
-
-    When set to non-zero, and the output buffer gets full, instead of being
-    printed, it will be allowed to overflow removing the oldest messages.
-*/
-#define gcdENABLE_OVERFLOW  1
-
 /*
     gcdSHOW_LINE_NUMBER
 
@@ -153,259 +117,16 @@ static gctUINT32 _debugZones = gcvZONE_NONE;
 ****************************** Miscellaneous Macros ****************************
 \******************************************************************************/
 
-#if gcmIS_DEBUG(gcdDEBUG_TRACE)
-#   define gcmDBGASSERT(Expression, Format, Value) \
-        if (!(Expression)) \
-        { \
-            _DirectPrint( \
-                "*** gcmDBGASSERT ***************************\n" \
-                "    function     : %s\n" \
-                "    line         : %d\n" \
-                "    expression   : " #Expression "\n" \
-                "    actual value : " Format "\n", \
-                __FUNCTION__, __LINE__, Value \
-                ); \
-        }
-#else
-#   define gcmDBGASSERT(Expression, Format, Value)
-#endif
-
-#define gcmPTRALIGNMENT(Pointer, Alignemnt) \
-( \
-    gcmALIGN(gcmPTR2INT32(Pointer), Alignemnt) - gcmPTR2INT32(Pointer) \
-)
-
-#if gcdALIGNBYSIZE
-#   define gcmISALIGNED(Offset, Alignment) \
-        (((Offset) & ((Alignment) - 1)) == 0)
-
-#   define gcmkALIGNPTR(Type, Pointer, Alignment) \
-        Pointer = (Type) gcmINT2PTR(gcmALIGN(gcmPTR2INT32(Pointer), Alignment))
-#else
-#   define gcmISALIGNED(Offset, Alignment) \
-        gcvTRUE
-
-#   define gcmkALIGNPTR(Type, Pointer, Alignment)
-#endif
-
-#define gcmALIGNSIZE(Offset, Size) \
-    ((Size - Offset) + Size)
-
-#define gcdHAVEPREFIX \
-( \
-       gcdSHOW_TIME \
-    || gcdSHOW_LINE_NUMBER \
-    || gcdSHOW_PROCESS_ID \
-    || gcdSHOW_THREAD_ID \
-)
-
-#if gcdHAVEPREFIX
-
-#   define gcdOFFSET                    0
-
-#if gcdSHOW_TIME
-#if gcmISALIGNED(gcdOFFSET, 8)
-#           define gcdTIMESIZE          gcmSIZEOF(gctUINT64)
-#       elif gcdOFFSET == 4
-#           define gcdTIMESIZE          gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
-#       else
-#           error "Unexpected offset value."
-#       endif
-#       undef  gcdOFFSET
-#       define gcdOFFSET                8
-#if !defined(gcdPREFIX_LEADER)
-#           define gcdPREFIX_LEADER     gcmSIZEOF(gctUINT64)
-#           define gcdTIMEFORMAT        "0x%016llX"
-#       else
-#           define gcdTIMEFORMAT        ", 0x%016llX"
-#       endif
-#   else
-#       define gcdTIMESIZE              0
-#       define gcdTIMEFORMAT
-#   endif
-
-#if gcdSHOW_LINE_NUMBER
-#if gcmISALIGNED(gcdOFFSET, 8)
-#           define gcdNUMSIZE           gcmSIZEOF(gctUINT64)
-#       elif gcdOFFSET == 4
-#           define gcdNUMSIZE           gcmALIGNSIZE(4, gcmSIZEOF(gctUINT64))
-#       else
-#           error "Unexpected offset value."
-#       endif
-#       undef  gcdOFFSET
-#       define gcdOFFSET                8
-#if !defined(gcdPREFIX_LEADER)
-#           define gcdPREFIX_LEADER     gcmSIZEOF(gctUINT64)
-#           define gcdNUMFORMAT         "%8llu"
-#       else
-#           define gcdNUMFORMAT         ", %8llu"
-#       endif
-#   else
-#       define gcdNUMSIZE               0
-#       define gcdNUMFORMAT
-#   endif
-
-#if gcdSHOW_PROCESS_ID
-#if gcmISALIGNED(gcdOFFSET, 4)
-#           define gcdPIDSIZE           gcmSIZEOF(gctUINT32)
-#       else
-#           error "Unexpected offset value."
-#       endif
-#       undef  gcdOFFSET
-#       define gcdOFFSET                4
-#if !defined(gcdPREFIX_LEADER)
-#           define gcdPREFIX_LEADER     gcmSIZEOF(gctUINT32)
-#           define gcdPIDFORMAT         "pid=%5d"
-#       else
-#           define gcdPIDFORMAT         ", pid=%5d"
-#       endif
-#   else
-#       define gcdPIDSIZE               0
-#       define gcdPIDFORMAT
-#   endif
-
-#if gcdSHOW_THREAD_ID
-#if gcmISALIGNED(gcdOFFSET, 4)
-#           define gcdTIDSIZE           gcmSIZEOF(gctUINT32)
-#       else
-#           error "Unexpected offset value."
-#       endif
-#       undef  gcdOFFSET
-#       define gcdOFFSET                4
-#if !defined(gcdPREFIX_LEADER)
-#           define gcdPREFIX_LEADER     gcmSIZEOF(gctUINT32)
-#           define gcdTIDFORMAT         "tid=%5d"
-#       else
-#           define gcdTIDFORMAT         ", tid=%5d"
-#       endif
-#   else
-#       define gcdTIDSIZE               0
-#       define gcdTIDFORMAT
-#   endif
-
-#   define gcdPREFIX_SIZE \
-    ( \
-          gcdTIMESIZE \
-        + gcdNUMSIZE  \
-        + gcdPIDSIZE  \
-        + gcdTIDSIZE  \
-    )
-
-    static const char * _prefixFormat =
-    "["
-        gcdTIMEFORMAT
-        gcdNUMFORMAT
-        gcdPIDFORMAT
-        gcdTIDFORMAT
-    "] ";
-
-#else
-
-#   define gcdPREFIX_LEADER             gcmSIZEOF(gctUINT32)
-#   define gcdPREFIX_SIZE               0
-
-#endif
-
-/* Assumed largest variable argument leader size. */
-#define gcdVARARG_LEADER                gcmSIZEOF(gctUINT64)
-
-/* Alignnments. */
-#if gcdALIGNBYSIZE
-#   define gcdPREFIX_ALIGNMENT gcdPREFIX_LEADER
-#   define gcdVARARG_ALIGNMENT gcdVARARG_LEADER
-#else
-#   define gcdPREFIX_ALIGNMENT 0
-#   define gcdVARARG_ALIGNMENT 0
-#endif
-
-#if gcdBUFFERED_OUTPUT
-#   define gcdOUTPUTPREFIX _AppendPrefix
-#   define gcdOUTPUTSTRING _AppendString
-#   define gcdOUTPUTCOPY   _AppendCopy
-#   define gcdOUTPUTBUFFER _AppendBuffer
+#if gcdSHOW_TIME || gcdSHOW_LINE_NUMBER || gcdSHOW_PROCESS_ID || gcdSHOW_THREAD_ID
+#  define gcdHAVEPREFIX     1
 #else
-#   define gcdOUTPUTPREFIX _PrintPrefix
-#   define gcdOUTPUTSTRING _PrintString
-#   define gcdOUTPUTCOPY   _PrintString
-#   define gcdOUTPUTBUFFER _PrintBuffer
+#  define gcdHAVEPREFIX     0
 #endif
 
 /******************************************************************************\
 ****************************** Private Structures ******************************
 \******************************************************************************/
 
-typedef enum _gceBUFITEM
-{
-    gceBUFITEM_NONE,
-    gcvBUFITEM_PREFIX,
-    gcvBUFITEM_STRING,
-    gcvBUFITEM_COPY,
-    gcvBUFITEM_BUFFER
-}
-gceBUFITEM;
-
-/* Common item head/buffer terminator. */
-typedef struct _gcsBUFITEM_HEAD * gcsBUFITEM_HEAD_PTR;
-typedef struct _gcsBUFITEM_HEAD
-{
-    gceBUFITEM              type;
-}
-gcsBUFITEM_HEAD;
-
-/* String prefix (for ex. [     1,tid=0x019A]) */
-typedef struct _gcsBUFITEM_PREFIX * gcsBUFITEM_PREFIX_PTR;
-typedef struct _gcsBUFITEM_PREFIX
-{
-    gceBUFITEM              type;
-#if gcdHAVEPREFIX
-    gctPOINTER              prefixData;
-#endif
-}
-gcsBUFITEM_PREFIX;
-
-/* Buffered string. */
-typedef struct _gcsBUFITEM_STRING * gcsBUFITEM_STRING_PTR;
-typedef struct _gcsBUFITEM_STRING
-{
-    gceBUFITEM              type;
-    gctINT                  indent;
-    gctCONST_STRING         message;
-    gctPOINTER              messageData;
-    gctUINT                 messageDataSize;
-}
-gcsBUFITEM_STRING;
-
-/* Buffered string (copy of the string is included with the record). */
-typedef struct _gcsBUFITEM_COPY * gcsBUFITEM_COPY_PTR;
-typedef struct _gcsBUFITEM_COPY
-{
-    gceBUFITEM              type;
-    gctINT                  indent;
-    gctPOINTER              messageData;
-    gctUINT                 messageDataSize;
-}
-gcsBUFITEM_COPY;
-
-/* Memory buffer. */
-typedef struct _gcsBUFITEM_BUFFER * gcsBUFITEM_BUFFER_PTR;
-typedef struct _gcsBUFITEM_BUFFER
-{
-    gceBUFITEM              type;
-    gctINT                  indent;
-    gceDUMP_BUFFER          bufferType;
-
-#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
-    gctUINT32               dmaAddress;
-#endif
-
-    gctUINT                 dataSize;
-    gctUINT32               address;
-#if gcdHAVEPREFIX
-    gctPOINTER              prefixData;
-#endif
-}
-gcsBUFITEM_BUFFER;
-
 typedef struct _gcsBUFFERED_OUTPUT * gcsBUFFERED_OUTPUT_PTR;
 typedef struct _gcsBUFFERED_OUTPUT
 {
@@ -414,133 +135,105 @@ typedef struct _gcsBUFFERED_OUTPUT
 #endif
 
 #if gcdSHOW_LINE_NUMBER
-    gctUINT64               lineNumber;
+    gctUINT                 lineNumber;
 #endif
 
     gctINT                  indent;
 
-#if gcdBUFFERED_OUTPUT
-    gctINT                  start;
-    gctINT                  index;
-    gctINT                  count;
-    gctUINT8                buffer[gcdBUFFERED_SIZE];
-#endif
-
     gcsBUFFERED_OUTPUT_PTR  prev;
     gcsBUFFERED_OUTPUT_PTR  next;
 }
 gcsBUFFERED_OUTPUT;
 
-typedef gctUINT (* gcfPRINTSTRING) (
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gcsBUFITEM_HEAD_PTR Item
-    );
-
-typedef gctINT (* gcfGETITEMSIZE) (
-    IN gcsBUFITEM_HEAD_PTR Item
-    );
-
-/******************************************************************************\
-******************************* Private Variables ******************************
-\******************************************************************************/
-
 static gcsBUFFERED_OUTPUT     _outputBuffer[gcdTHREAD_BUFFERS];
 static gcsBUFFERED_OUTPUT_PTR _outputBufferHead = gcvNULL;
 static gcsBUFFERED_OUTPUT_PTR _outputBufferTail = gcvNULL;
 
 /******************************************************************************\
-****************************** Item Size Functions *****************************
+******************************* Printing Functions *****************************
 \******************************************************************************/
 
-#if gcdBUFFERED_OUTPUT
-static gctINT
-_GetTerminatorItemSize(
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
-    return gcmSIZEOF(gcsBUFITEM_HEAD);
-}
-
-static gctINT
-_GetPrefixItemSize(
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
 #if gcdHAVEPREFIX
-    gcsBUFITEM_PREFIX_PTR item = (gcsBUFITEM_PREFIX_PTR) Item;
-    gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
-    return vlen + gcdPREFIX_SIZE;
-#else
-    return gcmSIZEOF(gcsBUFITEM_PREFIX);
-#endif
-}
 
-static gctINT
-_GetStringItemSize(
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
-    gcsBUFITEM_STRING_PTR item = (gcsBUFITEM_STRING_PTR) Item;
-    gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
-    return vlen + item->messageDataSize;
-}
-
-static gctINT
-_GetCopyItemSize(
-    IN gcsBUFITEM_HEAD_PTR Item
+#if gcdSHOW_TIME
+static gcmINLINE gctUINT64
+_GetTime(
+    void
     )
 {
-    gcsBUFITEM_COPY_PTR item = (gcsBUFITEM_COPY_PTR) Item;
-    gctUINT vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
-    return vlen + item->messageDataSize;
+    gctUINT64 time;
+    gckOS_GetProfileTick(&time);
+    return time;
 }
+#    define gcdPREFIX_LEADER        1
+#    define gcdTIMEFORMAT           "%18lld"
+#    define gcdTIMEVALUE            ,_GetTime()
+#  else
+#    define gcdTIMEFORMAT
+#    define gcdTIMEVALUE
+#  endif
 
-static gctINT
-_GetBufferItemSize(
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
-#if gcdHAVEPREFIX
-    gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
-    gctUINT vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
-    return vlen + gcdPREFIX_SIZE + item->dataSize;
-#else
-    gcsBUFITEM_BUFFER_PTR item = (gcsBUFITEM_BUFFER_PTR) Item;
-    return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
-#endif
-}
+#if gcdSHOW_LINE_NUMBER
+#ifndef gcdPREFIX_LEADER
+#      define gcdPREFIX_LEADER      1
+#      define gcdNUMFORMAT          "%8u"
+#    else
+#      define gcdNUMFORMAT          ", %8u"
+#    endif
+#    define gcdNUMVALUE             ,OutputBuffer->lineNumber
+#  else
+#    define gcdNUMFORMAT
+#    define gcdNUMVALUE
+#  endif
 
-static gcfGETITEMSIZE _itemSize[] =
-{
-    _GetTerminatorItemSize,
-    _GetPrefixItemSize,
-    _GetStringItemSize,
-    _GetCopyItemSize,
-    _GetBufferItemSize
-};
-#endif
+#if gcdSHOW_PROCESS_ID
+#ifndef gcdPREFIX_LEADER
+#      define gcdPREFIX_LEADER      1
+#      define gcdPIDFORMAT          "pid=%5u"
+#    else
+#      define gcdPIDFORMAT          ", pid=%5u"
+#    endif
+#    define gcdPIDVALUE             ,gcmkGETPROCESSID()
+#  else
+#    define gcdPIDFORMAT
+#    define gcdPIDVALUE
+#  endif
 
-/******************************************************************************\
-******************************* Printing Functions *****************************
-\******************************************************************************/
+#if gcdSHOW_THREAD_ID
+#ifndef gcdPREFIX_LEADER
+#      define gcdPREFIX_LEADER      1
+#      define gcdTIDFORMAT          "tid=%5u"
+#    else
+#      define gcdTIDFORMAT          ", tid=%5u"
+#    endif
+#    define gcdTIDVALUE             ,gcmkGETTHREADID()
+#  else
+#    define gcdTIDFORMAT
+#    define gcdTIDVALUE
+#  endif
 
-#if gcmIS_DEBUG(gcdDEBUG_TRACE) || gcdBUFFERED_OUTPUT
-static void
-_DirectPrint(
-    gctCONST_STRING Message,
-    ...
+static gctUINT
+_PrintPrefix(
+    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
+    IN char Buffer[],
+    IN gctUINT Size
     )
 {
     gctINT len;
-    char buffer[768];
-    gctARGUMENTS arguments;
 
-    gcmkARGUMENTS_START(arguments, Message);
-    len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), Message, &arguments);
-    gcmkARGUMENTS_END(arguments);
+    /* Format the string. */
+    len = gcmkSPRINTF(Buffer,
+                      Size,
+                      "[" gcdTIMEFORMAT gcdNUMFORMAT gcdPIDFORMAT gcdTIDFORMAT "] "
+                      gcdTIMEVALUE gcdNUMVALUE gcdPIDVALUE gcdTIDVALUE);
 
-    buffer[len] = '\0';
-    gcmkOUTPUT_STRING(buffer);
+    if (len > 0)
+    {
+        Buffer[len] = '\0';
+        return (gctUINT)len;
+    }
+
+    return 0;
 }
 #endif
 
@@ -573,1245 +266,178 @@ _AppendIndent(
     return len;
 }
 
-#if gcdHAVEPREFIX
-static void
-_PrintPrefix(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctPOINTER Data
-    )
-{
-    char buffer[768];
-    gctINT len;
-
-    /* Format the string. */
-    len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, Data);
-    buffer[len] = '\0';
-
-    /* Print the string. */
-    gcmkOUTPUT_STRING(buffer);
-}
-#endif
-
-static void
+static gctUINT
 _PrintString(
     IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
     IN gctINT Indent,
     IN gctCONST_STRING Message,
-    IN gctUINT ArgumentSize,
-    IN gctPOINTER Data
+    IN gctPOINTER Data,
+    IN char Buffer[],
+    IN gctUINT Size
     )
 {
-    char buffer[768];
     gctINT len;
 
     /* Append the indent string. */
-    len = _AppendIndent(Indent, buffer, gcmSIZEOF(buffer));
+    len = _AppendIndent(Indent, Buffer, Size);
 
     /* Format the string. */
-    len += gcmkVSPRINTF(buffer + len, gcmSIZEOF(buffer) - len, Message, Data);
-    buffer[len] = '\0';
+    len += gcmkVSPRINTF(Buffer + len, Size - len, Message, Data);
+    Buffer[len] = '\0';
 
     /* Add end-of-line if missing. */
-    if (buffer[len - 1] != '\n')
+    if (Buffer[len - 1] != '\n')
     {
-        buffer[len++] = '\n';
-        buffer[len] = '\0';
+        Buffer[len++] = '\n';
+        Buffer[len] = '\0';
     }
 
-    /* Print the string. */
-    gcmkOUTPUT_STRING(buffer);
+    return (gctUINT)len;
 }
 
-static void
-_PrintBuffer(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctINT Indent,
-    IN gctPOINTER PrefixData,
-    IN gctPOINTER Data,
-    IN gctUINT Address,
-    IN gctSIZE_T DataSize,
-    IN gceDUMP_BUFFER Type,
-    IN gctUINT32 DmaAddress
+/******************************************************************************\
+******************************* Private Functions ******************************
+\******************************************************************************/
+
+static gcmINLINE void
+_InitBuffers(
+    void
     )
 {
-    static gctCONST_STRING _titleString[] =
-    {
-        "CONTEXT BUFFER",
-        "USER COMMAND BUFFER",
-        "KERNEL COMMAND BUFFER",
-        "LINK BUFFER",
-        "WAIT LINK BUFFER",
-        ""
-    };
-
-    static const gctINT COLUMN_COUNT = 8;
-
-    gctUINT i, column, address;
-    gctSIZE_T count;
-    gctUINT32_PTR data;
-    gctCHAR buffer[768];
-    gctUINT indent, len;
-    gctBOOL command;
-
-    /* Append space for the prefix. */
-#if gcdHAVEPREFIX
-    indent = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer), _prefixFormat, PrefixData);
-    buffer[indent] = '\0';
-#else
-    indent = 0;
-#endif
-
-    /* Append the indent string. */
-    indent += _AppendIndent(
-        Indent, buffer + indent, gcmSIZEOF(buffer) - indent
-        );
+    int i;
 
-    switch (Type)
+    if (_outputBufferHead == gcvNULL)
     {
-    case gcvDUMP_BUFFER_CONTEXT:
-    case gcvDUMP_BUFFER_USER:
-    case gcvDUMP_BUFFER_KERNEL:
-    case gcvDUMP_BUFFER_LINK:
-    case gcvDUMP_BUFFER_WAITLINK:
-        /* Form and print the title string. */
-        gcmkSPRINTF2(
-            buffer + indent, gcmSIZEOF(buffer) - indent,
-            "%s%s\n", _titleString[Type],
-            ((DmaAddress >= Address) && (DmaAddress < Address + DataSize))
-                ? " (CURRENT)" : ""
-            );
-
-        gcmkOUTPUT_STRING(buffer);
+        for (i = 0; i < gcdTHREAD_BUFFERS; i += 1)
+        {
+            if (_outputBufferTail == gcvNULL)
+            {
+                _outputBufferHead = &_outputBuffer[i];
+            }
+            else
+            {
+                _outputBufferTail->next = &_outputBuffer[i];
+            }
 
-        /* Terminate the string. */
-        buffer[indent] = '\0';
+#if gcdTHREAD_BUFFERS > 1
+            _outputBuffer[i].threadID = ~0U;
+#endif
 
-        /* This is a command buffer. */
-        command = gcvTRUE;
-        break;
+            _outputBuffer[i].prev = _outputBufferTail;
+            _outputBuffer[i].next =  gcvNULL;
 
-    case gcvDUMP_BUFFER_FROM_USER:
-        /* This is not a command buffer. */
-        command = gcvFALSE;
+            _outputBufferTail = &_outputBuffer[i];
+        }
+    }
+}
 
-        /* No title. */
-        break;
+static gcmINLINE gcsBUFFERED_OUTPUT_PTR
+_GetOutputBuffer(
+    void
+    )
+{
+    gcsBUFFERED_OUTPUT_PTR outputBuffer;
 
-    default:
-        gcmDBGASSERT(gcvFALSE, "%s", "invalid buffer type");
+#if gcdTHREAD_BUFFERS > 1
+    /* Get the current thread ID. */
+    gctUINT32 ThreadID = gcmkGETTHREADID();
 
-        /* This is not a command buffer. */
-        command = gcvFALSE;
-    }
+    /* Locate the output buffer for the thread. */
+    outputBuffer = _outputBufferHead;
 
-    /* Overwrite the prefix with spaces. */
-    for (i = 0; i < indent; i += 1)
+    while (outputBuffer != gcvNULL)
     {
-        buffer[i] = ' ';
+        if (outputBuffer->threadID == ThreadID)
+        {
+            break;
+        }
+
+        outputBuffer = outputBuffer->next;
     }
 
-    /* Form and print the opening string. */
-    if (command)
+    /* No matching buffer found? */
+    if (outputBuffer == gcvNULL)
     {
-        gcmkSPRINTF2(
-            buffer + indent, gcmSIZEOF(buffer) - indent,
-            "@[kernel.command %08X %08X\n", Address, (gctUINT32)DataSize
-            );
+        /* Get the tail for the buffer. */
+        outputBuffer = _outputBufferTail;
 
-        gcmkOUTPUT_STRING(buffer);
+        /* Move it to the head. */
+        _outputBufferTail       = _outputBufferTail->prev;
+        _outputBufferTail->next = gcvNULL;
 
-        /* Terminate the string. */
-        buffer[indent] = '\0';
-    }
+        outputBuffer->prev = gcvNULL;
+        outputBuffer->next = _outputBufferHead;
 
-    /* Get initial address. */
-    address = Address;
+        _outputBufferHead->prev = outputBuffer;
+        _outputBufferHead       = outputBuffer;
 
-    /* Cast the data pointer. */
-    data = (gctUINT32_PTR) Data;
+        /* Reset the buffer. */
+        outputBuffer->threadID   = ThreadID;
+#if gcdSHOW_LINE_NUMBER
+        outputBuffer->lineNumber = 0;
+#  endif
+    }
+#else
+    outputBuffer = _outputBufferHead;
+#endif
 
-    /* Compute the number of double words. */
-    count = DataSize / gcmSIZEOF(gctUINT32);
+    return outputBuffer;
+}
 
-    /* Print the buffer. */
-    for (i = 0, len = indent, column = 0; i < count; i += 1)
-    {
-        /* Append the address. */
-        if (column == 0)
-        {
-            len += gcmkSPRINTF(
-                buffer + len, gcmSIZEOF(buffer) - len, "0x%08X:", address
-                );
-        }
+static void
+_Print(
+    IN gctCONST_STRING Message,
+    IN gctARGUMENTS * Arguments
+    )
+{
+    gcsBUFFERED_OUTPUT_PTR outputBuffer;
+    char buffer[256];
+    char *ptr = buffer;
+    gctINT len = 0;
+    static gcmkDECLARE_MUTEX(printMutex);
 
-        /* Append the data value. */
-        len += gcmkSPRINTF2(
-            buffer + len, gcmSIZEOF(buffer) - len, "%c%08X",
-            (address == DmaAddress)? '>' : ' ', data[i]
-            );
+    gcmkMUTEX_LOCK(printMutex);
 
-        buffer[len] = '\0';
+    /* Initialize output buffer list. */
+    _InitBuffers();
 
-        /* Update the address. */
-        address += gcmSIZEOF(gctUINT32);
+    /* Locate the proper output buffer. */
+    outputBuffer = _GetOutputBuffer();
 
-        /* Advance column count. */
-        column += 1;
+    /* Print prefix. */
+#if gcdHAVEPREFIX
+#if gcdSHOW_LINE_NUMBER
+    /* Update the line number. */
+    outputBuffer->lineNumber += 1;
+#  endif
 
-        /* End of line? */
-        if ((column % COLUMN_COUNT) == 0)
-        {
-            /* Append EOL. */
-            gcmkSTRCATSAFE(buffer, gcmSIZEOF(buffer), "\n");
-
-            /* Print the string. */
-            gcmkOUTPUT_STRING(buffer);
-
-            /* Reset. */
-            len    = indent;
-            column = 0;
-        }
-    }
-
-    /* Print the last partial string. */
-    if (column != 0)
-    {
-        /* Append EOL. */
-        gcmkSTRCATSAFE(buffer, gcmSIZEOF(buffer), "\n");
-
-        /* Print the string. */
-        gcmkOUTPUT_STRING(buffer);
-    }
-
-    /* Form and print the opening string. */
-    if (command)
-    {
-        buffer[indent] = '\0';
-        gcmkSTRCATSAFE(buffer, gcmSIZEOF(buffer), "] -- command\n");
-        gcmkOUTPUT_STRING(buffer);
-    }
-}
-
-#if gcdBUFFERED_OUTPUT
-static gctUINT
-_PrintNone(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
-    /* Return the size of the node. */
-    return gcmSIZEOF(gcsBUFITEM_HEAD);
-}
-
-static gctUINT
-_PrintPrefixWrapper(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
-#if gcdHAVEPREFIX
-    gcsBUFITEM_PREFIX_PTR item;
-    gctUINT vlen;
-
-    /* Get access to the data. */
-    item = (gcsBUFITEM_PREFIX_PTR) Item;
-
-    /* Print the message. */
-    _PrintPrefix(OutputBuffer, item->prefixData);
-
-    /* Compute the size of the variable portion of the structure. */
-    vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
-
-    /* Return the size of the node. */
-    return vlen + gcdPREFIX_SIZE;
-#else
-    return gcmSIZEOF(gcsBUFITEM_PREFIX);
-#endif
-}
-
-static gctUINT
-_PrintStringWrapper(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
-    gcsBUFITEM_STRING_PTR item;
-    gctUINT vlen;
-
-    /* Get access to the data. */
-    item = (gcsBUFITEM_STRING_PTR) Item;
-
-    /* Print the message. */
-    _PrintString(
-        OutputBuffer,
-        item->indent, item->message, item->messageDataSize, item->messageData
-        );
-
-    /* Compute the size of the variable portion of the structure. */
-    vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
-
-    /* Return the size of the node. */
-    return vlen + item->messageDataSize;
-}
-
-static gctUINT
-_PrintCopyWrapper(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
-    gcsBUFITEM_COPY_PTR item;
-    gctCONST_STRING message;
-    gctUINT vlen;
-
-    /* Get access to the data. */
-    item = (gcsBUFITEM_COPY_PTR) Item;
-
-    /* Determine the string pointer. */
-    message = (gctCONST_STRING) (item + 1);
-
-    /* Print the message. */
-    _PrintString(
-        OutputBuffer,
-        item->indent, message, item->messageDataSize, item->messageData
-        );
-
-    /* Compute the size of the variable portion of the structure. */
-    vlen = ((gctUINT8_PTR) item->messageData) - ((gctUINT8_PTR) item);
-
-    /* Return the size of the node. */
-    return vlen + item->messageDataSize;
-}
-
-static gctUINT
-_PrintBufferWrapper(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gcsBUFITEM_HEAD_PTR Item
-    )
-{
-#if gcdHAVEPREFIX
-    gctUINT32 dmaAddress;
-    gcsBUFITEM_BUFFER_PTR item;
-    gctPOINTER data;
-    gctUINT vlen;
-
-    /* Get access to the data. */
-    item = (gcsBUFITEM_BUFFER_PTR) Item;
-
-#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
-    dmaAddress = item->dmaAddress;
-#else
-    dmaAddress = 0xFFFFFFFF;
-#endif
-
-    if (dmaAddress != 0)
-    {
-        /* Compute the data address. */
-        data = ((gctUINT8_PTR) item->prefixData) + gcdPREFIX_SIZE;
-
-        /* Print buffer. */
-        _PrintBuffer(
-            OutputBuffer,
-            item->indent, item->prefixData,
-            data, item->address, item->dataSize,
-            item->bufferType, dmaAddress
-            );
-    }
-
-    /* Compute the size of the variable portion of the structure. */
-    vlen = ((gctUINT8_PTR) item->prefixData) - ((gctUINT8_PTR) item);
-
-    /* Return the size of the node. */
-    return vlen + gcdPREFIX_SIZE + item->dataSize;
-#else
-    gctUINT32 dmaAddress;
-    gcsBUFITEM_BUFFER_PTR item;
-
-    /* Get access to the data. */
-    item = (gcsBUFITEM_BUFFER_PTR) Item;
-
-#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
-    dmaAddress = item->dmaAddress;
-#else
-    dmaAddress = 0xFFFFFFFF;
-#endif
-
-    if (dmaAddress != 0)
-    {
-        /* Print buffer. */
-        _PrintBuffer(
-            OutputBuffer,
-            item->indent, gcvNULL,
-            item + 1, item->address, item->dataSize,
-            item->bufferType, dmaAddress
-            );
-    }
-
-    /* Return the size of the node. */
-    return gcmSIZEOF(gcsBUFITEM_BUFFER) + item->dataSize;
-#endif
-}
-
-static gcfPRINTSTRING _printArray[] =
-{
-    _PrintNone,
-    _PrintPrefixWrapper,
-    _PrintStringWrapper,
-    _PrintCopyWrapper,
-    _PrintBufferWrapper
-};
-#endif
-
-/******************************************************************************\
-******************************* Private Functions ******************************
-\******************************************************************************/
-
-#if gcdBUFFERED_OUTPUT
-
-#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
-static gcsBUFITEM_BUFFER_PTR
-_FindCurrentDMABuffer(
-    gctUINT32 DmaAddress
-    )
-{
-    gctINT i, skip;
-    gcsBUFITEM_HEAD_PTR item;
-    gcsBUFITEM_BUFFER_PTR dmaCurrent;
-
-    /* Reset the current buffer. */
-    dmaCurrent = gcvNULL;
-
-    /* Get the first stored item. */
-    item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
-
-    /* Run through all items. */
-    for (i = 0; i < _outputBufferHead->count; i += 1)
-    {
-        /* Buffer item? */
-        if (item->type == gcvBUFITEM_BUFFER)
-        {
-            gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
-
-            if ((DmaAddress >= buffer->address) &&
-                (DmaAddress <  buffer->address + buffer->dataSize))
-            {
-                dmaCurrent = buffer;
-            }
-        }
-
-        /* Get the item size and skip it. */
-        skip = (* _itemSize[item->type]) (item);
-        item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
-
-        /* End of the buffer? Wrap around. */
-        if (item->type == gceBUFITEM_NONE)
-        {
-            item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
-        }
-    }
-
-    /* Return result. */
-    return dmaCurrent;
-}
-
-static void
-_EnableAllDMABuffers(
-    void
-    )
-{
-    gctINT i, skip;
-    gcsBUFITEM_HEAD_PTR item;
-
-    /* Get the first stored item. */
-    item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
-
-    /* Run through all items. */
-    for (i = 0; i < _outputBufferHead->count; i += 1)
-    {
-        /* Buffer item? */
-        if (item->type == gcvBUFITEM_BUFFER)
-        {
-            gcsBUFITEM_BUFFER_PTR buffer = (gcsBUFITEM_BUFFER_PTR) item;
-
-            /* Enable the buffer. */
-            buffer->dmaAddress = ~0U;
-        }
-
-        /* Get the item size and skip it. */
-        skip = (* _itemSize[item->type]) (item);
-        item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
-
-        /* End of the buffer? Wrap around. */
-        if (item->type == gceBUFITEM_NONE)
-        {
-            item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
-        }
-    }
-}
-
-static void
-_EnableDMABuffers(
-    gctUINT32 DmaAddress,
-    gcsBUFITEM_BUFFER_PTR CurrentDMABuffer
-    )
-{
-    gctINT i, skip, index;
-    gcsBUFITEM_HEAD_PTR item;
-    gcsBUFITEM_BUFFER_PTR buffers[gcdDMA_BUFFER_COUNT];
-
-    /* Reset buffer pointers. */
-    gckOS_ZeroMemory(buffers, gcmSIZEOF(buffers));
-
-    /* Set the current buffer index. */
-    index = -1;
-
-    /* Get the first stored item. */
-    item = (gcsBUFITEM_HEAD_PTR) &_outputBufferHead->buffer[_outputBufferHead->start];
-
-    /* Run through all items until the current DMA buffer is found. */
-    for (i = 0; i < _outputBufferHead->count; i += 1)
-    {
-        /* Buffer item? */
-        if (item->type == gcvBUFITEM_BUFFER)
-        {
-            /* Advance the index. */
-            index = (index + 1) % gcdDMA_BUFFER_COUNT;
-
-            /* Add to the buffer array. */
-            buffers[index] = (gcsBUFITEM_BUFFER_PTR) item;
-
-            /* Stop if this is the current DMA buffer. */
-            if ((gcsBUFITEM_BUFFER_PTR) item == CurrentDMABuffer)
-            {
-                break;
-            }
-        }
-
-        /* Get the item size and skip it. */
-        skip = (* _itemSize[item->type]) (item);
-        item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
-
-        /* End of the buffer? Wrap around. */
-        if (item->type == gceBUFITEM_NONE)
-        {
-            item = (gcsBUFITEM_HEAD_PTR) _outputBufferHead->buffer;
-        }
-    }
-
-    /* Enable the found buffers. */
-    gcmDBGASSERT(index != -1, "%d", index);
-
-    for (i = 0; i < gcdDMA_BUFFER_COUNT; i += 1)
-    {
-        if (buffers[index] == gcvNULL)
-        {
-            break;
-        }
-
-        buffers[index]->dmaAddress = DmaAddress;
-
-        index -= 1;
-
-        if (index == -1)
-        {
-            index = gcdDMA_BUFFER_COUNT - 1;
-        }
-    }
-}
-#endif
-
-static void
-_Flush(
-    gctUINT32 DmaAddress
-    )
-{
-    gctINT i, skip;
-    gcsBUFITEM_HEAD_PTR item;
-
-    gcsBUFFERED_OUTPUT_PTR outputBuffer = _outputBufferHead;
-
-#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
-    if ((outputBuffer != gcvNULL) && (outputBuffer->count != 0))
-    {
-        /* Find the current DMA buffer. */
-        gcsBUFITEM_BUFFER_PTR dmaCurrent = _FindCurrentDMABuffer(DmaAddress);
-
-        /* Was the current buffer found? */
-        if (dmaCurrent == gcvNULL)
-        {
-            /* No, print all buffers. */
-            _EnableAllDMABuffers();
-        }
-        else
-        {
-            /* Yes, enable only specified number of buffers. */
-            _EnableDMABuffers(DmaAddress, dmaCurrent);
-        }
-    }
-#endif
-
-    while (outputBuffer != gcvNULL)
-    {
-        if (outputBuffer->count != 0)
-        {
-            _DirectPrint("********************************************************************************\n");
-            _DirectPrint("FLUSHING DEBUG OUTPUT BUFFER (%d elements).\n", outputBuffer->count);
-            _DirectPrint("********************************************************************************\n");
-
-            item = (gcsBUFITEM_HEAD_PTR) &outputBuffer->buffer[outputBuffer->start];
-
-            for (i = 0; i < outputBuffer->count; i += 1)
-            {
-                skip = (* _printArray[item->type]) (outputBuffer, item);
-
-                item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
-
-                if (item->type == gceBUFITEM_NONE)
-                {
-                    item = (gcsBUFITEM_HEAD_PTR) outputBuffer->buffer;
-                }
-            }
-
-            outputBuffer->start = 0;
-            outputBuffer->index = 0;
-            outputBuffer->count = 0;
-        }
-
-        outputBuffer = outputBuffer->next;
-    }
-}
-
-static gcsBUFITEM_HEAD_PTR
-_AllocateItem(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctINT Size
-    )
-{
-    gctINT skip;
-    gcsBUFITEM_HEAD_PTR item, next;
-
-#if gcdENABLE_OVERFLOW
-    if (
-            (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
-            ||
-            (
-                (OutputBuffer->index        <  OutputBuffer->start) &&
-                (OutputBuffer->index + Size >= OutputBuffer->start)
-            )
-    )
-    {
-        if (OutputBuffer->index + Size >= gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
-        {
-            if (OutputBuffer->index < OutputBuffer->start)
-            {
-                item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
-
-                while (item->type != gceBUFITEM_NONE)
-                {
-                    skip = (* _itemSize[item->type]) (item);
-
-                    OutputBuffer->start += skip;
-                    OutputBuffer->count -= 1;
-
-                    item->type = gceBUFITEM_NONE;
-                    item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
-                }
-
-                OutputBuffer->start = 0;
-            }
-
-            OutputBuffer->index = 0;
-        }
-
-        item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->start];
-
-        while (OutputBuffer->start - OutputBuffer->index <= Size)
-        {
-            skip = (* _itemSize[item->type]) (item);
-
-            OutputBuffer->start += skip;
-            OutputBuffer->count -= 1;
-
-            item->type = gceBUFITEM_NONE;
-            item = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + skip);
-
-            if (item->type == gceBUFITEM_NONE)
-            {
-                OutputBuffer->start = 0;
-                break;
-            }
-        }
-    }
-#else
-    if (OutputBuffer->index + Size > gcdBUFFERED_SIZE - gcmSIZEOF(gcsBUFITEM_HEAD))
-    {
-        _DirectPrint("\nMessage buffer full; forcing message flush.\n\n");
-        _Flush(~0U);
-    }
-#endif
-
-    item = (gcsBUFITEM_HEAD_PTR) &OutputBuffer->buffer[OutputBuffer->index];
-
-    OutputBuffer->index += Size;
-    OutputBuffer->count += 1;
-
-    next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) item + Size);
-    next->type = gceBUFITEM_NONE;
-
-    return item;
-}
-
-#if gcdALIGNBYSIZE
-static void
-_FreeExtraSpace(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctPOINTER Item,
-    IN gctINT ItemSize,
-    IN gctINT FreeSize
-    )
-{
-    gcsBUFITEM_HEAD_PTR next;
-
-    OutputBuffer->index -= FreeSize;
-
-    next = (gcsBUFITEM_HEAD_PTR) ((gctUINT8_PTR) Item + ItemSize);
-    next->type = gceBUFITEM_NONE;
-}
-#endif
-
-#if gcdHAVEPREFIX
-static void
-_AppendPrefix(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctPOINTER Data
-    )
-{
-    gctUINT8_PTR prefixData;
-    gcsBUFITEM_PREFIX_PTR item;
-    gctINT allocSize;
-
-#if gcdALIGNBYSIZE
-    gctUINT alignment;
-    gctINT size, freeSize;
-#endif
-
-    gcmDBGASSERT(Data != gcvNULL, "%p", Data);
-
-    /* Determine the maximum item size. */
-    allocSize
-        = gcmSIZEOF(gcsBUFITEM_PREFIX)
-        + gcdPREFIX_SIZE
-        + gcdPREFIX_ALIGNMENT;
-
-    /* Allocate prefix item. */
-    item = (gcsBUFITEM_PREFIX_PTR) _AllocateItem(OutputBuffer, allocSize);
-
-    /* Compute the initial prefix data pointer. */
-    prefixData = (gctUINT8_PTR) (item + 1);
-
-    /* Align the data pointer as necessary. */
-#if gcdALIGNBYSIZE
-    alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
-    prefixData += alignment;
-#endif
-
-    /* Set item data. */
-    item->type       = gcvBUFITEM_PREFIX;
-    item->prefixData = prefixData;
-
-    /* Copy argument value. */
-    gcmkMEMCPY(prefixData, Data, gcdPREFIX_SIZE);
-
-#if gcdALIGNBYSIZE
-    /* Compute the actual node size. */
-    size = gcmSIZEOF(gcsBUFITEM_PREFIX) + gcdPREFIX_SIZE + alignment;
-
-    /* Free extra memory if any. */
-    freeSize = allocSize - size;
-    if (freeSize != 0)
-    {
-        _FreeExtraSpace(OutputBuffer, item, size, freeSize);
-    }
-#endif
-}
-#endif
-
-static void
-_AppendString(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctINT Indent,
-    IN gctCONST_STRING Message,
-    IN gctUINT ArgumentSize,
-    IN gctPOINTER Data
-    )
-{
-    gctUINT8_PTR messageData;
-    gcsBUFITEM_STRING_PTR item;
-    gctINT allocSize;
-
-#if gcdALIGNBYSIZE
-    gctUINT alignment;
-    gctINT size, freeSize;
-#endif
-
-    /* Determine the maximum item size. */
-    allocSize
-        = gcmSIZEOF(gcsBUFITEM_STRING)
-        + ArgumentSize
-        + gcdVARARG_ALIGNMENT;
-
-    /* Allocate prefix item. */
-    item = (gcsBUFITEM_STRING_PTR) _AllocateItem(OutputBuffer, allocSize);
-
-    /* Compute the initial message data pointer. */
-    messageData = (gctUINT8_PTR) (item + 1);
-
-    /* Align the data pointer as necessary. */
-#if gcdALIGNBYSIZE
-    alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
-    messageData += alignment;
-#endif
-
-    /* Set item data. */
-    item->type            = gcvBUFITEM_STRING;
-    item->indent          = Indent;
-    item->message         = Message;
-    item->messageData     = messageData;
-    item->messageDataSize = ArgumentSize;
-
-    /* Copy argument value. */
-    if (ArgumentSize != 0)
-    {
-        gcmkMEMCPY(messageData, Data, ArgumentSize);
-    }
-
-#if gcdALIGNBYSIZE
-    /* Compute the actual node size. */
-    size = gcmSIZEOF(gcsBUFITEM_STRING) + ArgumentSize + alignment;
-
-    /* Free extra memory if any. */
-    freeSize = allocSize - size;
-    if (freeSize != 0)
-    {
-        _FreeExtraSpace(OutputBuffer, item, size, freeSize);
-    }
-#endif
-}
-
-static void
-_AppendCopy(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctINT Indent,
-    IN gctCONST_STRING Message,
-    IN gctUINT ArgumentSize,
-    IN gctPOINTER Data
-    )
-{
-    gctUINT8_PTR messageData;
-    gcsBUFITEM_COPY_PTR item;
-    gctINT allocSize;
-    gctINT messageLength;
-    gctCONST_STRING message;
-
-#if gcdALIGNBYSIZE
-    gctUINT alignment;
-    gctINT size, freeSize;
-#endif
-
-    /* Get the length of the string. */
-    messageLength = strlen(Message) + 1;
-
-    /* Determine the maximum item size. */
-    allocSize
-        = gcmSIZEOF(gcsBUFITEM_COPY)
-        + messageLength
-        + ArgumentSize
-        + gcdVARARG_ALIGNMENT;
-
-    /* Allocate prefix item. */
-    item = (gcsBUFITEM_COPY_PTR) _AllocateItem(OutputBuffer, allocSize);
-
-    /* Determine the message placement. */
-    message = (gctCONST_STRING) (item + 1);
-
-    /* Compute the initial message data pointer. */
-    messageData = (gctUINT8_PTR) message + messageLength;
-
-    /* Align the data pointer as necessary. */
-#if gcdALIGNBYSIZE
-    if (ArgumentSize == 0)
-    {
-        alignment = 0;
-    }
-    else
-    {
-        alignment = gcmPTRALIGNMENT(messageData, gcdVARARG_ALIGNMENT);
-        messageData += alignment;
-    }
-#endif
-
-    /* Set item data. */
-    item->type            = gcvBUFITEM_COPY;
-    item->indent          = Indent;
-    item->messageData     = messageData;
-    item->messageDataSize = ArgumentSize;
-
-    /* Copy the message. */
-    gcmkMEMCPY((gctPOINTER) message, Message, messageLength);
-
-    /* Copy argument value. */
-    if (ArgumentSize != 0)
-    {
-        gcmkMEMCPY(messageData, Data, ArgumentSize);
-    }
-
-#if gcdALIGNBYSIZE
-    /* Compute the actual node size. */
-    size
-        = gcmSIZEOF(gcsBUFITEM_COPY)
-        + messageLength
-        + ArgumentSize
-        + alignment;
-
-    /* Free extra memory if any. */
-    freeSize = allocSize - size;
-    if (freeSize != 0)
-    {
-        _FreeExtraSpace(OutputBuffer, item, size, freeSize);
-    }
-#endif
-}
-
-static void
-_AppendBuffer(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctINT Indent,
-    IN gctPOINTER PrefixData,
-    IN gctPOINTER Data,
-    IN gctUINT Address,
-    IN gctUINT DataSize,
-    IN gceDUMP_BUFFER Type,
-    IN gctUINT32 DmaAddress
-    )
-{
-#if gcdHAVEPREFIX
-    gctUINT8_PTR prefixData;
-    gcsBUFITEM_BUFFER_PTR item;
-    gctINT allocSize;
-    gctPOINTER data;
-
-#if gcdALIGNBYSIZE
-    gctUINT alignment;
-    gctINT size, freeSize;
-#endif
-
-    gcmDBGASSERT(DataSize != 0, "%d", DataSize);
-    gcmDBGASSERT(Data != gcvNULL, "%p", Data);
-
-    /* Determine the maximum item size. */
-    allocSize
-        = gcmSIZEOF(gcsBUFITEM_BUFFER)
-        + gcdPREFIX_SIZE
-        + gcdPREFIX_ALIGNMENT
-        + DataSize;
-
-    /* Allocate prefix item. */
-    item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, allocSize);
-
-    /* Compute the initial prefix data pointer. */
-    prefixData = (gctUINT8_PTR) (item + 1);
-
-#if gcdALIGNBYSIZE
-    /* Align the data pointer as necessary. */
-    alignment = gcmPTRALIGNMENT(prefixData, gcdPREFIX_ALIGNMENT);
-    prefixData += alignment;
-#endif
-
-    /* Set item data. */
-    item->type       = gcvBUFITEM_BUFFER;
-    item->indent     = Indent;
-    item->bufferType = Type;
-    item->dataSize   = DataSize;
-    item->address    = Address;
-    item->prefixData = prefixData;
-
-#if gcdDMA_BUFFER_COUNT && (gcdTHREAD_BUFFERS == 1)
-    item->dmaAddress = DmaAddress;
-#endif
-
-    /* Copy prefix data. */
-    gcmkMEMCPY(prefixData, PrefixData, gcdPREFIX_SIZE);
-
-    /* Compute the data pointer. */
-    data = prefixData + gcdPREFIX_SIZE;
-
-    /* Copy argument value. */
-    gcmkMEMCPY(data, Data, DataSize);
-
-#if gcdALIGNBYSIZE
-    /* Compute the actual node size. */
-    size
-        = gcmSIZEOF(gcsBUFITEM_BUFFER)
-        + gcdPREFIX_SIZE
-        + alignment
-        + DataSize;
-
-    /* Free extra memory if any. */
-    freeSize = allocSize - size;
-    if (freeSize != 0)
-    {
-        _FreeExtraSpace(OutputBuffer, item, size, freeSize);
-    }
-#endif
-#else
-    gcsBUFITEM_BUFFER_PTR item;
-    gctINT size;
-
-    gcmDBGASSERT(DataSize != 0, "%d", DataSize);
-    gcmDBGASSERT(Data != gcvNULL, "%p", Data);
-
-    /* Determine the maximum item size. */
-    size = gcmSIZEOF(gcsBUFITEM_BUFFER) + DataSize;
-
-    /* Allocate prefix item. */
-    item = (gcsBUFITEM_BUFFER_PTR) _AllocateItem(OutputBuffer, size);
-
-    /* Set item data. */
-    item->type     = gcvBUFITEM_BUFFER;
-    item->indent   = Indent;
-    item->dataSize = DataSize;
-    item->address  = Address;
-
-    /* Copy argument value. */
-    gcmkMEMCPY(item + 1, Data, DataSize);
-#endif
-}
-#endif
-
-static gcmINLINE void
-_InitBuffers(
-    void
-    )
-{
-    int i;
-
-    if (_outputBufferHead == gcvNULL)
-    {
-        for (i = 0; i < gcdTHREAD_BUFFERS; i += 1)
-        {
-            if (_outputBufferTail == gcvNULL)
-            {
-                _outputBufferHead = &_outputBuffer[i];
-            }
-            else
-            {
-                _outputBufferTail->next = &_outputBuffer[i];
-            }
-
-#if gcdTHREAD_BUFFERS > 1
-            _outputBuffer[i].threadID = ~0U;
-#endif
-
-            _outputBuffer[i].prev = _outputBufferTail;
-            _outputBuffer[i].next =  gcvNULL;
-
-            _outputBufferTail = &_outputBuffer[i];
-        }
-    }
-}
-
-static gcmINLINE gcsBUFFERED_OUTPUT_PTR
-_GetOutputBuffer(
-    void
-    )
-{
-    gcsBUFFERED_OUTPUT_PTR outputBuffer;
-
-#if gcdTHREAD_BUFFERS > 1
-    /* Get the current thread ID. */
-    gctUINT32 ThreadID = gcmkGETTHREADID();
-
-    /* Locate the output buffer for the thread. */
-    outputBuffer = _outputBufferHead;
-
-    while (outputBuffer != gcvNULL)
-    {
-        if (outputBuffer->threadID == ThreadID)
-        {
-            break;
-        }
-
-        outputBuffer = outputBuffer->next;
-    }
-
-    /* No matching buffer found? */
-    if (outputBuffer == gcvNULL)
-    {
-        /* Get the tail for the buffer. */
-        outputBuffer = _outputBufferTail;
-
-        /* Move it to the head. */
-        _outputBufferTail       = _outputBufferTail->prev;
-        _outputBufferTail->next = gcvNULL;
-
-        outputBuffer->prev = gcvNULL;
-        outputBuffer->next = _outputBufferHead;
-
-        _outputBufferHead->prev = outputBuffer;
-        _outputBufferHead       = outputBuffer;
-
-        /* Reset the buffer. */
-        outputBuffer->threadID   = ThreadID;
-#if gcdBUFFERED_OUTPUT
-        outputBuffer->start      = 0;
-        outputBuffer->index      = 0;
-        outputBuffer->count      = 0;
-#endif
-#if gcdSHOW_LINE_NUMBER
-        outputBuffer->lineNumber = 0;
-#endif
-    }
-#else
-    outputBuffer = _outputBufferHead;
-#endif
-
-    return outputBuffer;
-}
-
-static gcmINLINE int _GetArgumentSize(
-    IN gctCONST_STRING Message
-    )
-{
-    int i, count;
-
-    gcmDBGASSERT(Message != gcvNULL, "%p", Message);
-
-    for (i = 0, count = 0; Message[i]; i += 1)
-    {
-        if (Message[i] == '%')
-        {
-            count += 1;
-        }
-    }
-
-    return count * gcmSIZEOF(gctUINT32);
-}
-
-#if gcdHAVEPREFIX
-static void
-_InitPrefixData(
-    IN gcsBUFFERED_OUTPUT_PTR OutputBuffer,
-    IN gctPOINTER Data
-    )
-{
-    gctUINT8_PTR data  = (gctUINT8_PTR) Data;
-
-#if gcdSHOW_TIME
-    {
-        gctUINT64 time;
-        gckOS_GetProfileTick(&time);
-        gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
-        * ((gctUINT64_PTR) data) = time;
-        data += gcmSIZEOF(gctUINT64);
-    }
-#endif
-
-#if gcdSHOW_LINE_NUMBER
-    {
-        gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT64));
-        * ((gctUINT64_PTR) data) = OutputBuffer->lineNumber;
-        data += gcmSIZEOF(gctUINT64);
-    }
-#endif
-
-#if gcdSHOW_PROCESS_ID
-    {
-        gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
-        * ((gctUINT32_PTR) data) = gcmkGETPROCESSID();
-        data += gcmSIZEOF(gctUINT32);
-    }
-#endif
-
-#if gcdSHOW_THREAD_ID
-    {
-        gcmkALIGNPTR(gctUINT8_PTR, data, gcmSIZEOF(gctUINT32));
-        * ((gctUINT32_PTR) data) = gcmkGETTHREADID();
-    }
-#endif
-}
-#endif
-
-static void
-_Print(
-    IN gctUINT ArgumentSize,
-    IN gctBOOL CopyMessage,
-    IN gctCONST_STRING Message,
-    IN gctARGUMENTS * Arguments
-    )
-{
-    gcsBUFFERED_OUTPUT_PTR outputBuffer;
-    static gcmkDECLARE_MUTEX(lockHandle);
-
-    gcmkMUTEX_LOCK(lockHandle);
-
-    /* Initialize output buffer list. */
-    _InitBuffers();
-
-    /* Locate the proper output buffer. */
-    outputBuffer = _GetOutputBuffer();
-
-    /* Update the line number. */
-#if gcdSHOW_LINE_NUMBER
-    outputBuffer->lineNumber += 1;
-#endif
-
-    /* Print prefix. */
-#if gcdHAVEPREFIX
-    {
-        gctUINT8_PTR alignedPrefixData;
-        gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
-
-        /* Compute aligned pointer. */
-        alignedPrefixData = prefixData;
-        gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
-
-        /* Initialize the prefix data. */
-        _InitPrefixData(outputBuffer, alignedPrefixData);
-
-        /* Print the prefix. */
-        gcdOUTPUTPREFIX(outputBuffer, alignedPrefixData);
-    }
+    /* Print the prefix. */
+    len = _PrintPrefix(outputBuffer, buffer, gcmSIZEOF(buffer));
+    ptr += len;
 #endif
 
     /* Form the indent string. */
-    if (strncmp(Message, "--", 2) == 0)
+    if (Message[0] == '-' && Message[1] == '-')
     {
         outputBuffer->indent -= 2;
     }
 
     /* Print the message. */
-    if (CopyMessage)
-    {
-        gcdOUTPUTCOPY(
-            outputBuffer, outputBuffer->indent,
-            Message, ArgumentSize, (gctPOINTER) Arguments
-            );
-    }
-    else
-    {
-        gcdOUTPUTSTRING(
-            outputBuffer, outputBuffer->indent,
-            Message, ArgumentSize, ((gctPOINTER) Arguments)
-            );
-    }
+    len += _PrintString(
+        outputBuffer, outputBuffer->indent,
+        Message, ((gctPOINTER) Arguments),
+        ptr, gcmSIZEOF(buffer) - outputBuffer->indent - len
+        );
+
+    gcmkOUTPUT_STRING(buffer);
 
     /* Check increasing indent. */
-    if (strncmp(Message, "++", 2) == 0)
+    if (Message[0] == '+' && Message[1] == '+')
     {
         outputBuffer->indent += 2;
     }
 
-    gcmkMUTEX_UNLOCK(lockHandle);
+    gcmkMUTEX_UNLOCK(printMutex);
 }
 
 
@@ -1823,321 +449,48 @@ _Print(
 
 extern volatile unsigned g_nQnxInIsrs;
 
-#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
+#define gcmDEBUGPRINT(Message) \
 { \
     if (atomic_add_value(&g_nQnxInIsrs, 1) == 0) \
     { \
         gctARGUMENTS __arguments__; \
         gcmkARGUMENTS_START(__arguments__, Message); \
-        _Print(ArgumentSize, CopyMessage, Message, &__arguments__); \
+        _Print(Message, &__arguments__); \
         gcmkARGUMENTS_END(__arguments__); \
     } \
     atomic_sub(&g_nQnxInIsrs, 1); \
 }
 
 #elif defined(__VXWORKS__)
-#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
+#define gcmDEBUGPRINT(Message) \
 { \
     printf(Message); \
 }
 
 #else
-#define gcmDEBUGPRINT(ArgumentSize, CopyMessage, Message) \
+
+#define gcmDEBUGPRINT(Message) \
 { \
     gctARGUMENTS __arguments__; \
     gcmkARGUMENTS_START(__arguments__, Message); \
-    _Print(ArgumentSize, CopyMessage, Message, &__arguments__); \
+    _Print(Message, &__arguments__); \
     gcmkARGUMENTS_END(__arguments__); \
 }
 
 #endif
 
-/******************************************************************************\
-********************************** Debug Code **********************************
-\******************************************************************************/
-
-/*******************************************************************************
-**
-**  gckOS_Print
-**
-**  Send a message to the debugger.
-**
-**  INPUT:
-**
-**      gctCONST_STRING Message
-**          Pointer to message.
-**
-**      ...
-**          Optional arguments.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-void
-gckOS_Print(
-    IN gctCONST_STRING Message,
-    ...
-    )
-{
-    gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
-}
-
-/*******************************************************************************
-**
-**  gckOS_PrintN
-**
-**  Send a message to the debugger.
-**
-**  INPUT:
-**
-**      gctUINT ArgumentSize
-**          The size of the optional arguments in bytes.
-**
-**      gctCONST_STRING Message
-**          Pointer to message.
-**
-**      ...
-**          Optional arguments.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-void
-gckOS_PrintN(
-    IN gctUINT ArgumentSize,
-    IN gctCONST_STRING Message,
-    ...
-    )
-{
-    gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
-}
-
-/*******************************************************************************
-**
-**  gckOS_CopyPrint
-**
-**  Send a message to the debugger. If in buffered output mode, the entire
-**  message will be copied into the buffer instead of using the pointer to
-**  the string.
-**
-**  INPUT:
-**
-**      gctCONST_STRING Message
-**          Pointer to message.
-**
-**      ...
-**          Optional arguments.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-void
-gckOS_CopyPrint(
-    IN gctCONST_STRING Message,
-    ...
-    )
-{
-    gcmDEBUGPRINT(_GetArgumentSize(Message), gcvTRUE, Message);
-}
-
-/*******************************************************************************
-**
-**  gckOS_DumpBuffer
-**
-**  Print the contents of the specified buffer.
-**
-**  INPUT:
-**
-**      gckOS Os
-**          Pointer to gckOS object.
-**
-**      gctPOINTER Buffer
-**          Pointer to the buffer to print.
-**
-**      gctUINT Size
-**          Size of the buffer.
-**
-**      gceDUMP_BUFFER Type
-**          Buffer type.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-void
-gckOS_DumpBuffer(
-    IN gckOS Os,
-    IN gctPOINTER Buffer,
-    IN gctSIZE_T Size,
-    IN gceDUMP_BUFFER Type,
-    IN gctBOOL CopyMessage
-    )
-{
-    gctPHYS_ADDR_T physical;
-    gctUINT32 address                   = 0;
-    gcsBUFFERED_OUTPUT_PTR outputBuffer = gcvNULL;
-    gctCHAR *buffer                     = (gctCHAR*)Buffer;
-    gctPOINTER pAllocated               = gcvNULL;
-    gctPOINTER pMapped                  = gcvNULL;
-    gceSTATUS status                    = gcvSTATUS_OK;
-
-    static gcmkDECLARE_MUTEX(lockHandle);
-
-    gcmkMUTEX_LOCK(lockHandle);
-
-    /* Request lock when not coming from user,
-       or coming from user and not yet locked
-          and message is starting with @[. */
-    if (Type == gcvDUMP_BUFFER_FROM_USER)
-    {
-        /* Some format check. */
-        if ((Size > 2)
-         && (buffer[0] == '@' || buffer[0] == '#')
-         && (buffer[1] != '[')
-        )
-        {
-            gcmkMUTEX_UNLOCK(lockHandle);
-
-            /* No error tolerence in parser, so we stop on error to make noise. */
-            for (;;)
-            {
-                gcmkPRINT(
-                    "[galcore]: %s(%d): Illegal dump message %s\n",
-                    __FUNCTION__, __LINE__,
-                    buffer
-                    );
-
-                gckOS_Delay(Os, 10 * 1000);
-            }
-        }
-    }
-
-    if (Buffer != gcvNULL)
-    {
-        /* Initialize output buffer list. */
-        _InitBuffers();
-
-        /* Locate the proper output buffer. */
-        outputBuffer = _GetOutputBuffer();
-
-        /* Update the line number. */
-#if gcdSHOW_LINE_NUMBER
-        outputBuffer->lineNumber += 1;
-#endif
-
-        /* Get the physical address of the buffer. */
-        if (Type != gcvDUMP_BUFFER_FROM_USER)
-        {
-            gcmkVERIFY_OK(gckOS_GetPhysicalAddress(Os, Buffer, &physical));
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, physical, &physical));
-            gcmkSAFECASTPHYSADDRT(address, physical);
-        }
-        else
-        {
-            address = 0;
-        }
-
-        if (Type == gcvDUMP_BUFFER_USER)
-        {
-            gctBOOL needCopy = gcvTRUE;
-
-            gcmkONERROR(gckOS_QueryNeedCopy(Os, 0, &needCopy));
-
-            if (needCopy)
-            {
-                gcmkONERROR(gckOS_Allocate(
-                    Os,
-                    Size,
-                    &pAllocated
-                    ));
-
-                gcmkONERROR(gckOS_CopyFromUserData(
-                    Os,
-                    pAllocated,
-                    Buffer,
-                    Size
-                    ));
-
-                Buffer = pAllocated;
-            }
-            else
-            {
-                gcmkONERROR(gckOS_MapUserPointer(
-                    Os,
-                    Buffer,
-                    Size,
-                    &pMapped
-                    ));
-
-                Buffer = pMapped;
-            }
-        }
-
-#if gcdHAVEPREFIX
-        {
-            gctUINT8_PTR alignedPrefixData;
-            gctUINT8 prefixData[gcdPREFIX_SIZE + gcdPREFIX_ALIGNMENT];
-
-            /* Compute aligned pointer. */
-            alignedPrefixData = prefixData;
-            gcmkALIGNPTR(gctUINT8_PTR, alignedPrefixData, gcdPREFIX_ALIGNMENT);
-
-            /* Initialize the prefix data. */
-            _InitPrefixData(outputBuffer, alignedPrefixData);
-
-            /* Print/schedule the buffer. */
-            gcdOUTPUTBUFFER(
-                outputBuffer, outputBuffer->indent,
-                alignedPrefixData, Buffer, address, Size, Type, 0
-                );
-        }
-#else
-        /* Print/schedule the buffer. */
-        if (Type == gcvDUMP_BUFFER_FROM_USER)
-        {
-            gckOS_CopyPrint(Buffer);
-        }
-        else
-        {
-            gcdOUTPUTBUFFER(
-                outputBuffer, outputBuffer->indent,
-                gcvNULL, Buffer, address, Size, Type, 0
-                );
-        }
-#endif
-    }
-
-OnError:
-    gcmkMUTEX_UNLOCK(lockHandle);
-
-    if (pAllocated)
-    {
-        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, pAllocated));
-    }
-    else if (pMapped)
-    {
-        gckOS_UnmapUserPointer(Os, buffer, Size, pMapped);
-    }
-}
-
+/******************************************************************************\
+********************************** Debug Code **********************************
+\******************************************************************************/
+
 /*******************************************************************************
 **
-**  gckOS_DebugTrace
+**  gckOS_Print
 **
-**  Send a leveled message to the debugger.
+**  Send a message to the debugger.
 **
 **  INPUT:
 **
-**      gctUINT32 Level
-**          Debug level of message.
-**
 **      gctCONST_STRING Message
 **          Pointer to message.
 **
@@ -2150,23 +503,17 @@ OnError:
 */
 
 void
-gckOS_DebugTrace(
-    IN gctUINT32 Level,
+gckOS_Print(
     IN gctCONST_STRING Message,
     ...
     )
 {
-    if (Level > _debugLevel)
-    {
-        return;
-    }
-
-    gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
+    gcmDEBUGPRINT(Message);
 }
 
 /*******************************************************************************
 **
-**  gckOS_DebugTraceN
+**  gckOS_DebugTrace
 **
 **  Send a leveled message to the debugger.
 **
@@ -2175,9 +522,6 @@ gckOS_DebugTrace(
 **      gctUINT32 Level
 **          Debug level of message.
 **
-**      gctUINT ArgumentSize
-**          The size of the optional arguments in bytes.
-**
 **      gctCONST_STRING Message
 **          Pointer to message.
 **
@@ -2190,9 +534,8 @@ gckOS_DebugTrace(
 */
 
 void
-gckOS_DebugTraceN(
+gckOS_DebugTrace(
     IN gctUINT32 Level,
-    IN gctUINT ArgumentSize,
     IN gctCONST_STRING Message,
     ...
     )
@@ -2202,7 +545,7 @@ gckOS_DebugTraceN(
         return;
     }
 
-    gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
+    gcmDEBUGPRINT(Message);
 }
 
 /*******************************************************************************
@@ -2243,52 +586,7 @@ gckOS_DebugTraceZone(
         return;
     }
 
-    gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
-}
-
-/*******************************************************************************
-**
-**  gckOS_DebugTraceZoneN
-**
-**  Send a leveled and zoned message to the debugger.
-**
-**  INPUT:
-**
-**      gctUINT32 Level
-**          Debug level for message.
-**
-**      gctUINT32 Zone
-**          Debug zone for message.
-**
-**      gctUINT ArgumentSize
-**          The size of the optional arguments in bytes.
-**
-**      gctCONST_STRING Message
-**          Pointer to message.
-**
-**      ...
-**          Optional arguments.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-void
-gckOS_DebugTraceZoneN(
-    IN gctUINT32 Level,
-    IN gctUINT32 Zone,
-    IN gctUINT ArgumentSize,
-    IN gctCONST_STRING Message,
-    ...
-    )
-{
-    if ((Level > _debugLevel) || !(Zone & _debugZones))
-    {
-        return;
-    }
-
-    gcmDEBUGPRINT(ArgumentSize, gcvFALSE, Message);
+    gcmDEBUGPRINT(Message);
 }
 
 /*******************************************************************************
@@ -2338,7 +636,7 @@ gckOS_DebugFatal(
     )
 {
     gcmkPRINT_VERSION();
-    gcmDEBUGPRINT(_GetArgumentSize(Message), gcvFALSE, Message);
+    gcmDEBUGPRINT(Message);
 
     /* Break into the debugger. */
     gckOS_DebugBreak();
@@ -2482,40 +780,6 @@ gckOS_Verify(
     _lastError = status;
 }
 
-/*******************************************************************************
-**
-**  gckOS_DebugFlush
-**
-**  Force messages to be flushed out.
-**
-**  INPUT:
-**
-**      gctCONST_STRING CallerName
-**          Name of the caller function.
-**
-**      gctUINT LineNumber
-**          Line number of the caller.
-**
-**      gctUINT32 DmaAddress
-**          The current DMA address or ~0U to ignore.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-
-void
-gckOS_DebugFlush(
-    gctCONST_STRING CallerName,
-    gctUINT LineNumber,
-    gctUINT32 DmaAddress
-    )
-{
-#if gcdBUFFERED_OUTPUT
-    _DirectPrint("\nFlush requested by %s(%d).\n\n", CallerName, LineNumber);
-    _Flush(DmaAddress);
-#endif
-}
 gctCONST_STRING
 gckOS_DebugStatus2Name(
     gceSTATUS status
@@ -2686,186 +950,384 @@ gckOS_DebugStatus2Name(
 }
 
 /*******************************************************************************
-***** Binary Trace *************************************************************
+***** Kernel Dump **************************************************************
 *******************************************************************************/
 
+/*
+ * TODO: Dump to file is only valid in linux currently.
+ */
+#ifndef gcmkDUMP_STRING
+#  define gcmkDUMP_STRING(os, s)    gcmkOUTPUT_STRING((s))
+#endif
+
+static gcmkDECLARE_MUTEX(_dumpMutex);
+static gctCHAR _dumpStorage[512];
+
 /*******************************************************************************
-**  _VerifyMessage
 **
-**  Verify a binary trace message, decode it to human readable string and print
-**  it.
+**  gckOS_Dump
+**
+**  Formated print string to dump pool.
+**
+**  INPUT:
 **
-**  ARGUMENTS:
+**      gctCONST_STRING Format
+**          String format.
 **
-**      gctCONST_STRING Buffer
-**          Pointer to buffer to store.
+**  OUTPUT:
 **
-**      gctSIZE_T Bytes
-**          Buffer length.
+**      Nothing.
 */
 void
-_VerifyMessage(
-    IN gctCONST_STRING Buffer,
-    IN gctSIZE_T Bytes
+gckOS_Dump(
+    IN gckOS Os,
+    IN gctCONST_STRING Format,
+    ...
+    )
+{
+    char buffer[256];
+    gctINT len;
+    gctARGUMENTS args;
+
+    gcmkARGUMENTS_START(args, Format);
+    len = gcmkVSPRINTF(buffer, gcmSIZEOF(buffer) - 2, Format, &args);
+    gcmkARGUMENTS_END(args);
+
+    if (len > 0)
+    {
+        if (buffer[len - 1] != '\n')
+        {
+            buffer[len] = '\n';
+            buffer[len + 1] = '\0';
+        }
+
+        gcmkMUTEX_LOCK(_dumpMutex);
+        gcmkDUMP_STRING(Os, buffer);
+        gcmkMUTEX_UNLOCK(_dumpMutex);
+    }
+}
+
+static void
+_DumpUserString(
+    IN gckOS Os,
+    IN gctPOINTER UserStr,
+    IN gctSIZE_T Size
     )
 {
-    char arguments[150] = {0};
-    char format[100] = {0};
+    gceSTATUS status = gcvSTATUS_OK;
+    gctSIZE_T offset = 0;
+    gctSIZE_T length = 0;
+    gctBOOL needCopy = gcvTRUE;
+    const gctSIZE_T maxLength = gcmSIZEOF(_dumpStorage) - 1;
 
-    gctSTRING function;
-    gctPOINTER args;
-    gctUINT32 numArguments;
-    int i = 0;
-    gctUINT32 functionBytes;
+    gcmkVERIFY_OK(gckOS_QueryNeedCopy(Os, 0, &needCopy));
 
-    gcsBINARY_TRACE_MESSAGE_PTR message = (gcsBINARY_TRACE_MESSAGE_PTR)Buffer;
+    gcmkMUTEX_LOCK(_dumpMutex);
 
-    /* Check signature. */
-    if (message->signature != 0x7FFFFFFF)
+    while (offset < Size)
     {
-        gcmkPRINT("Signature error");
-        return;
+        length = maxLength < (Size - offset) ? maxLength : (Size - offset);
+
+        /* Copy or map from user. */
+        if (needCopy)
+        {
+            gcmkONERROR(gckOS_CopyFromUserData(
+                Os,
+                _dumpStorage,
+                UserStr,
+                length
+                ));
+        }
+        else
+        {
+            gctPOINTER ptr = gcvNULL;
+
+            gcmkONERROR(gckOS_MapUserPointer(
+                Os,
+                UserStr,
+                length,
+                (gctPOINTER *)&ptr
+                ));
+
+            gckOS_MemCopy(_dumpStorage, ptr, length);
+            gckOS_UnmapUserPointer(Os, UserStr, length, ptr);
+        }
+
+        _dumpStorage[length] = '\0';
+        gcmkDUMP_STRING(Os, _dumpStorage);
+
+        UserStr = (gctUINT8_PTR)UserStr + length;
+        offset += length;
     }
 
-    /* Get function name. */
-    function = (gctSTRING)&message->payload;
-    functionBytes = (gctUINT32)strlen(function) + 1;
+    gcmkDUMP_STRING(Os, "\n");
+
+OnError:
+    gcmkMUTEX_UNLOCK(_dumpMutex);
+}
+
+static void
+_DumpDataBuffer(
+    IN gckOS Os,
+    IN gceDUMP_BUFFER_TYPE Type,
+    IN gctPOINTER Data,
+    IN gctUINT64 Address,
+    IN gctSIZE_T Size
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    gctSIZE_T offset = 0;
+    gctSIZE_T length = 0;
+    gctBOOL needCopy = gcvTRUE;
+    gctCONST_STRING dumpTag;
+    gctBOOL skip = gcvFALSE;
+    char buffer[256];
+    const gctSIZE_T maxLength = gcmSIZEOF(_dumpStorage);
+
+    switch (Type)
+    {
+    case gcvDUMP_BUFFER_VERIFY:
+        dumpTag = "verify";
+        break;
+    case gcvDUMP_BUFFER_PHYSICAL_MEMORY:
+        dumpTag = "physical";
+        break;
+    default:
+        dumpTag = "memory";
+        break;
+    }
 
-    /* Get arguments number. */
-    numArguments = message->numArguments;
+    if (Type <= gcvDUMP_BUFFER_USER_TYPE_LAST)
+    {
+        gcmkVERIFY_OK(gckOS_QueryNeedCopy(Os, 0, &needCopy));
+    }
 
-    /* Get arguments . */
-    args = function + functionBytes;
+    gcmkMUTEX_LOCK(_dumpMutex);
 
-    /* Prepare format string. */
-    while (numArguments--)
+    /* Form and print the opening string. */
+    if (Type == gcvDUMP_BUFFER_PHYSICAL_MEMORY)
+    {
+        gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                    "@[%s 0x%010llX 0x%08X\n",
+                    dumpTag, (unsigned long long)Address, (gctUINT32)Size);
+    }
+    else
     {
-        format[i++] = '%';
-        format[i++] = 'x';
-        format[i++] = ' ';
+        gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                    "@[%s 0x%08X 0x%08X\n",
+                    dumpTag, (gctUINT32)Address, (gctUINT32)Size);
     }
 
-    format[i] = '\0';
+    gcmkDUMP_STRING(Os, buffer);
 
-    if (numArguments)
+
+    while (offset < Size)
     {
-        gcmkVSPRINTF(arguments, 150, format, (gctARGUMENTS *) &args);
+        gctPOINTER data = gcvNULL;
+        gctUINT32_PTR ptr;
+        gctUINT8_PTR bytePtr;
+        gctSIZE_T count, tailByteCount;
+
+        length = maxLength < (Size - offset) ? maxLength : (Size - offset);
+
+        if (skip)
+        {
+            length = 128 < length ? 128 : length;
+        }
+
+        count = length / 4;
+        tailByteCount = length % 4;
+
+        ptr = (gctUINT32_PTR)Data;
+
+        if (Type <= gcvDUMP_BUFFER_USER_TYPE_LAST)
+        {
+            /* Copy or map from user. */
+            if (needCopy)
+            {
+                gcmkONERROR(gckOS_CopyFromUserData(
+                    Os,
+                    _dumpStorage,
+                    Data,
+                    length
+                    ));
+
+                ptr = (gctUINT32_PTR)_dumpStorage;
+            }
+            else
+            {
+                gcmkONERROR(gckOS_MapUserPointer(
+                    Os,
+                    Data,
+                    length,
+                    (gctPOINTER *)&data
+                    ));
+
+                ptr = (gctUINT32_PTR)data;
+            }
+        }
+
+        while (count >= 4)
+        {
+            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                        "  0x%08X 0x%08X 0x%08X 0x%08X\n",
+                        ptr[0], ptr[1], ptr[2], ptr[3]);
+
+            ptr   += 4;
+            count -= 4;
+
+            gcmkDUMP_STRING(Os, buffer);
+        }
+
+        switch (count)
+        {
+        case 3:
+            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                        "  0x%08X 0x%08X 0x%08X",
+                        ptr[0], ptr[1], ptr[2]);
+            break;
+        case 2:
+            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                        "  0x%08X 0x%08X",
+                        ptr[0], ptr[1]);
+            break;
+        case 1:
+            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1, "  0x%08X", ptr[0]);
+            break;
+        }
+
+        if (count > 0)
+        {
+            gcmkDUMP_STRING(Os, buffer);
+        }
+
+        bytePtr = (gctUINT8_PTR)(ptr + count);
+
+        if (!count && tailByteCount)
+        {
+            /* There is an extra space for the new line. */
+            gcmkDUMP_STRING(Os, " ");
+        }
+
+        switch (tailByteCount)
+        {
+        case 3:
+            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                        " 0x00%02X%02X%02X",
+                        bytePtr[2], bytePtr[1], bytePtr[0]);
+            break;
+        case 2:
+            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                        " 0x0000%02X%02X",
+                        bytePtr[1], bytePtr[0]);
+            break;
+        case 1:
+            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                        " 0x000000%02X", bytePtr[0]);
+            break;
+        }
+
+        if (tailByteCount)
+        {
+            gcmkDUMP_STRING(Os, buffer);
+        }
+
+        if (count || tailByteCount)
+        {
+            gcmkDUMP_STRING(Os, "\n");
+        }
+
+        if (Type <= gcvDUMP_BUFFER_USER_TYPE_LAST && !needCopy)
+        {
+            gckOS_UnmapUserPointer(Os, Data, length, data);
+        }
+
+        if (skip && Size > 128 * 2)
+        {
+            length = (Size & ~(128 - 1)) - 128;
+            gcmkDUMP_STRING(Os, "  ...skip...\n");
+
+            gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1,
+                        "  0x%08X:\n",
+                        (gctUINT32)(Address + length));
+            gcmkDUMP_STRING(Os, buffer);
+
+            skip = gcvFALSE;
+        }
+
+        /* advance to next batch. */
+        Data    = (gctUINT8_PTR)Data + length;
+        offset += length;
     }
 
-    gcmkPRINT("[%d](%d): %s(%d) %s",
-             message->pid,
-             message->tid,
-             function,
-             message->line,
-             arguments);
-}
+OnError:
+    gcmkSPRINTF(buffer, gcmSIZEOF(buffer) - 1, "] -- %s\n", dumpTag);
+    gcmkDUMP_STRING(Os, buffer);
 
+    gcmkMUTEX_UNLOCK(_dumpMutex);
+}
 
 /*******************************************************************************
-**  gckOS_WriteToRingBuffer
 **
-**  Store a buffer to ring buffer.
+**  gckOS_DumpBuffer
+**
+**  Print the contents of the specified buffer.
 **
-**  ARGUMENTS:
+**  INPUT:
 **
-**      gctCONST_STRING Buffer
-**          Pointer to buffer to store.
+**      gckOS Os
+**          Pointer to gckOS object.
 **
-**      gctSIZE_T Bytes
-**          Buffer length.
-*/
-void
-gckOS_WriteToRingBuffer(
-    IN gctCONST_STRING Buffer,
-    IN gctSIZE_T Bytes
-    )
-{
-
-}
-
-/*******************************************************************************
-**  gckOS_BinaryTrace
+**      gceDUMP_BUFFER_TYPE Type
+**          Buffer type.
 **
-**  Output a binary trace message.
+**      gctPOINTER Buffer
+**          Pointer to the buffer to print.
 **
-**  ARGUMENTS:
+**      gctUINT64 Address
+**          Address.
 **
-**      gctCONST_STRING Function
-**          Pointer to function name.
+**      gctUINT Size
+**          Size of the buffer.
 **
-**      gctINT Line
-**          Line number.
 **
-**      gctCONST_STRING Text OPTIONAL
-**          Optional pointer to a descriptive text.
+**  OUTPUT:
 **
-**      ...
-**          Optional arguments to the descriptive text.
+**      Nothing.
 */
 void
-gckOS_BinaryTrace(
-    IN gctCONST_STRING Function,
-    IN gctINT Line,
-    IN gctCONST_STRING Text OPTIONAL,
-    ...
+gckOS_DumpBuffer(
+    IN gckOS Os,
+    IN gceDUMP_BUFFER_TYPE Type,
+    IN gctPOINTER Buffer,
+    IN gctUINT64 Address,
+    IN gctSIZE_T Size
     )
 {
-    static gctUINT32 messageSignature = 0x7FFFFFFF;
-    char buffer[gcdBINARY_TRACE_MESSAGE_SIZE];
-    gctUINT32 numArguments = 0;
-    gctUINT32 functionBytes;
-    gctUINT32 i = 0;
-    gctSTRING payload;
-    gcsBINARY_TRACE_MESSAGE_PTR message = (gcsBINARY_TRACE_MESSAGE_PTR)buffer;
-
-    /* Calculate arguments number. */
-    if (Text)
+    if (!Buffer)
     {
-        while (Text[i] != '\0')
-        {
-            if (Text[i] == '%')
-            {
-                numArguments++;
-            }
-            i++;
-        }
+        return;
     }
 
-    message->signature    = messageSignature;
-    message->pid          = gcmkGETPROCESSID();
-    message->tid          = gcmkGETTHREADID();
-    message->line         = Line;
-    message->numArguments = numArguments;
-
-    payload = (gctSTRING)&message->payload;
-
-    /* Function name. */
-    functionBytes = (gctUINT32)gcmkSTRLEN(Function) + 1;
-    gcmkMEMCPY(payload, Function, functionBytes);
-
-    /* Advance to next payload. */
-    payload += functionBytes;
-
-    /* Arguments value. */
-    if (numArguments)
+    /* memory dump below. */
+    if (Type >= gcvDUMP_BUFFER_TYPE_COUNT)
     {
-        gctARGUMENTS p;
-        gcmkARGUMENTS_START(p, Text);
-
-        for (i = 0; i < numArguments; ++i)
-        {
-            gctPOINTER value = gcmkARGUMENTS_ARG(p, gctPOINTER);
-            gcmkMEMCPY(payload, &value, gcmSIZEOF(gctPOINTER));
-            payload += gcmSIZEOF(gctPOINTER);
-        }
-
-        gcmkARGUMENTS_END(p);
+        gcmkPRINT("#[ERROR: invalid buffer type]\n");
+        return;
     }
 
-    gcmkASSERT(payload - buffer <= gcdBINARY_TRACE_MESSAGE_SIZE);
+    if (Type == gcvDUMP_BUFFER_USER_STRING)
+    {
+        _DumpUserString(Os, Buffer, Size);
+    }
+    else
+    {
+        _DumpDataBuffer(Os, Type, Buffer, Address, Size);
+    }
+}
 
 
-    /* Send buffer to ring buffer. */
-    gckOS_WriteToRingBuffer(buffer, (gctUINT32)(payload - buffer));
-}
+/*******************************************************************************
+***** Binary Trace *************************************************************
+*******************************************************************************/
 
index 67400d0..fe8015d 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -230,7 +230,7 @@ OnError:
 static gceSTATUS
 _TryToIdleGPU(
     IN gckEVENT Event
-)
+    )
 {
     gceSTATUS status;
     gctBOOL empty = gcvFALSE, idle = gcvFALSE;
@@ -299,22 +299,6 @@ __RemoveRecordFromProcessDB(
 
     switch (Record->info.command)
     {
-    case gcvHAL_FREE_NON_PAGED_MEMORY:
-        gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
-            Event->kernel,
-            Record->processID,
-            gcvDB_NON_PAGED,
-            gcmUINT64_TO_PTR(Record->info.u.FreeNonPagedMemory.logical)));
-        break;
-
-    case gcvHAL_FREE_CONTIGUOUS_MEMORY:
-        gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
-            Event->kernel,
-            Record->processID,
-            gcvDB_CONTIGUOUS,
-            gcmUINT64_TO_PTR(Record->info.u.FreeContiguousMemory.logical)));
-        break;
-
     case gcvHAL_UNLOCK_VIDEO_MEMORY:
         gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
             Event->kernel,
@@ -323,22 +307,6 @@ __RemoveRecordFromProcessDB(
             gcmUINT64_TO_PTR(Record->info.u.UnlockVideoMemory.node)));
         break;
 
-    case gcvHAL_UNMAP_USER_MEMORY:
-        gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
-            Event->kernel,
-            Record->processID,
-            gcvDB_MAP_USER_MEMORY,
-            gcmINT2PTR(Record->info.u.UnmapUserMemory.info)));
-        break;
-
-    case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
-        gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
-            Event->kernel,
-            Record->processID,
-            gcvDB_COMMAND_BUFFER,
-            gcmUINT64_TO_PTR(Record->info.u.FreeVirtualCommandBuffer.logical)));
-        break;
-
     default:
         break;
     }
@@ -396,6 +364,8 @@ _QueryFlush(
     )
 {
     gceKERNEL_FLUSH flush = 0;
+    gckVIDMEM_NODE nodeObject;
+
     gcmkHEADER_ARG("Event=0x%x Record=0x%x", Event, Record);
     gcmkVERIFY_ARGUMENT(Record != gcvNULL);
 
@@ -404,48 +374,44 @@ _QueryFlush(
         switch (Record->info.command)
         {
         case gcvHAL_UNLOCK_VIDEO_MEMORY:
-            switch(Record->info.u.UnlockVideoMemory.type)
+            nodeObject = gcmUINT64_TO_PTR(Record->info.u.UnlockVideoMemory.node);
+
+            switch (nodeObject->type)
             {
-            case gcvSURF_TILE_STATUS:
+            case gcvVIDMEM_TYPE_TILE_STATUS:
                 flush |= gcvFLUSH_TILE_STATUS;
                 break;
-            case gcvSURF_RENDER_TARGET:
+            case gcvVIDMEM_TYPE_COLOR_BUFFER:
                 flush |= gcvFLUSH_COLOR;
                 break;
-            case gcvSURF_DEPTH:
+            case gcvVIDMEM_TYPE_DEPTH_BUFFER:
                 flush |= gcvFLUSH_DEPTH;
                 break;
-            case gcvSURF_TEXTURE:
+            case gcvVIDMEM_TYPE_TEXTURE:
                 flush |= gcvFLUSH_TEXTURE;
                 break;
-            case gcvSURF_ICACHE:
+            case gcvVIDMEM_TYPE_ICACHE:
                 flush |= gcvFLUSH_ICACHE;
                 break;
-            case gcvSURF_TXDESC:
+            case gcvVIDMEM_TYPE_TXDESC:
                 flush |= gcvFLUSH_TXDESC;
                 break;
-            case gcvSURF_FENCE:
+            case gcvVIDMEM_TYPE_FENCE:
                 flush |= gcvFLUSH_FENCE;
                 break;
-            case gcvSURF_VERTEX:
+            case gcvVIDMEM_TYPE_VERTEX_BUFFER:
                 flush |= gcvFLUSH_VERTEX;
                 break;
-            case gcvSURF_TFBHEADER:
+            case gcvVIDMEM_TYPE_TFBHEADER:
                 flush |= gcvFLUSH_TFBHEADER;
                 break;
-            case gcvSURF_TYPE_UNKNOWN:
-                *Flush = gcvFLUSH_ALL;
-                gcmkFOOTER_NO();
-                return gcvSTATUS_OK;
+            case gcvVIDMEM_TYPE_GENERIC:
+                flush = gcvFLUSH_ALL;
+                goto Out;
             default:
                 break;
             }
             break;
-        case gcvHAL_UNMAP_USER_MEMORY:
-            *Flush = gcvFLUSH_ALL;
-            gcmkFOOTER_NO();
-            return gcvSTATUS_OK;
-
         default:
             break;
         }
@@ -453,6 +419,7 @@ _QueryFlush(
         Record = Record->next;
     }
 
+Out:
     *Flush = flush;
 
     gcmkFOOTER_NO();
@@ -491,6 +458,7 @@ _SubmitTimerFunction(
 gceSTATUS
 gckEVENT_Construct(
     IN gckKERNEL Kernel,
+    IN gckCOMMAND Command,
     OUT gckEVENT * Event
     )
 {
@@ -523,6 +491,7 @@ gckEVENT_Construct(
     eventObj->object.type = gcvOBJ_EVENT;
     eventObj->kernel      = Kernel;
     eventObj->os          = os;
+    eventObj->command     = Command;
 
     /* Create the mutexes. */
     gcmkONERROR(gckOS_CreateMutex(os, &eventObj->eventQueueMutex));
@@ -987,8 +956,6 @@ gckEVENT_AddList(
     gctBOOL acquired = gcvFALSE;
     gcsEVENT_PTR record = gcvNULL;
     gcsEVENT_QUEUE_PTR queue;
-    gckVIRTUAL_COMMAND_BUFFER_PTR buffer;
-    gckKERNEL kernel = Event->kernel;
 
     gcmkHEADER_ARG("Event=0x%x Interface=0x%x",
                    Event, Interface);
@@ -1003,15 +970,11 @@ gckEVENT_AddList(
 
     /* Verify the event command. */
     gcmkASSERT
-        (  (Interface->command == gcvHAL_FREE_NON_PAGED_MEMORY)
-        || (Interface->command == gcvHAL_FREE_CONTIGUOUS_MEMORY)
-        || (Interface->command == gcvHAL_WRITE_DATA)
+        (  (Interface->command == gcvHAL_WRITE_DATA)
         || (Interface->command == gcvHAL_UNLOCK_VIDEO_MEMORY)
         || (Interface->command == gcvHAL_SIGNAL)
-        || (Interface->command == gcvHAL_UNMAP_USER_MEMORY)
         || (Interface->command == gcvHAL_TIMESTAMP)
         || (Interface->command == gcvHAL_COMMIT_DONE)
-        || (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER)
         || (Interface->command == gcvHAL_DESTROY_MMU)
         );
 
@@ -1056,43 +1019,6 @@ gckEVENT_AddList(
     record->kernel = Event->kernel;
 #endif
 
-    /* Unmap user space logical address.
-     * Linux kernel does not support unmap the memory of other process any more since 3.5.
-     * Let's unmap memory of self process before submit the event to gpu.
-     * */
-    switch(Interface->command)
-    {
-    case gcvHAL_FREE_NON_PAGED_MEMORY:
-        gcmkONERROR(gckOS_UnmapUserLogical(
-                        Event->os,
-                        gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical),
-                        (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes,
-                        gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical)));
-        break;
-    case gcvHAL_FREE_CONTIGUOUS_MEMORY:
-        gcmkONERROR(gckOS_UnmapUserLogical(
-                        Event->os,
-                        gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical),
-                        (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes,
-                        gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical)));
-        break;
-
-    case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
-        buffer = (gckVIRTUAL_COMMAND_BUFFER_PTR)gcmNAME_TO_PTR(Interface->u.FreeVirtualCommandBuffer.physical);
-        if (buffer != gcvNULL && buffer->virtualBuffer.userLogical)
-        {
-            gcmkONERROR(gckOS_DestroyUserVirtualMapping(
-                            Event->os,
-                            buffer->virtualBuffer.physical,
-                            (gctSIZE_T) Interface->u.FreeVirtualCommandBuffer.bytes,
-                            gcmUINT64_TO_PTR(Interface->u.FreeVirtualCommandBuffer.logical)));
-        }
-        break;
-
-    default:
-        break;
-    }
-
     /* Acquire the mutex. */
     gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->eventListMutex, gcvINFINITE));
     acquired = gcvTRUE;
@@ -1179,8 +1105,8 @@ OnError:
 **          Pointer to a gcuVIDMEM_NODE union that specifies the virtual memory
 **          to unlock.
 **
-**      gceSURF_TYPE Type
-**          Type of surface to unlock.
+**      gceVIDMEM_TYPE Type
+**          Video memory allocation type to unlock.
 **
 **  OUTPUT:
 **
@@ -1190,15 +1116,14 @@ gceSTATUS
 gckEVENT_Unlock(
     IN gckEVENT Event,
     IN gceKERNEL_WHERE FromWhere,
-    IN gctPOINTER Node,
-    IN gceSURF_TYPE Type
+    IN gctPOINTER Node
     )
 {
     gceSTATUS status;
     gcsHAL_INTERFACE iface;
 
-    gcmkHEADER_ARG("Event=0x%x FromWhere=%d Node=0x%x Type=%d",
-                   Event, FromWhere, Node, Type);
+    gcmkHEADER_ARG("Event=0x%x FromWhere=%d Node=0x%x",
+                   Event, FromWhere, Node);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
@@ -1207,7 +1132,6 @@ gckEVENT_Unlock(
     /* Mark the event as an unlock. */
     iface.command                           = gcvHAL_UNLOCK_VIDEO_MEMORY;
     iface.u.UnlockVideoMemory.node          = gcmPTR_TO_UINT64(Node);
-    iface.u.UnlockVideoMemory.type          = Type;
     iface.u.UnlockVideoMemory.asynchroneous = 0;
 
     /* Append it to the queue. */
@@ -1223,178 +1147,6 @@ OnError:
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckEVENT_FreeNonPagedMemory
-**
-**  Schedule an event to free non-paged memory.
-**
-**  INPUT:
-**
-**      gckEVENT Event
-**          Pointer to an gckEVENT object.
-**
-**      gctSIZE_T Bytes
-**          Number of bytes of non-paged memory to free.
-**
-**      gctPHYS_ADDR Physical
-**          Physical address of non-paged memory to free.
-**
-**      gctPOINTER Logical
-**          Logical address of non-paged memory to free.
-**
-**      gceKERNEL_WHERE FromWhere
-**          Place in the pipe where the event needs to be generated.
-*/
-gceSTATUS
-gckEVENT_FreeNonPagedMemory(
-    IN gckEVENT Event,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gceKERNEL_WHERE FromWhere
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-    gckKERNEL kernel = Event->kernel;
-
-    gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
-                   "FromWhere=%d",
-                   Event, Bytes, Physical, Logical, FromWhere);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
-    gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-
-    /* Create an event. */
-    iface.command = gcvHAL_FREE_NON_PAGED_MEMORY;
-    iface.u.FreeNonPagedMemory.bytes    = Bytes;
-    iface.u.FreeNonPagedMemory.physical = gcmPTR_TO_NAME(Physical);
-    iface.u.FreeNonPagedMemory.logical  = gcmPTR_TO_UINT64(Logical);
-
-    /* Append it to the queue. */
-    gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckEVENT_DestroyVirtualCommandBuffer(
-    IN gckEVENT Event,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gceKERNEL_WHERE FromWhere
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-    gckKERNEL kernel = Event->kernel;
-
-    gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
-                   "FromWhere=%d",
-                   Event, Bytes, Physical, Logical, FromWhere);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
-    gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-
-    /* Create an event. */
-    iface.command = gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER;
-    iface.u.FreeVirtualCommandBuffer.bytes    = Bytes;
-    iface.u.FreeVirtualCommandBuffer.physical = gcmPTR_TO_NAME(Physical);
-    iface.u.FreeVirtualCommandBuffer.logical  = gcmPTR_TO_UINT64(Logical);
-
-    /* Append it to the queue. */
-    gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gckEVENT_FreeContigiuousMemory
-**
-**  Schedule an event to free contiguous memory.
-**
-**  INPUT:
-**
-**      gckEVENT Event
-**          Pointer to an gckEVENT object.
-**
-**      gctSIZE_T Bytes
-**          Number of bytes of contiguous memory to free.
-**
-**      gctPHYS_ADDR Physical
-**          Physical address of contiguous memory to free.
-**
-**      gctPOINTER Logical
-**          Logical address of contiguous memory to free.
-**
-**      gceKERNEL_WHERE FromWhere
-**          Place in the pipe where the event needs to be generated.
-*/
-gceSTATUS
-gckEVENT_FreeContiguousMemory(
-    IN gckEVENT Event,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gceKERNEL_WHERE FromWhere
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-    gckKERNEL kernel = Event->kernel;
-
-    gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
-                   "FromWhere=%d",
-                   Event, Bytes, Physical, Logical, FromWhere);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
-    gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-
-    /* Create an event. */
-    iface.command = gcvHAL_FREE_CONTIGUOUS_MEMORY;
-    iface.u.FreeContiguousMemory.bytes    = Bytes;
-    iface.u.FreeContiguousMemory.physical = gcmPTR_TO_NAME(Physical);
-    iface.u.FreeContiguousMemory.logical  = gcmPTR_TO_UINT64(Logical);
-
-    /* Append it to the queue. */
-    gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
 /*******************************************************************************
 **
 **  gckEVENT_Signal
@@ -1459,168 +1211,6 @@ OnError:
     return status;
 }
 
-#if gcdPROCESS_ADDRESS_SPACE
-gceSTATUS
-gckEVENT_DestroyMmu(
-    IN gckEVENT Event,
-    IN gckMMU Mmu,
-    IN gceKERNEL_WHERE FromWhere
-    )
-{
-    gceSTATUS status;
-    gcsHAL_INTERFACE iface;
-
-    gcmkHEADER_ARG("Event=0x%x FromWhere=%d", Event, FromWhere);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
-
-    iface.command = gcvHAL_DESTROY_MMU;
-    iface.u.DestroyMmu.mmu = gcmPTR_TO_UINT64(Mmu);
-
-    /* Append it to the queue. */
-    gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-#endif
-
-gceSTATUS
-gckEVENT_SubmitAsync(
-    IN gckEVENT Event,
-    IN gctBOOL Wait,
-    IN gctBOOL FromPower
-    )
-{
-    gceSTATUS status;
-    gctUINT8 id = 0xFF;
-    gcsEVENT_QUEUE_PTR queue;
-    gctBOOL acquired = gcvFALSE;
-    gctBOOL commitEntered = gcvFALSE;
-    gctUINT32 start, end;
-    gctUINT8_PTR startLogical;
-    gctUINT32 eventBytes;
-
-    gckHARDWARE hardware;
-    gckASYNC_COMMAND asyncCommand;
-
-    gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
-
-    /* Get gckCOMMAND object. */
-    hardware = Event->kernel->hardware;
-    asyncCommand = Event->asyncCommand;
-
-    gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
-
-    /* Are there event queues? */
-    if (Event->queueHead != gcvNULL)
-    {
-        /* Acquire the command queue. */
-        gcmkONERROR(gckASYNC_COMMAND_EnterCommit(asyncCommand));
-        commitEntered = gcvTRUE;
-
-        /* Process all queues. */
-        while (Event->queueHead != gcvNULL)
-        {
-            /* Acquire the list mutex. */
-            gcmkONERROR(gckOS_AcquireMutex(Event->os,
-                Event->eventListMutex,
-                gcvINFINITE));
-            acquired = gcvTRUE;
-
-            /* Get the current queue. */
-            queue = Event->queueHead;
-
-            /* Allocate an event ID. */
-            gcmkONERROR(gckEVENT_GetEvent(Event, Wait, &id, queue->source));
-
-            /* Copy event list to event ID queue. */
-            Event->queues[id].head   = queue->head;
-
-            /* Remove the top queue from the list. */
-            if (Event->queueHead == Event->queueTail)
-            {
-                Event->queueHead = gcvNULL;
-                Event->queueTail = gcvNULL;
-            }
-            else
-            {
-                Event->queueHead = Event->queueHead->next;
-            }
-
-            /* Free the queue. */
-            gcmkONERROR(gckEVENT_FreeQueue(Event, queue));
-
-            /* Release the list mutex. */
-            gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
-            acquired = gcvFALSE;
-
-            gcmkONERROR(gckHARDWARE_Event(Event->kernel->hardware, gcvNULL, id, gcvKERNEL_BLT, &eventBytes));
-
-            /* Get command sequence. */
-            start = hardware->functions[gcvHARDWARE_FUNCTION_BLT_EVENT].address + id * eventBytes;
-            end   = start + 24;
-
-            startLogical = hardware->functions[gcvHARDWARE_FUNCTION_BLT_EVENT].logical + id * eventBytes;
-
-            gcmkDUMPCOMMAND(
-                Event->os,
-                startLogical,
-                end - start,
-                gcvDUMP_BUFFER_KERNEL,
-                gcvFALSE
-                );
-
-            gcmkONERROR(gckASYNC_COMMAND_Execute(asyncCommand, start, end));
-        }
-
-        /* Release the command queue. */
-        gcmkONERROR(gckASYNC_COMMAND_ExitCommit(asyncCommand));
-    }
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    if (acquired)
-    {
-        /* Need to unroll the mutex acquire. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
-    }
-
-    if (commitEntered)
-    {
-        /* Release the command queue mutex. */
-        gcmkVERIFY_OK(gckASYNC_COMMAND_ExitCommit(asyncCommand));
-    }
-
-    if (id != 0xFF)
-    {
-        /* Need to unroll the event allocation. */
-        Event->queues[id].head = gcvNULL;
-    }
-
-    if (status == gcvSTATUS_GPU_NOT_RESPONDING)
-    {
-        /* Broadcast GPU stuck. */
-        status = gckOS_Broadcast(Event->os,
-            Event->kernel->hardware,
-            gcvBROADCAST_GPU_STUCK);
-    }
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
 /*******************************************************************************
 **
 **  gckEVENT_Submit
@@ -1659,12 +1249,10 @@ gckEVENT_Submit(
     gctBOOL acquired = gcvFALSE;
     gckCOMMAND command = gcvNULL;
     gctBOOL commitEntered = gcvFALSE;
-#if !gcdNULL_DRIVER
     gctUINT32 bytes;
     gctPOINTER buffer;
     gctUINT32 executeBytes;
     gctUINT32 flushBytes;
-#endif
 
 #if gcdINTERRUPT_STATISTIC
     gctINT32 oldValue;
@@ -1682,20 +1270,11 @@ gckEVENT_Submit(
     gcmkHEADER_ARG("Event=0x%x Wait=%d", Event, Wait);
 
     /* Get gckCOMMAND object. */
-    command = Event->kernel->command;
+    command = Event->command;
     hardware = Event->kernel->hardware;
 
     gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
 
-    if (Event->asyncCommand)
-    {
-        /* Call async submit path. */
-        gcmkONERROR(gckEVENT_SubmitAsync(Event, Wait, FromPower));
-
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
-    }
-
     gckOS_GetTicks(&Event->lastCommitStamp);
 
     /* Are there event queues? */
@@ -1706,7 +1285,7 @@ gckEVENT_Submit(
         commitEntered = gcvTRUE;
 
         /* Get current commit stamp. */
-        commitStamp = Event->kernel->command->commitStamp;
+        commitStamp = command->commitStamp;
 
         if (commitStamp)
         {
@@ -1752,41 +1331,53 @@ gckEVENT_Submit(
             gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->eventListMutex));
             acquired = gcvFALSE;
 
-            /* Determine cache needed to flush. */
-            gcmkVERIFY_OK(_QueryFlush(Event, Event->queues[id].head, &flush));
 
-#if gcdNULL_DRIVER
-#if gcdINTERRUPT_STATISTIC
-            gcmkVERIFY_OK(gckOS_AtomIncrement(
-                Event->os,
-                Event->interruptCount,
-                &oldValue
-                ));
-#endif
-
-            /* Notify immediately on infinite hardware. */
-            gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
-
-            gcmkONERROR(gckEVENT_Notify(Event, 0));
-#else
-            /* Get the size of the hardware event. */
-            gcmkONERROR(gckHARDWARE_Event(
-                hardware,
-                gcvNULL,
-                id,
-                Event->queues[id].source,
-                &bytes
-                ));
+            if (command->feType == gcvHW_FE_WAIT_LINK)
+            {
+                /* Determine cache needed to flush. */
+                gcmkVERIFY_OK(_QueryFlush(Event, Event->queues[id].head, &flush));
+
+                /* Get the size of the hardware event. */
+                gcmkONERROR(gckWLFE_Event(
+                    hardware,
+                    gcvNULL,
+                    id,
+                    Event->queues[id].source,
+                    &bytes
+                    ));
 
-            /* Get the size of flush command. */
-            gcmkONERROR(gckHARDWARE_Flush(
-                hardware,
-                flush,
-                gcvNULL,
-                &flushBytes
-                ));
+                /* Get the size of flush command. */
+                gcmkONERROR(gckHARDWARE_Flush(
+                    hardware,
+                    flush,
+                    gcvNULL,
+                    &flushBytes
+                    ));
 
-            bytes += flushBytes;
+                bytes += flushBytes;
+            }
+            else if (command->feType == gcvHW_FE_ASYNC)
+            {
+                /* Get the size of the hardware event. */
+                gcmkONERROR(gckASYNC_FE_Event(
+                    hardware,
+                    gcvNULL,
+                    id,
+                    Event->queues[id].source,
+                    &bytes
+                    ));
+            }
+            else
+            {
+                /* Get the size of the hardware event. */
+                gcmkONERROR(gckMCFE_Event(
+                    hardware,
+                    gcvNULL,
+                    id,
+                    Event->queues[id].source,
+                    &bytes
+                    ));
+            }
 
             /* Total bytes need to execute. */
             executeBytes = bytes;
@@ -1797,29 +1388,6 @@ gckEVENT_Submit(
             reservedBuffer = buffer;
 #endif
 
-            /* Set the flush in the command queue. */
-            gcmkONERROR(gckHARDWARE_Flush(
-                hardware,
-                flush,
-                buffer,
-                &flushBytes
-                ));
-
-            /* Advance to next command. */
-            buffer = (gctUINT8_PTR)buffer + flushBytes;
-
-            /* Set the hardware event in the command queue. */
-            gcmkONERROR(gckHARDWARE_Event(
-                hardware,
-                buffer,
-                id,
-                Event->queues[id].source,
-                &bytes
-                ));
-
-            /* Advance to next command. */
-            buffer = (gctUINT8_PTR)buffer + bytes;
-
 #if gcdINTERRUPT_STATISTIC
             gcmkVERIFY_OK(gckOS_AtomIncrement(
                 Event->os,
@@ -1828,16 +1396,73 @@ gckEVENT_Submit(
                 ));
 #endif
 
+            if (command->feType == gcvHW_FE_WAIT_LINK)
+            {
+                /* Set the flush in the command queue. */
+                gcmkONERROR(gckHARDWARE_Flush(
+                    hardware,
+                    flush,
+                    buffer,
+                    &flushBytes
+                    ));
+
+                /* Advance to next command. */
+                buffer = (gctUINT8_PTR)buffer + flushBytes;
+
+                /* Set the hardware event in the command queue. */
+                gcmkONERROR(gckWLFE_Event(
+                    hardware,
+                    buffer,
+                    id,
+                    Event->queues[id].source,
+                    &bytes
+                    ));
+
 #if gcdSECURITY
-            gckKERNEL_SecurityExecute(
-                Event->kernel,
-                reservedBuffer,
-                executeBytes
-                );
+                gckKERNEL_SecurityExecute(
+                    Event->kernel,
+                    reservedBuffer,
+                    executeBytes
+                    );
 #else
-            /* Execute the hardware event. */
-            gcmkONERROR(gckCOMMAND_Execute(command, executeBytes));
+                /* Execute the hardware event. */
+                gcmkONERROR(gckCOMMAND_Execute(command, executeBytes));
 #endif
+            }
+            else if (command->feType == gcvHW_FE_ASYNC)
+            {
+                /* Set the hardware event in the command queue. */
+                gcmkONERROR(gckASYNC_FE_Event(
+                    hardware,
+                    buffer,
+                    id,
+                    Event->queues[id].source,
+                    &bytes
+                    ));
+
+                /* Execute the hardware event. */
+                gcmkONERROR(gckCOMMAND_ExecuteAsync(command, executeBytes));
+            }
+            else
+            {
+                /* Set the hardware event in the command queue. */
+                gcmkONERROR(gckMCFE_Event(
+                    hardware,
+                    buffer,
+                    id,
+                    Event->queues[id].source,
+                    &bytes
+                    ));
+
+                /* Execute the hardware event. */
+                gcmkONERROR(gckCOMMAND_ExecuteMultiChannel(command, 0, 0, executeBytes));
+            }
+
+#if gcdNULL_DRIVER
+            /* Notify immediately on infinite hardware. */
+            gcmkONERROR(gckEVENT_Interrupt(Event, 1 << id));
+
+            gcmkONERROR(gckEVENT_Notify(Event, 0));
 #endif
         }
 
@@ -2050,11 +1675,9 @@ gckEVENT_Interrupt(
         {
             if ((Data & (1 << j)))
             {
-                gckOS_AtomDecrement(
-                    Event->os,
-                    Event->interruptCount,
-                    &oldValue
-                    );
+                gckOS_AtomDecrement(Event->os,
+                                    Event->interruptCount,
+                                    &oldValue);
             }
         }
     }
@@ -2092,14 +1715,9 @@ gckEVENT_Notify(
     gctBOOL acquired = gcvFALSE;
     gctSIGNAL signal;
     gctUINT pending = 0;
-    gckKERNEL kernel = Event->kernel;
 
 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
     gctINT eventNumber = 0;
-#endif
-#if gcdSECURE_USER
-    gcskSECURE_CACHE_PTR cache;
-    gcuVIDMEM_NODE_PTR node;
 #endif
     gckVIDMEM_NODE nodeObject;
 
@@ -2305,10 +1923,6 @@ gckEVENT_Notify(
 #ifndef __QNXNTO__
             gctPOINTER logical;
 #endif
-#if gcdSECURE_USER
-            gctSIZE_T bytes;
-#endif
-
             /* Grab next record. */
             recordNext = record->next;
 
@@ -2319,14 +1933,6 @@ gckEVENT_Notify(
              */
             drv_thread_specific_key_assign(record->processID, 0);
 #endif
-
-#if gcdSECURE_USER
-            /* Get the cache that belongs to this process. */
-            gcmkONERROR(gckKERNEL_GetProcessDBCache(Event->kernel,
-                        record->processID,
-                        &cache));
-#endif
-
             gcmkTRACE_ZONE_N(
                 gcvLEVEL_INFO, gcvZONE_EVENT,
                 gcmSIZEOF(record->info.command),
@@ -2336,57 +1942,6 @@ gckEVENT_Notify(
 
             switch (record->info.command)
             {
-            case gcvHAL_FREE_NON_PAGED_MEMORY:
-                gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_EVENT,
-                               "gcvHAL_FREE_NON_PAGED_MEMORY: 0x%x",
-                               gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical));
-
-                /* Free non-paged memory. */
-                status = gckOS_FreeNonPagedMemory(
-                            Event->os,
-                            (gctSIZE_T) record->info.u.FreeNonPagedMemory.bytes,
-                            gcmNAME_TO_PTR(record->info.u.FreeNonPagedMemory.physical),
-                            gcmUINT64_TO_PTR(record->info.u.FreeNonPagedMemory.logical));
-
-                if (gcmIS_SUCCESS(status))
-                {
-#if gcdSECURE_USER
-                    gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
-                        Event->kernel,
-                        cache,
-                        gcmUINT64_TO_PTR(record->record.u.FreeNonPagedMemory.logical),
-                        (gctSIZE_T) record->record.u.FreeNonPagedMemory.bytes));
-#endif
-                }
-                gcmRELEASE_NAME(record->info.u.FreeNonPagedMemory.physical);
-                break;
-
-            case gcvHAL_FREE_CONTIGUOUS_MEMORY:
-                gcmkTRACE_ZONE(
-                    gcvLEVEL_VERBOSE, gcvZONE_EVENT,
-                    "gcvHAL_FREE_CONTIGUOUS_MEMORY: 0x%x",
-                    gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical));
-
-                /* Unmap the user memory. */
-                status = gckOS_FreeContiguous(
-                            Event->os,
-                            gcmNAME_TO_PTR(record->info.u.FreeContiguousMemory.physical),
-                            gcmUINT64_TO_PTR(record->info.u.FreeContiguousMemory.logical),
-                            (gctSIZE_T) record->info.u.FreeContiguousMemory.bytes);
-
-                if (gcmIS_SUCCESS(status))
-                {
-#if gcdSECURE_USER
-                    gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
-                        Event->kernel,
-                        cache,
-                        gcmUINT64_TO_PTR(event->event.u.FreeContiguousMemory.logical),
-                        (gctSIZE_T) event->event.u.FreeContiguousMemory.bytes));
-#endif
-                }
-                gcmRELEASE_NAME(record->info.u.FreeContiguousMemory.physical);
-                break;
-
             case gcvHAL_WRITE_DATA:
 #ifndef __QNXNTO__
                 /* Convert physical into logical address. */
@@ -2423,49 +1978,15 @@ gckEVENT_Notify(
 
                 nodeObject = gcmUINT64_TO_PTR(record->info.u.UnlockVideoMemory.node);
 
-#if gcdSECURE_USER
-                node = nodeObject->node;
-
-                /* Save node information before it disappears. */
-                node = event->event.u.UnlockVideoMemory.node;
-                if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
-                {
-                    logical = gcvNULL;
-                    bytes   = 0;
-                }
-                else
-                {
-                    logical = node->Virtual.logical;
-                    bytes   = node->Virtual.bytes;
-                }
-#endif
-
-                /* Unlock. */
-                status = gckVIDMEM_Unlock(
-                    Event->kernel,
-                    nodeObject,
-                    record->info.u.UnlockVideoMemory.type,
-                    gcvNULL);
-
-#if gcdSECURE_USER
-                if (gcmIS_SUCCESS(status) && (logical != gcvNULL))
-                {
-                    gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache(
-                        Event->kernel,
-                        cache,
-                        logical,
-                        bytes));
-                }
-#endif
-
-#if gcdPROCESS_ADDRESS_SPACE
-                gcmkVERIFY_OK(gckVIDMEM_NODE_Unlock(
+                /* Unlock, sync'ed. */
+                status = gckVIDMEM_NODE_Unlock(
                     Event->kernel,
                     nodeObject,
-                    record->processID
-                    ));
-#endif
+                    record->processID,
+                    gcvNULL
+                    );
 
+                /* Deref node. */
                 status = gckVIDMEM_NODE_Dereference(Event->kernel, nodeObject);
                 break;
 
@@ -2551,22 +2072,6 @@ gckEVENT_Notify(
                 }
                 break;
 
-             case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
-                 gcmkVERIFY_OK(
-                     gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel,
-                         (gctSIZE_T) record->info.u.FreeVirtualCommandBuffer.bytes,
-                         gcmNAME_TO_PTR(record->info.u.FreeVirtualCommandBuffer.physical),
-                         gcmUINT64_TO_PTR(record->info.u.FreeVirtualCommandBuffer.logical)
-                         ));
-                 gcmRELEASE_NAME(record->info.u.FreeVirtualCommandBuffer.physical);
-                 break;
-
-#if gcdPROCESS_ADDRESS_SPACE
-            case gcvHAL_DESTROY_MMU:
-                status = gckMMU_Destroy(gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu));
-                break;
-#endif
-
             case gcvHAL_COMMIT_DONE:
                 break;
 
@@ -2751,123 +2256,6 @@ OnError:
     return status;
 }
 
-/*******************************************************************************
-**  gckEVENT_Stop
-**
-**  Stop the hardware using the End event mechanism.
-**
-**  INPUT:
-**
-**      gckEVENT Event
-**          Pointer to an gckEVENT object.
-**
-**      gctUINT32 ProcessID
-**          Process ID Logical belongs.
-**
-**      gctPHYS_ADDR Handle
-**          Physical address handle.  If gcvNULL it is video memory.
-**
-**      gctSIZE_T Offset,
-**          Offset to this memory block.
-**
-**      gctPOINTER Logical
-**          Logical address to flush.
-**
-**      gctSIGNAL Signal
-**          Pointer to the signal to trigger.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckEVENT_Stop(
-    IN gckEVENT Event,
-    IN gctUINT32 ProcessID,
-    IN gctPHYS_ADDR Handle,
-    IN gctSIZE_T Offset,
-    IN gctPOINTER Logical,
-    IN gctUINT32 Address,
-    IN gctSIGNAL Signal,
-    IN OUT gctUINT32 * waitSize
-    )
-{
-    gceSTATUS status;
-   /* gctSIZE_T waitSize;*/
-    gcsEVENT_PTR record = gcvNULL;
-    gctUINT8 id = 0xFF;
-
-    gcmkHEADER_ARG("Event=0x%x ProcessID=%u Handle=0x%x Logical=0x%x "
-                   "Address=0x%x Signal=0x%x",
-                   Event, ProcessID, Handle, Logical, Address, Signal);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
-
-    /* Submit the current event queue. */
-    gcmkONERROR(gckEVENT_Submit(Event, gcvTRUE, gcvFALSE));
-    gcmkONERROR(gckEVENT_GetEvent(Event, gcvTRUE, &id, gcvKERNEL_PIXEL));
-
-    /* Allocate a record. */
-    gcmkONERROR(gckEVENT_AllocateRecord(Event, gcvTRUE, &record));
-
-    /* Initialize the record. */
-    record->next = gcvNULL;
-    record->processID               = ProcessID;
-    record->info.command            = gcvHAL_SIGNAL;
-    record->info.u.Signal.signal    = gcmPTR_TO_UINT64(Signal);
-#ifdef __QNXNTO__
-    record->info.u.Signal.coid      = 0;
-    record->info.u.Signal.rcvid     = 0;
-#endif
-    record->info.u.Signal.auxSignal = 0;
-    record->info.u.Signal.process   = 0;
-
-    /* Append the record. */
-    Event->queues[id].head      = record;
-
-    /* Replace last WAIT with END. */
-    gcmkONERROR(gckHARDWARE_End(
-        Event->kernel->hardware, Logical, Address, waitSize
-        ));
-
-#if USE_KERNEL_VIRTUAL_BUFFERS
-    if (Event->kernel->virtualCommandBuffer)
-    {
-        gcmkONERROR(gckKERNEL_GetGPUAddress(
-            Event->kernel,
-            Logical,
-            gcvFALSE,
-            Event->kernel->command->virtualMemory,
-            &Event->kernel->hardware->lastEnd
-            ));
-    }
-#endif
-
-    /* Flush the cache for the END. */
-    gcmkONERROR(gckOS_CacheClean(
-        Event->os,
-        0,
-        Handle,
-        Offset,
-        Logical,
-        *waitSize
-        ));
-
-    /* Wait for the signal. */
-    gcmkONERROR(gckOS_WaitSignal(Event->os, Signal, gcvFALSE, gcvINFINITE));
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
 static void
 _PrintRecord(
     gcsEVENT_PTR record
@@ -2875,14 +2263,6 @@ _PrintRecord(
 {
     switch (record->info.command)
     {
-    case gcvHAL_FREE_NON_PAGED_MEMORY:
-        gcmkPRINT("      gcvHAL_FREE_NON_PAGED_MEMORY");
-            break;
-
-    case gcvHAL_FREE_CONTIGUOUS_MEMORY:
-        gcmkPRINT("      gcvHAL_FREE_CONTIGUOUS_MEMORY");
-            break;
-
     case gcvHAL_WRITE_DATA:
         gcmkPRINT("      gcvHAL_WRITE_DATA");
        break;
@@ -2892,15 +2272,11 @@ _PrintRecord(
         break;
 
     case gcvHAL_SIGNAL:
-        gcmkPRINT("      gcvHAL_SIGNAL process=%d signal=0x%x",
+        gcmkPRINT("      gcvHAL_SIGNAL process=%lld signal=0x%llx",
                   record->info.u.Signal.process,
                   record->info.u.Signal.signal);
         break;
 
-    case gcvHAL_UNMAP_USER_MEMORY:
-        gcmkPRINT("      gcvHAL_UNMAP_USER_MEMORY");
-       break;
-
     case gcvHAL_TIMESTAMP:
         gcmkPRINT("      gcvHAL_TIMESTAMP");
         break;
@@ -2909,13 +2285,8 @@ _PrintRecord(
         gcmkPRINT("      gcvHAL_COMMIT_DONE");
         break;
 
-    case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
-        gcmkPRINT("      gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER logical=0x%08x",
-                  record->info.u.FreeVirtualCommandBuffer.logical);
-        break;
-
     case gcvHAL_DESTROY_MMU:
-        gcmkPRINT("      gcvHAL_DESTORY_MMU mmu=0x%08x",
+        gcmkPRINT("      gcvHAL_DESTORY_MMU mmu=%p",
                   gcmUINT64_TO_PTR(record->info.u.DestroyMmu.mmu));
 
         break;
@@ -2958,7 +2329,7 @@ gckEVENT_Dump(
         queue = queueHead;
         record = queueHead->head;
 
-        gcmkPRINT("    [%x]:", queue);
+        gcmkPRINT("    [%p]:", queue);
         while(record)
         {
             _PrintRecord(record);
index 5c4835a..325cdd7 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -121,7 +121,7 @@ struct _gckHEAP
     gctUINT64                   timeStamp;
 #endif
 
-#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+#if VIVANTE_PROFILER_SYSTEM_MEMORY || gcmIS_DEBUG(gcdDEBUG_CODE)
     /* Profile information. */
     gctUINT32                   allocCount;
     gctUINT64                   allocBytes;
@@ -284,7 +284,7 @@ _CompactKernelHeap(
                 heap->next->prev = heap->prev;
             }
 
-#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+#if VIVANTE_PROFILER_SYSTEM_MEMORY || gcmIS_DEBUG(gcdDEBUG_CODE)
             /* Update profiling. */
             Heap->heapCount  -= 1;
             Heap->heapMemory -= heap->size + gcmSIZEOF(gcskHEAP);
@@ -382,7 +382,7 @@ gckHEAP_Construct(
     heap->timeStamp      = 0;
 #endif
 
-#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+#if VIVANTE_PROFILER_SYSTEM_MEMORY || gcmIS_DEBUG(gcdDEBUG_CODE)
     /* Zero the counters. */
     heap->allocCount      = 0;
     heap->allocBytes      = 0;
@@ -658,7 +658,7 @@ gckHEAP_Allocate(
     /* No previous free. */
     prevFree = gcvNULL;
 
-#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+#if VIVANTE_PROFILER_SYSTEM_MEMORY || gcmIS_DEBUG(gcdDEBUG_CODE)
     /* Update profiling. */
     Heap->heapCount  += 1;
     Heap->heapMemory += Heap->allocationSize;
@@ -730,7 +730,7 @@ UseNode:
     used->timeStamp = ++Heap->timeStamp;
 #endif
 
-#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+#if VIVANTE_PROFILER_SYSTEM_MEMORY || gcmIS_DEBUG(gcdDEBUG_CODE)
     /* Update profile counters. */
     Heap->allocCount      += 1;
     Heap->allocBytes      += bytes;
@@ -811,7 +811,7 @@ gckHEAP_Free(
     /* Mark the node as freed. */
     node->next = gcvNULL;
 
-#if VIVANTE_PROFILER || gcmIS_DEBUG(gcdDEBUG_CODE)
+#if VIVANTE_PROFILER_SYSTEM_MEMORY || gcmIS_DEBUG(gcdDEBUG_CODE)
     /* Update profile counters. */
     Heap->allocBytes -= node->bytes;
 #endif
@@ -830,7 +830,7 @@ OnError:
     return status;
 }
 
-#if VIVANTE_PROFILER
+#if VIVANTE_PROFILER_SYSTEM_MEMORY
 gceSTATUS
 gckHEAP_ProfileStart(
     IN gckHEAP Heap
@@ -868,7 +868,7 @@ gckHEAP_ProfileEnd(
     gcmkVERIFY_OBJECT(Heap, gcvOBJ_HEAP);
     gcmkVERIFY_ARGUMENT(Title != gcvNULL);
 
-    gcmkPRINT("");
+    gcmkPRINT("\n");
     gcmkPRINT("=====[ HEAP - %s ]=====", Title);
     gcmkPRINT("Number of allocations           : %12u",   Heap->allocCount);
     gcmkPRINT("Number of bytes allocated       : %12llu", Heap->allocBytes);
@@ -884,9 +884,5 @@ gckHEAP_ProfileEnd(
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 }
-#endif /* VIVANTE_PROFILER */
-
-/*******************************************************************************
-***** Test Code ****************************************************************
-*******************************************************************************/
+#endif /* VIVANTE_PROFILER_SYSTEM_MEMORY */
 
index 057fad6..1480e17 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index dd2a58a..ecc6f09 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -57,6 +57,8 @@
 
 #define _GC_OBJ_ZONE    gcvZONE_MMU
 
+#define gcdMMU_PGTABLE_POOL     gcvPOOL_VIRTUAL
+
 typedef enum _gceMMU_TYPE
 {
     gcvMMU_USED     = (0 << 4),
@@ -77,7 +79,7 @@ typedef struct _gcsMMU_STLB_CHUNK *gcsMMU_STLB_CHUNK_PTR;
 
 typedef struct _gcsMMU_STLB_CHUNK
 {
-    gctPHYS_ADDR    physical;
+    gckVIDMEM_NODE  videoMem;
     gctUINT32_PTR   logical;
     gctSIZE_T       size;
     gctPHYS_ADDR_T  physBase;
@@ -172,7 +174,7 @@ _Link(
     IN gctUINT32 Next
     )
 {
-    if (Index >= Area->pageTableEntries)
+    if (Index >= Area->stlbEntries)
     {
         /* Just move heap pointer. */
         Area->heapList = Next;
@@ -244,7 +246,7 @@ _Collect(
     Area->freeNodes = gcvFALSE;
 
     /* Walk the entire page table. */
-    for (i = 0; i < Area->pageTableEntries; ++i)
+    for (i = 0; i < Area->stlbEntries; ++i)
     {
         /* Dispatch based on type of page. */
         switch (gcmENTRY_TYPE(map[i]))
@@ -352,10 +354,14 @@ _AddressToIndex(
     IN gctUINT32 Address
     )
 {
+
+    gctUINT32 stlbShift = (Area->areaType == gcvAREA_TYPE_1M) ? gcdMMU_STLB_1M_SHIFT : gcdMMU_STLB_4K_SHIFT;
+    gctUINT32 stlbMask  = (Area->areaType == gcvAREA_TYPE_1M) ? gcdMMU_STLB_1M_MASK : gcdMMU_STLB_4K_MASK;
+    gctUINT32 stlbEntryNum = (Area->areaType == gcvAREA_TYPE_1M) ? gcdMMU_STLB_1M_ENTRY_NUM : gcdMMU_STLB_4K_ENTRY_NUM;
     gctUINT32 mtlbOffset = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
-    gctUINT32 stlbOffset = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+    gctUINT32 stlbOffset = (Address & stlbMask) >> stlbShift;
 
-    return (mtlbOffset - Area->dynamicMappingStart) * gcdMMU_STLB_4K_ENTRY_NUM + stlbOffset;
+    return (mtlbOffset - Area->mappingStart) * stlbEntryNum + stlbOffset;
 }
 
 static gctUINT32_PTR
@@ -366,7 +372,27 @@ _StlbEntry(
 {
     gctUINT32 index = _AddressToIndex(Area, Address);
 
-    return &Area->pageTableLogical[index];
+    return &Area->stlbLogical[index];
+}
+
+static gctBOOL
+_IsRangeInsected(
+    gctUINT64 baseAddress1,
+    gctSIZE_T size1,
+    gctUINT64 baseAddress2,
+    gctSIZE_T size2
+    )
+{
+    gctUINT64 endAddress1 = baseAddress1 + size1 - 1;
+    gctUINT64 endAddress2 = baseAddress2 + size2 - 1;
+
+    if (!size1 || !size2)
+    {
+        return gcvFALSE;
+    }
+
+    return (((baseAddress2 <= endAddress1) && (endAddress2 >= baseAddress1)) ||
+            ((baseAddress1 <= endAddress2) && (endAddress1 >= baseAddress2)));
 }
 
 static gceSTATUS
@@ -384,7 +410,7 @@ _FillFlatMappingInMap(
     gctUINT32 previous = ~0U;
 
     /* Find node which contains index. */
-    for (i = 0; !gotIt && (i < Area->pageTableEntries);)
+    for (i = 0; !gotIt && (i < Area->stlbEntries);)
     {
         gctUINT32 numPages;
 
@@ -602,182 +628,191 @@ OnError:
     return status;
 }
 
-#if gcdPROCESS_ADDRESS_SPACE
-gctUINT32
-_StlbOffset(
-    gctUINT32 Address
-    )
-{
-    return (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
-}
-
-static gceSTATUS
-_AllocateStlb(
-    IN gckOS Os,
-    OUT gcsMMU_STLB_PTR *Stlb
-    )
-{
-    gceSTATUS status;
-    gcsMMU_STLB_PTR stlb;
-    gctPOINTER pointer;
-
-    /* Allocate slave TLB record. */
-    gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(gcsMMU_STLB), &pointer));
-    stlb = pointer;
-
-    stlb->size = gcdMMU_STLB_4K_SIZE;
-
-    /* Allocate slave TLB entries. */
-    gcmkONERROR(gckOS_AllocateContiguous(
-        Os,
-        gcvFALSE,
-        &stlb->size,
-        &stlb->physical,
-        (gctPOINTER)&stlb->logical
-        ));
-
-    gcmkONERROR(gckOS_GetPhysicalAddress(Os, stlb->logical, &stlb->physBase));
-
-    gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, stlb->physBase, &stlb->physBase));
-
-#if gcdUSE_MMU_EXCEPTION
-    _FillPageTable(stlb->logical, stlb->size / 4, gcdMMU_STLB_EXCEPTION);
-#else
-    gckOS_ZeroMemory(stlb->logical, stlb->size);
-#endif
-
-    *Stlb = stlb;
-
-    return gcvSTATUS_OK;
-
-OnError:
-    return status;
-}
-
-gceSTATUS
-_SetupProcessAddressSpace(
-    IN gckMMU Mmu
-    )
-{
-    gceSTATUS status;
-    gctINT numEntries = 0;
-    gctUINT32_PTR map;
-
-    numEntries = gcdPROCESS_ADDRESS_SPACE_SIZE
-               /* Address space mapped by one MTLB entry. */
-               / (1 << gcdMMU_MTLB_SHIFT);
-
-    area->dynamicMappingStart = 0;
-
-    area->pageTableSize = numEntries * 4096;
-
-    area->pageTableEntries = area->pageTableSize / gcmSIZEOF(gctUINT32);
-
-    gcmkONERROR(gckOS_Allocate(Mmu->os,
-                               area->pageTableSize,
-                               (void **)&area->mapLogical));
-
-    /* Initialization. */
-    map      = area->mapLogical;
-    map[0]   = (area->pageTableEntries << 8) | gcvMMU_FREE;
-    map[1]   = ~0U;
-    area->heapList  = 0;
-    area->freeNodes = gcvFALSE;
-
-    return gcvSTATUS_OK;
-
-OnError:
-    return status;
-}
-#else
 static gceSTATUS
 _FillFlatMapping(
     IN gckMMU Mmu,
     IN gctUINT64 PhysBase,
-    OUT gctSIZE_T Size,
+    IN gctSIZE_T Size,
+    IN gctBOOL   reserved,
+    IN gctBOOL   ableToShift,
     OUT gctUINT32 *GpuBaseAddress
     )
 {
     gceSTATUS status;
     gctUINT32 mtlb;
     gctUINT32 physBase;
-    gcsADDRESS_AREA_PTR area = &Mmu->area[0];
-
-    /************************ look up existing flat mapping ranges. ****************/
+    gckKERNEL kernel = Mmu->hardware->kernel;
+    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea4K;
+    gctBOOL physicalRangeOverlapped = gcvFALSE;
+    gctBOOL virtualRangeOverlapped = gcvFALSE;
+    gctBOOL specificFlatMapping = gcvFALSE;
+    gctBOOL needShiftMapping = gcvFALSE;
     gctUINT64 flatBase = PhysBase;
-    gctUINT32 flatSize = (gctUINT32)Size;
+    gctUINT32 flatSize = (gctUINT32) Size;
     gctUINT64 base = flatBase;
-    gctUINT32 size = flatSize;
-    gctUINT64 end  = base + size;
+    gctUINT64 end  = base + flatSize;
+    gctUINT32 reqVirtualBase = 0;
+    gctUINT32 flatVirtualBase = 0;
     gctUINT32 i;
 
-    for (i = 0; i < Mmu->flatMappingRangeCount; i++)
+    /************************ Get flat mapping type and range. ************************/
     {
-        if (base < Mmu->flatMappingRanges[i].start)
-        {
-            end  = gcmMIN(end, Mmu->flatMappingRanges[i].start);
-            flatSize = (gctUINT32) (end - base);
-        }
-        else if (end > Mmu->flatMappingRanges[i].end)
+        for (i = 0; i < Mmu->gpuPhysicalRangeCount; i++)
         {
-            base = gcmMAX(base, Mmu->flatMappingRanges[i].end);
+            if (base < Mmu->gpuPhysicalRanges[i].start)
+            {
+                if (end > Mmu->gpuPhysicalRanges[i].start)
+                {
+                    physicalRangeOverlapped = gcvTRUE;
+                    if (Mmu->gpuPhysicalRanges[i].flag == gcvFLATMAP_DIRECT)
+                    {
+                        /* Overlapped part is direct mapping, continue direct mapping */
+                        end = Mmu->gpuPhysicalRanges[i].start;
+                    }
+                    else
+                    {
+                        /* Overlapped part is shift mapping, do entire shift mapping */
+                        needShiftMapping = gcvTRUE;
+                    }
+                }
 
-            flatBase = base;
-            flatSize = (gctUINT32) (end - base);
-        }
-        else
-        {
-            /* it is already inside existing flat mapping ranges. */
-            flatSize = 0;
-        }
+                flatSize = (gctUINT32) (end - base);
+            }
+            else if (end > Mmu->gpuPhysicalRanges[i].end)
+            {
+                if (base < Mmu->gpuPhysicalRanges[i].end)
+                {
+                    physicalRangeOverlapped = gcvTRUE;
+                    if (Mmu->gpuPhysicalRanges[i].flag == gcvFLATMAP_DIRECT)
+                    {
+                        /* Overlapped part is direct mapping, continue direct mapping */
+                        base = Mmu->gpuPhysicalRanges[i].end + 1;
+                    }
+                    else
+                    {
+                        /* Overlapped part is shift mapping, do entire shift mapping */
+                        needShiftMapping = gcvTRUE;
+                    }
 
-        if (flatSize == 0)
-        {
-            if (GpuBaseAddress)
+                }
+
+                flatBase = base;
+                flatSize = (gctUINT32) (end - base);
+            }
+            else
             {
-                *GpuBaseAddress = (gctUINT32) PhysBase;
+                /* it is already inside existing flat mapping ranges. */
+                flatSize = 0;
             }
 
-            return gcvSTATUS_OK;
+            if (flatSize == 0)
+            {
+                if (GpuBaseAddress)
+                {
+                    *GpuBaseAddress = (gctUINT32) PhysBase;
+                }
+
+                return gcvSTATUS_OK;
+            }
         }
     }
 
-    Mmu->flatMappingRanges[Mmu->flatMappingRangeCount].start = flatBase;
-    Mmu->flatMappingRanges[Mmu->flatMappingRangeCount].end = flatBase + flatSize;
-    Mmu->flatMappingRangeCount++;
-
-    gcmkASSERT(Mmu->flatMappingRangeCount <= gcdMAX_FLAT_MAPPING_COUNT);
-
     /* overwrite the orignal parameters */
     PhysBase = flatBase;
     physBase = (gctUINT32)flatBase;
-    Size = (gctSIZE_T)flatSize;
 
     mtlb = _MtlbOffset(physBase);
 
-    /************************ Setup flat mapping in dynamic range. ****************/
+    if (GpuBaseAddress)
+    {
+        reqVirtualBase = *GpuBaseAddress;
+    }
+
+    /*
+     * if no partcial physical range overlap to request entire shift mapping,
+     * it is specific shift mapping or directly mapping by default.
+     */
+    if (!needShiftMapping)
+    {
+        flatVirtualBase = reqVirtualBase ? reqVirtualBase : (gctUINT32)flatBase;
+    }
+
+    for (i = 0; i < Mmu->gpuAddressRangeCount; i++)
+    {
+        if (_IsRangeInsected(flatVirtualBase, flatSize,
+            Mmu->gpuAddressRanges[i].start,  Mmu->gpuAddressRanges[i].size))
+        {
+            virtualRangeOverlapped = gcvTRUE;
+        }
+    }
+
+    /* If gpu virtual range overlapped or gpu physical over 4G, still need entire shift mapping */
+    if ((!physicalRangeOverlapped && virtualRangeOverlapped) ||
+        PhysBase + flatSize - 1 > 0xffffffff)
+    {
+        needShiftMapping = gcvTRUE;
+    }
 
-    if (area->dynamicMappingStart != gcvINVALID_ADDRESS && mtlb >= area->dynamicMappingStart &&
-       _MtlbOffset(PhysBase + Size - 1) < area->dynamicMappingEnd)
+    if (needShiftMapping && !ableToShift)
     {
+        /*
+         * Return without mapping any address.
+         * By now, only physBase physSize could run here.
+         */
+        return gcvSTATUS_OK;
+    }
+
+    specificFlatMapping = (reqVirtualBase && !virtualRangeOverlapped && !physicalRangeOverlapped);
+
+    /************************ Setup flat mapping in dynamic range. ****************/
+    if (area->mappingStart != gcvINVALID_ADDRESS && mtlb >= area->mappingStart && mtlb < area->mappingEnd)
+    {
+        /* This path is useless now, keep it 4K page size */
+
         gctUINT32_PTR stlbEntry;
-        gctUINT i;
 
         stlbEntry = _StlbEntry(area, physBase);
 
         /* Must be aligned to page. */
-        gcmkASSERT((Size & 0xFFF) == 0);
+        gcmkASSERT((flatSize & 0xFFF) == 0);
 
-        for (i = 0; i < (Size / 4096); i++)
+        for (i = 0; i < (flatSize / gcdMMU_PAGE_4K_SIZE); i++)
         {
             /* Flat mapping in page table. */
-            _WritePageEntry(stlbEntry, _SetPage(physBase + i * 4096, 0, gcvTRUE));
+            _WritePageEntry(stlbEntry, _SetPage(physBase + i * gcdMMU_PAGE_4K_SIZE, 0, gcvTRUE));
+#if gcdMMU_TABLE_DUMP
+            gckOS_Print("%s(%d): insert MTLB[%d] STLB[%d]: %08x\n",
+                __FUNCTION__, __LINE__,
+                (physBase & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT,
+                ((physBase & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT) + i,
+                _ReadPageEntry(stlbEntry));
+#endif
+            stlbEntry++;
         }
 
-        gcmkSAFECASTSIZET(size, Size);
+#if gcdDUMP_IN_KERNEL
+        {
+            gctPHYS_ADDR_T physical;
+            gctUINT32 data = _SetPage(physBase, 0, gcvTRUE) & ~0xF;
+            gctUINT32 step = (_SetPage(physBase + gcdMMU_PAGE_4K_SIZE, 0, gcvTRUE) & ~0xF) - data;
+            gctUINT32 mask = _SetPage(physBase, 0, gcvTRUE) & 0xF;
+
+            physical  = area->stlbPhysical + 4 * _AddressToIndex(area, physBase);
+
+            gcmkDUMP(Mmu->os,
+                     "#[mmu-stlb: flat-mapping in dynamic: 0x%08X - 0x%08X]",
+                     physBase, physBase - 1 + flatSize);
+
+            gcmkDUMP(Mmu->os,
+                     "@[physical.step 0x%010llX 0x%08X 0x%08lX 0x%08X 0x%08X",
+                     (unsigned long long)physical, data,
+                     (unsigned long)(flatSize / gcdMMU_PAGE_4K_SIZE * sizeof(gctUINT32)),
+                     step, mask);
+        }
+#endif
 
         /* Flat mapping in map. */
-        _FillFlatMappingInMap(area, _AddressToIndex(area, physBase), size / 4096);
+        _FillFlatMappingInMap(area, _AddressToIndex(area, physBase), flatSize / gcdMMU_PAGE_4K_SIZE);
 
         return gcvSTATUS_OK;
     }
@@ -786,12 +821,12 @@ _FillFlatMapping(
     {
         gctBOOL mutex = gcvFALSE;
         gctUINT32 physBaseExt = (gctUINT32) (PhysBase >> 32);
-        gctUINT32 start = physBase & ~gcdMMU_PAGE_64K_MASK;
-        gctUINT32 end = (gctUINT32) (physBase + Size - 1) & ~gcdMMU_PAGE_64K_MASK;
+        gctUINT32 start = physBase & ~gcdMMU_PAGE_1M_MASK;
+        gctUINT32 end = (gctUINT32) (physBase + flatSize - 1) & ~gcdMMU_PAGE_1M_MASK;
         gctUINT32 mStart = start >> gcdMMU_MTLB_SHIFT;
         gctUINT32 mEnd = end >> gcdMMU_MTLB_SHIFT;
-        gctUINT32 sStart = (start & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
-        gctUINT32 sEnd = (end & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
+        gctUINT32 sStart = (start & gcdMMU_STLB_1M_MASK) >> gcdMMU_STLB_1M_SHIFT;
+        gctUINT32 sEnd = (end & gcdMMU_STLB_1M_MASK) >> gcdMMU_STLB_1M_SHIFT;
         gctPHYS_ADDR_T physical;
         gcsMMU_STLB_CHUNK_PTR newStlbChunk = gcvNULL;
         gctUINT32 stlbIndex = 0;
@@ -799,32 +834,55 @@ _FillFlatMapping(
         gctINT32 firstMtlbEntry = -1;
         gctUINT32 mtlbCurEntry;
         gcsMMU_STLB_CHUNK_PTR curStlbChunk = gcvNULL;
-        gctUINT32 seqs[2] = {0, 0};
-        gctUINT32 seqIdx = 0;
+        gceFLATMAP_FLAG mapFlag = gcvFLATMAP_DIRECT;
+        enum
+        {
+            COLOR_NONE   = 0,
+            COLOR_RED    = 1, /* occupied entry */
+            COLOR_BLUE   = 2, /* empty entry */
+            COLOR_MAX    = COLOR_BLUE,
+        } lastColor = COLOR_NONE;
+        gctUINT32 colorNumber = 0;
 
         /* Grab the mutex. */
         gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
         mutex = gcvTRUE;
 
-        if (PhysBase + Size - 1 > 0xffffffff)
+        if (needShiftMapping)
         {
             gctUINT32 mEntries;
             gctUINT32 sEntries;
 
-            mEntries = (gctUINT32)(Size + (1 << gcdMMU_MTLB_SHIFT) - 1) / (1 << gcdMMU_MTLB_SHIFT);
+            mEntries = (flatSize + (1 << gcdMMU_MTLB_SHIFT) - 1) / (1 << gcdMMU_MTLB_SHIFT);
 
             gcmkONERROR(_GetMtlbFreeSpace(Mmu, mEntries, &mStart, &mEnd));
 
             sStart = 0;
-            sEntries = (gctUINT32)(Size + gcdMMU_PAGE_64K_SIZE - 1) / gcdMMU_PAGE_64K_SIZE;
-            sEnd = (sEntries - 1) % gcdMMU_STLB_64K_ENTRY_NUM;
+            sEntries = (flatSize + gcdMMU_PAGE_1M_SIZE - 1) / gcdMMU_PAGE_1M_SIZE;
+            sEnd = (sEntries - 1) % gcdMMU_STLB_1M_ENTRY_NUM;
+            mapFlag = gcvFLATMAP_SHIFT;
         }
 
+        if (specificFlatMapping)
+        {
+            start    = reqVirtualBase & ~gcdMMU_PAGE_1M_MASK;
+            end      = (reqVirtualBase + flatSize - 1) & ~gcdMMU_PAGE_1M_MASK;
+            mStart   = start >> gcdMMU_MTLB_SHIFT;
+            mEnd     = end >> gcdMMU_MTLB_SHIFT;
+            sStart   = (start & gcdMMU_STLB_1M_MASK) >> gcdMMU_STLB_1M_SHIFT;
+            sEnd     = (end & gcdMMU_STLB_1M_MASK) >> gcdMMU_STLB_1M_SHIFT;
+            mapFlag  = gcvFLATMAP_SHIFT;
+        }
+
+        /* No matter direct mapping or shift mapping or specific mapping, store gpu virtual ranges */
+        flatVirtualBase = (mStart << gcdMMU_MTLB_SHIFT)
+                        | (sStart << gcdMMU_STLB_1M_SHIFT)
+                        | (physBase & gcdMMU_PAGE_1M_MASK);
+
+        /* Return GPU virtual base address if necessary */
         if (GpuBaseAddress)
         {
-            *GpuBaseAddress = (mStart << gcdMMU_MTLB_SHIFT)
-                            | (sStart << gcdMMU_STLB_64K_SHIFT)
-                            | (physBase & gcdMMU_PAGE_64K_MASK);
+            *GpuBaseAddress = flatVirtualBase;
         }
 
         mtlbCurEntry = mStart;
@@ -834,25 +892,19 @@ _FillFlatMapping(
         {
             if (*(Mmu->mtlbLogical + mtlbCurEntry) == 0)
             {
-                if (seqIdx < 2)
+                if (lastColor != COLOR_BLUE)
                 {
-                    if (seqs[seqIdx] != 2)
+                    if (colorNumber < COLOR_MAX)
                     {
-                        seqs[seqIdx] = 1;
-                    }
-                    else if (seqIdx < 1)
-                    {
-                        seqs[++seqIdx] = 1;
+                        lastColor = COLOR_BLUE;
+                        colorNumber++;
                     }
                     else
                     {
-                        gcmkASSERT(gcvFALSE);
+                        gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
                     }
                 }
-                else if (seqs[1] != 1)
-                {
-                    gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
-                }
+
                 totalNewStlbs++;
                 if (-1 == firstMtlbEntry)
                 {
@@ -861,25 +913,18 @@ _FillFlatMapping(
             }
             else
             {
-                if (seqIdx < 2)
+                if (lastColor != COLOR_RED)
                 {
-                    if (seqs[seqIdx] != 1)
-                    {
-                        seqs[seqIdx] = 2;
-                    }
-                    else if (seqIdx < 1)
+                    if (colorNumber < COLOR_MAX)
                     {
-                        seqs[++seqIdx] = 2;
+                        lastColor = COLOR_RED;
+                        colorNumber++;
                     }
                     else
                     {
-                        gcmkASSERT(gcvFALSE);
+                        gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
                     }
                 }
-                else if (seqs[1] != 2)
-                {
-                    gcmkPRINT("There is a hole in new flat mapping range, which is not correct");
-                }
             }
             mtlbCurEntry++;
         }
@@ -887,6 +932,7 @@ _FillFlatMapping(
         /* Need allocate a new chunk of stlbs */
         if (totalNewStlbs)
         {
+            gcePOOL pool = gcdMMU_PGTABLE_POOL;
             gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
 
             gcmkONERROR(
@@ -896,9 +942,9 @@ _FillFlatMapping(
 
             newStlbChunk->mtlbEntryNum = totalNewStlbs;
             newStlbChunk->next = gcvNULL;
-            newStlbChunk->physical = gcvNULL;
+            newStlbChunk->videoMem = gcvNULL;
             newStlbChunk->logical = gcvNULL;
-            newStlbChunk->size = gcdMMU_STLB_64K_SIZE * newStlbChunk->mtlbEntryNum;
+            newStlbChunk->size = gcdMMU_STLB_1M_SIZE * newStlbChunk->mtlbEntryNum;
             newStlbChunk->pageCount = 0;
             newStlbChunk->mtlbIndex = firstMtlbEntry;
 
@@ -906,19 +952,30 @@ _FillFlatMapping(
             allocFlag |= gcvALLOC_FLAG_CACHEABLE;
 #endif
 
-            gcmkONERROR(
-                    gckOS_AllocateNonPagedMemory(Mmu->os,
-                                                 gcvFALSE,
-                                                 allocFlag,
-                                                 &newStlbChunk->size,
-                                                 &newStlbChunk->physical,
-                                                 (gctPOINTER)&newStlbChunk->logical));
+            gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+                kernel,
+                gcdMMU_STLB_1M_SIZE,
+                gcvVIDMEM_TYPE_COMMAND,
+                allocFlag | gcvALLOC_FLAG_4K_PAGES,
+                &newStlbChunk->size,
+                &pool,
+                &newStlbChunk->videoMem));
+
+            /* Lock for kernel side CPU access. */
+            gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+                kernel,
+                newStlbChunk->videoMem,
+                gcvFALSE,
+                gcvFALSE,
+                (gctPOINTER *)&newStlbChunk->logical));
 
             gcmkONERROR(gckOS_ZeroMemory(newStlbChunk->logical, newStlbChunk->size));
 
-            gcmkONERROR(gckOS_GetPhysicalAddress(
-                Mmu->os,
-                newStlbChunk->logical,
+            /* Get CPU physical address. */
+            gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+                kernel,
+                newStlbChunk->videoMem,
+                0,
                 &physical));
 
             gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
@@ -926,17 +983,12 @@ _FillFlatMapping(
                 physical,
                 &physical));
 
-            gcmkSAFECASTPHYSADDRT(newStlbChunk->physBase, physical);
-
-            if (newStlbChunk->physBase & (gcdMMU_STLB_64K_SIZE - 1))
-            {
-                gcmkONERROR(gcvSTATUS_NOT_ALIGNED);
-            }
+            newStlbChunk->physBase = physical;
         }
 
         while (mStart <= mEnd)
         {
-            gctUINT32 last = (mStart == mEnd) ? sEnd : (gcdMMU_STLB_64K_ENTRY_NUM - 1);
+            gctUINT32 last = (mStart == mEnd) ? sEnd : (gcdMMU_STLB_1M_ENTRY_NUM - 1);
             gctPHYS_ADDR_T stlbPhyBase;
             gctUINT32_PTR stlbLogical;
 
@@ -946,11 +998,12 @@ _FillFlatMapping(
             {
                 gctUINT32 mtlbEntry;
                 curStlbChunk = newStlbChunk;
-                stlbPhyBase = curStlbChunk->physBase + (stlbIndex * gcdMMU_STLB_64K_SIZE);
-                stlbLogical = (gctUINT32_PTR)((gctUINT8_PTR)curStlbChunk->logical + (stlbIndex * gcdMMU_STLB_64K_SIZE));
+                stlbPhyBase = curStlbChunk->physBase + (stlbIndex * gcdMMU_STLB_1M_SIZE);
+                stlbLogical = (gctUINT32_PTR)((gctUINT8_PTR)curStlbChunk->logical + (stlbIndex * gcdMMU_STLB_1M_SIZE));
+
                 physical  = stlbPhyBase
-                          /* 64KB page size */
-                          | (1 << 2)
+                          /* 1MB page size */
+                          | (1 << 3)
                           /* Ignore exception */
                           | (0 << 1)
                           /* Present */
@@ -965,14 +1018,19 @@ _FillFlatMapping(
                     __FUNCTION__, __LINE__,
                     mStart,
                     _ReadPageEntry(Mmu->mtlbLogical + mStart));
-#endif
 
-#if gcdMMU_TABLE_DUMP
                 gckOS_Print("%s(%d): STLB: logical:%08x -> physical:%08x\n",
                         __FUNCTION__, __LINE__,
                         stlbLogical,
                         stlbPhyBase);
 #endif
+
+                gcmkDUMP(Mmu->os, "#[mmu-mtlb: flat-mapping, slot: %d]", mStart);
+
+                gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                         (unsigned long long)Mmu->mtlbPhysical + mStart * 4,
+                         Mmu->mtlbLogical[mStart], 4);
+
                 ++stlbIndex;
             }
             else
@@ -992,22 +1050,40 @@ _FillFlatMapping(
                     curStlbChunk = curStlbChunk->next;
                 }
                 gcmkASSERT(curStlbChunk);
+
+                if (!curStlbChunk)
+                    gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+
                 stlbOffset = mStart - curStlbChunk->mtlbIndex;
 
-                stlbPhyBase = curStlbChunk->physBase + (stlbOffset * gcdMMU_STLB_64K_SIZE);
-                stlbLogical = (gctUINT32_PTR)((gctUINT8_PTR)curStlbChunk->logical + (stlbOffset * gcdMMU_STLB_64K_SIZE));
+                stlbPhyBase = curStlbChunk->physBase + (stlbOffset * gcdMMU_STLB_1M_SIZE);
+                stlbLogical = (gctUINT32_PTR)((gctUINT8_PTR)curStlbChunk->logical + (stlbOffset * gcdMMU_STLB_1M_SIZE));
                 if (stlbPhyBase != (mtlbEntry & gcdMMU_MTLB_ENTRY_STLB_MASK))
                 {
                     gcmkASSERT(0);
                 }
             }
 
-            while (sStart <= last)
-            {
-                gcmkASSERT(!(start & gcdMMU_PAGE_64K_MASK));
+#if gcdDUMP_IN_KERNEL
+            /* Start index. */
+            i = sStart;
 
-                _WritePageEntry(stlbLogical + sStart, _SetPage(start, physBaseExt, gcvTRUE));
+            gcmkDUMP(Mmu->os, "#[mmu-stlb: flat-mapping: 0x%08X - 0x%08X]",
+                     start, start + (last - sStart) * gcdMMU_PAGE_1M_SIZE - 1);
+#endif
 
+            while (sStart <= last)
+            {
+                gcmkASSERT(!(start & gcdMMU_PAGE_1M_MASK));
+                if (reserved)
+                {
+                    /* program NOT_PRESENT | EXCEPTION  for reserved entries */
+                    _WritePageEntry(stlbLogical + sStart, 1 << 1);
+                }
+                else
+                {
+                    _WritePageEntry(stlbLogical + sStart, _SetPage(start, physBaseExt, gcvTRUE));
+                }
 #if gcdMMU_TABLE_DUMP
                 gckOS_Print("%s(%d): insert STLB[%d]: %08x\n",
                     __FUNCTION__, __LINE__,
@@ -1015,7 +1091,7 @@ _FillFlatMapping(
                     _ReadPageEntry(stlbLogical + sStart));
 #endif
                 /* next page. */
-                start += gcdMMU_PAGE_64K_SIZE;
+                start += gcdMMU_PAGE_1M_SIZE;
                 if (start == 0)
                 {
                     physBaseExt++;
@@ -1024,11 +1100,22 @@ _FillFlatMapping(
                 curStlbChunk->pageCount++;
             }
 
-            /* Flush STLB table. */
-            gcmkONERROR(gckOS_CacheClean(
-                Mmu->os,
-                0,
-                curStlbChunk->physical,
+#if gcdDUMP_IN_KERNEL
+            {
+                gctUINT32 data = stlbLogical[i] & ~0xF;
+                gctUINT32 step = (last > i) ? (stlbLogical[i + 1] - stlbLogical[i]) : 0;
+                gctUINT32 mask = stlbLogical[i] & 0xF;
+
+                gcmkDUMP(Mmu->os,
+                         "@[physical.step 0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X]",
+                         (unsigned long long)stlbPhyBase + i * 4,
+                         data, (last - i) * 4, step, mask);
+            }
+#endif
+
+            gcmkONERROR(gckVIDMEM_NODE_CleanCache(
+                kernel,
+                curStlbChunk->videoMem,
                 0,
                 curStlbChunk->logical,
                 curStlbChunk->size
@@ -1062,10 +1149,29 @@ _FillFlatMapping(
 #if gcdENABLE_TRUST_APPLICATION
         if (Mmu->hardware->options.secureMode == gcvSECURE_IN_TA)
         {
-            gckKERNEL_SecurityMapMemory(Mmu->hardware->kernel, gcvNULL, physBase, (gctUINT32)Size/4096, &physBase);
+            gckKERNEL_SecurityMapMemory(Mmu->hardware->kernel, gcvNULL, physBase, flatSize / gcdMMU_PAGE_4K_SIZE, &physBase);
         }
 #endif
 
+        /* Store the gpu physical ranges */
+        Mmu->gpuPhysicalRanges[Mmu->gpuPhysicalRangeCount].start = flatBase;
+        Mmu->gpuPhysicalRanges[Mmu->gpuPhysicalRangeCount].end   = flatBase + flatSize - 1;
+        Mmu->gpuPhysicalRanges[Mmu->gpuPhysicalRangeCount].size  = flatSize;
+        Mmu->gpuPhysicalRanges[Mmu->gpuPhysicalRangeCount].flag  = mapFlag;
+        Mmu->gpuPhysicalRangeCount++;
+
+        gcmkASSERT(Mmu->gpuPhysicalRangeCount <= gcdMAX_FLAT_MAPPING_COUNT);
+
+        /* Store the gpu virtual ranges */
+        Mmu->gpuAddressRanges[Mmu->gpuAddressRangeCount].start = flatVirtualBase;
+        Mmu->gpuAddressRanges[Mmu->gpuAddressRangeCount].end   = flatVirtualBase + flatSize - 1;
+        Mmu->gpuAddressRanges[Mmu->gpuAddressRangeCount].size  = flatSize;
+        Mmu->gpuAddressRanges[Mmu->gpuAddressRangeCount].flag  = mapFlag;
+        Mmu->gpuAddressRangeCount++;
+
+        gcmkASSERT(Mmu->gpuAddressRangeCount <= gcdMAX_FLAT_MAPPING_COUNT);
+
+
         return gcvSTATUS_OK;
 OnError:
         /* Roll back the allocation.
@@ -1074,14 +1180,14 @@ OnError:
         */
         if (newStlbChunk)
         {
-            if (newStlbChunk->physical)
+            if (newStlbChunk->videoMem)
             {
-                gcmkVERIFY_OK(
-                    gckOS_FreeContiguous(Mmu->os,
-                        newStlbChunk->physical,
-                        newStlbChunk->logical,
-                        newStlbChunk->size));
+                gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+                    kernel,
+                    newStlbChunk->videoMem
+                    ));
             }
+
             gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, newStlbChunk));
         }
         if (mutex)
@@ -1102,17 +1208,19 @@ _SetupAddressArea(
 {
     gceSTATUS status;
     gctUINT32_PTR map;
+    gctUINT32 stlbSize = (Area->areaType == gcvAREA_TYPE_1M)
+                       ? gcdMMU_STLB_1M_SIZE : gcdMMU_STLB_4K_SIZE;
 
     gcmkHEADER();
-    Area->pageTableSize = NumMTLBEntries * 4096;
+    Area->stlbSize = NumMTLBEntries * stlbSize;
 
-    gcmkSAFECASTSIZET(Area->pageTableEntries, Area->pageTableSize / gcmSIZEOF(gctUINT32));
+    gcmkSAFECASTSIZET(Area->stlbEntries, Area->stlbSize / gcmSIZEOF(gctUINT32));
 
-    gcmkONERROR(gckOS_Allocate(Os, Area->pageTableSize, (void **)&Area->mapLogical));
+    gcmkONERROR(gckOS_Allocate(Os, Area->stlbSize, (void **)&Area->mapLogical));
 
     /* Initialization. */
     map      = Area->mapLogical;
-    map[0]   = (Area->pageTableEntries << 8) | gcvMMU_FREE;
+    map[0]   = (Area->stlbEntries << 8) | gcvMMU_FREE;
     map[1]   = ~0U;
     Area->heapList  = 0;
     Area->freeNodes = gcvFALSE;
@@ -1126,110 +1234,120 @@ OnError:
 }
 
 static gceSTATUS
-_SetupDynamicSpace(
-    IN gckMMU Mmu
+_ConstructDynamicStlb(
+    IN gckMMU Mmu,
+    IN gcsADDRESS_AREA_PTR Area,
+    IN gctUINT32 NumEntries
     )
 {
-    gceSTATUS status;
-    gcsFreeSpaceNode_PTR nodeArray = gcvNULL;
-    gctINT i, nodeArraySize = 0;
-    gctPHYS_ADDR_T physical;
-    gctUINT32 address;
-    gctINT numEntries = 0;
+    gceSTATUS status = gcvSTATUS_OK;
     gctBOOL acquired = gcvFALSE;
-    gctUINT32 mtlbEntry;
-    gcsADDRESS_AREA_PTR area = &Mmu->area[0];
-    gcsADDRESS_AREA_PTR areaSecure = &Mmu->area[gcvADDRESS_AREA_SECURE];
-    gctUINT32 secureAreaSize = 0;
+    gckKERNEL kernel = Mmu->hardware->kernel;
     gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
-
-    /* Find all the free address space. */
-    gcmkONERROR(_CollectFreeSpace(Mmu, &nodeArray, &nodeArraySize));
-
-    for (i = 0; i < nodeArraySize; i++)
-    {
-        if (nodeArray[i].entries > numEntries)
-        {
-            area->dynamicMappingStart = nodeArray[i].start;
-            numEntries                = nodeArray[i].entries;
-            area->dynamicMappingEnd   = area->dynamicMappingStart + numEntries;
-        }
-    }
-
-    gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
-
-#if gcdENABLE_TRUST_APPLICATION
-    if (gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_SECURITY) == gcvSTATUS_TRUE)
-    {
-        secureAreaSize = gcdMMU_SECURE_AREA_SIZE;
-    }
-#endif
-
-    /* Setup secure address area if need. */
-    if (secureAreaSize > 0)
-    {
-        gcmkASSERT(numEntries > (gctINT)secureAreaSize);
-
-        areaSecure->dynamicMappingStart = area->dynamicMappingStart
-                                        + (numEntries - secureAreaSize);
-
-        gcmkONERROR(_SetupAddressArea(Mmu->os, areaSecure, secureAreaSize));
-
-        numEntries -= secureAreaSize;
-    }
-
-    /* Setup normal address area. */
-    gcmkONERROR(_SetupAddressArea(Mmu->os, area, numEntries));
+    gcePOOL pool = gcdMMU_PGTABLE_POOL;
+    gctUINT32 address;
+    gctUINT32 mtlbEntry;
+    gctUINT32 i;
 
 #if gcdENABLE_CACHEABLE_COMMAND_BUFFER
     allocFlag |= gcvALLOC_FLAG_CACHEABLE;
 #endif
 
     /* Construct Slave TLB. */
-    gcmkONERROR(gckOS_AllocateNonPagedMemory(Mmu->os,
+    gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+                kernel,
+                64,
+                gcvVIDMEM_TYPE_COMMAND,
+                allocFlag | gcvALLOC_FLAG_4K_PAGES,
+                &Area->stlbSize,
+                &pool,
+                &Area->stlbVideoMem));
+
+    /* Lock for kernel side CPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+                kernel,
+                Area->stlbVideoMem,
+                gcvFALSE,
                 gcvFALSE,
-                allocFlag,
-                &area->pageTableSize,
-                &area->pageTablePhysical,
-                (gctPOINTER)&area->pageTableLogical));
+                (gctPOINTER *)&Area->stlbLogical));
 
 #if gcdUSE_MMU_EXCEPTION
-    gcmkONERROR(_FillPageTable(area->pageTableLogical,
-                               area->pageTableEntries,
+    gcmkONERROR(_FillPageTable(Area->stlbLogical,
+                               Area->stlbEntries,
                                /* Enable exception */
                                1 << 1));
 #else
     /* Invalidate all entries. */
-    gcmkONERROR(gckOS_ZeroMemory(area->pageTableLogical,
-                area->pageTableSize));
+    gcmkONERROR(gckOS_ZeroMemory(Area->stlbLogical,
+                Area->stlbSize));
 #endif
 
-    gcmkONERROR(gckOS_GetPhysicalAddress(Mmu->os,
-                area->pageTableLogical,
-                &physical));
+    /* Get stlb table physical. */
+    gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+                kernel,
+                Area->stlbVideoMem,
+                0,
+                &Area->stlbPhysical));
 
     gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Mmu->os,
-                physical,
-                &physical));
+                  Area->stlbPhysical,
+                  &Area->stlbPhysical));
 
-    gcmkSAFECASTPHYSADDRT(address, physical);
+    if (Area->areaType == gcvAREA_TYPE_1M)
+    {
+        gcmkDUMP(Mmu->os, "#[mmu: 1M page size dynamic space: 0x%08X - 0x%08X]",
+                 (Area->mappingStart << gcdMMU_MTLB_SHIFT),
+                 (Area->mappingEnd << gcdMMU_MTLB_SHIFT) - 1);
+    }
+    else
+    {
+        gcmkDUMP(Mmu->os, "#[mmu: 4K page size dynamic space: 0x%08X - 0x%08X]",
+                 (Area->mappingStart << gcdMMU_MTLB_SHIFT),
+                 (Area->mappingEnd << gcdMMU_MTLB_SHIFT) - 1);
+    }
+
+    gcmkDUMP(Mmu->os, "#[mmu-stlb]");
+
+    gcmkDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 0x%08lX]",
+             (unsigned long long)Area->stlbPhysical,
+             Area->stlbLogical[0],
+             (unsigned long)Area->stlbSize);
+
+    gcmkSAFECASTPHYSADDRT(address, Area->stlbPhysical);
 
     /* Grab the mutex. */
     gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
     acquired = gcvTRUE;
 
     /* Map to Master TLB. */
-    for (i = (gctINT)area->dynamicMappingStart;
-         i < (gctINT)area->dynamicMappingStart + numEntries;
+    for (i = Area->mappingStart;
+         i < Area->mappingStart + NumEntries;
          i++)
     {
-        mtlbEntry = address
-                  /* 4KB page size */
-                  | (0 << 2)
-                  /* Ignore exception */
-                  | (0 << 1)
-                  /* Present */
-                  | (1 << 0);
+        if (Area->areaType == gcvAREA_TYPE_1M)
+        {
+            mtlbEntry = address
+                      /* 1M page size */
+                      | (1 << 3)
+                      /*Ignore exception */
+                      | (0 << 1)
+                      /* Present */
+                      | (1 << 0);
+
+            address += gcdMMU_STLB_1M_SIZE;
+        }
+        else
+        {
+            mtlbEntry = address
+                      /* 4KB page size */
+                      | (0 << 2)
+                      /*Ignore exception */
+                      | (0 << 1)
+                      /* Present */
+                      | (1 << 0);
+
+            address += gcdMMU_STLB_4K_SIZE;
+        }
 
         _WritePageEntry(Mmu->mtlbLogical + i, mtlbEntry);
 
@@ -1239,37 +1357,143 @@ _SetupDynamicSpace(
                 i,
                 _ReadPageEntry(Mmu->mtlbLogical + i));
 #endif
-        address += gcdMMU_STLB_4K_SIZE;
     }
 
-    /* Release the mutex. */
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+    gcmkDUMP(Mmu->os, "#[mmu-mtlb: slot: %d - %d]",
+             Area->mappingStart, Area->mappingEnd - 1);
+
+#if gcdDUMP_IN_KERNEL
+    {
+        gctUINT32 data = Mmu->mtlbLogical[Area->mappingStart] & ~0x3F;
+        gctUINT32 step = 0;
+        gctUINT32 mask = Mmu->mtlbLogical[Area->mappingStart] & 0x3F;
+
+        if (NumEntries > 1)
+        {
+            step = Mmu->mtlbLogical[Area->mappingStart + 1]
+                 - Mmu->mtlbLogical[Area->mappingStart];
+        }
+
+        gcmkDUMP(Mmu->os,
+                 "@[physical.step 0x%010llX 0x%08X 0x%08X 0x%08X 0x%08X]",
+                 (unsigned long long)(Mmu->mtlbPhysical + Area->mappingStart * 4),
+                 data, NumEntries * 4, step, mask);
+    }
+#endif
+
+OnError:
+    if (acquired)
+    {
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+    }
+
+    return status;
+}
+
+gceSTATUS
+gckMMU_SetupDynamicSpace(
+    IN gckMMU Mmu
+    )
+{
+    gceSTATUS status;
+    gcsFreeSpaceNode_PTR nodeArray = gcvNULL;
+    gctINT i, nodeArraySize = 0;
+    gctINT numEntries = 0;
+    gckKERNEL kernel = Mmu->hardware->kernel;
+    gcsADDRESS_AREA_PTR area4K = &Mmu->dynamicArea4K;
+#if gcdENABLE_GPU_1M_PAGE
+    gcsADDRESS_AREA_PTR area1M = &Mmu->dynamicArea1M;
+    gctINT numEntries1M;
+#endif
+
+    /* Find all the free address space. */
+    gcmkONERROR(_CollectFreeSpace(Mmu, &nodeArray, &nodeArraySize));
+
+    for (i = 0; i < nodeArraySize; i++)
+    {
+        if (nodeArray[i].entries > numEntries)
+        {
+            area4K->mappingStart = nodeArray[i].start;
+            numEntries           = nodeArray[i].entries;
+            area4K->mappingEnd   = area4K->mappingStart + numEntries - 1;
+        }
+    }
+
+    gckOS_Free(Mmu->os, (gctPOINTER)nodeArray);
+
+#if gcdENABLE_TRUST_APPLICATION
+    if (gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_SECURITY) == gcvSTATUS_TRUE)
+    {
+        /* Setup secure address area when needed. */
+        gctUINT32 secureAreaSize = gcdMMU_SECURE_AREA_SIZE;
+        gcsADDRESS_AREA_PTR secureArea = &Mmu->secureArea;
+
+        gcmkASSERT(numEntries > (gctINT)secureAreaSize);
+
+        secureArea->mappingStart = area4K->mappingStart
+                                 + (numEntries - secureAreaSize);
+
+        gcmkONERROR(_SetupAddressArea(Mmu->os, secureArea, secureAreaSize));
+
+        numEntries -= secureAreaSize;
+        area4K->mappingEnd -= secureAreaSize;
+    }
+#endif
+
+#if gcdENABLE_GPU_1M_PAGE
+    numEntries1M = numEntries >> 1;
+    area1M->mappingStart = area4K->mappingStart + (numEntries - numEntries1M);
+    area1M->mappingEnd   = area1M->mappingStart + numEntries1M - 1;
+    area1M->areaType     = gcvAREA_TYPE_1M;
+    numEntries           -= numEntries1M;
+    area4K->mappingEnd   -= numEntries1M;
+
+    gcmkONERROR(_SetupAddressArea(Mmu->os, area1M, numEntries1M));
+
+    gcmkONERROR(_ConstructDynamicStlb(Mmu, area1M, numEntries1M));
+#endif
+
+    area4K->areaType = gcvAREA_TYPE_4K;
+
+    /* Setup normal address area. */
+    gcmkONERROR(_SetupAddressArea(Mmu->os, area4K, numEntries));
+
+    gcmkONERROR(_ConstructDynamicStlb(Mmu, area4K, numEntries));
 
     return gcvSTATUS_OK;
 
 OnError:
-    if (area->mapLogical)
+#if gcdENABLE_GPU_1M_PAGE
+    if (area1M->mapLogical)
     {
         gcmkVERIFY_OK(
-            gckOS_Free(Mmu->os, (gctPOINTER) area->mapLogical));
+            gckOS_Free(Mmu->os, (gctPOINTER) area1M->mapLogical));
+    }
 
+    if (area1M->stlbVideoMem)
+    {
+        gcmkVERIFY_OK(
+            gckVIDMEM_NODE_Dereference(kernel,
+                                       area1M->stlbVideoMem));
+    }
+#endif
 
+    if (area4K->mapLogical)
+    {
         gcmkVERIFY_OK(
-            gckOS_FreeContiguous(Mmu->os,
-                                 area->pageTablePhysical,
-                                 (gctPOINTER) area->pageTableLogical,
-                                 area->pageTableSize));
+            gckOS_Free(Mmu->os, (gctPOINTER) area4K->mapLogical));
     }
 
-    if (acquired)
+    if (area4K->stlbVideoMem)
     {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
+        gcmkVERIFY_OK(
+            gckVIDMEM_NODE_Dereference(kernel,
+                                       area4K->stlbVideoMem));
     }
 
     return status;
 }
-#endif
 
 gctUINT32
 _GetPageCountOfUsedNode(
@@ -1291,19 +1515,25 @@ _GetPageCountOfUsedNode(
 static gcsADDRESS_AREA_PTR
 _GetProcessArea(
     IN gckMMU Mmu,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure
     )
 {
-    gceADDRESS_AREA area = gcvADDRESS_AREA_NORMAL;
-
 #if gcdENABLE_TRUST_APPLICATION
     if (Secure == gcvTRUE)
     {
-        area = gcvADDRESS_AREA_SECURE;
+        return &Mmu->secureArea;
     }
 #endif
 
-    return &Mmu->area[area];
+    if (PageType == gcvPAGE_TYPE_1M)
+    {
+        return &Mmu->dynamicArea1M;
+    }
+    else
+    {
+        return &Mmu->dynamicArea4K;
+    }
 }
 
 /*******************************************************************************
@@ -1338,16 +1568,19 @@ _Construct(
     gckMMU mmu = gcvNULL;
     gctUINT32_PTR map;
     gctPOINTER pointer = gcvNULL;
-    gctUINT32 physBase;
-    gctUINT32 physSize;
-    gctUINT32 contiguousBase;
-    gctUINT32 contiguousSize = 0;
-    gctUINT32 externalBase;
-    gctUINT32 externalSize = 0;
+    gctPHYS_ADDR_T physBase;
+    gctSIZE_T physSize;
+    gctPHYS_ADDR_T contiguousBase;
+    gctSIZE_T contiguousSize = 0;
+    gctPHYS_ADDR_T externalBase;
+    gctSIZE_T externalSize = 0;
     gctUINT32 gpuAddress;
     gctPHYS_ADDR_T gpuPhysical;
     gcsADDRESS_AREA_PTR area = gcvNULL;
+    gcePOOL pool;
+    gctUINT64 data;
     gctUINT32 allocFlag = gcvALLOC_FLAG_CONTIGUOUS;
+    gctUINT64 mmuEnabled;
 
     gcmkHEADER_ARG("Kernel=0x%x MmuSize=%lu", Kernel, MmuSize);
 
@@ -1379,49 +1612,87 @@ _Construct(
     mmu->mtlbLogical      = gcvNULL;
     mmu->staticSTLB       = gcvNULL;
     mmu->enabled          = gcvFALSE;
-    gcsLIST_Init(&mmu->hardwareList);
 
+    mmu->dynamicAreaSetuped = gcvFALSE;
+
+    gcsLIST_Init(&mmu->hardwareList);
 
-    area = &mmu->area[0];
-    area->mapLogical       = gcvNULL;
-    area->pageTableLogical = gcvNULL;
+    /* Use 4K page size for MMU version 0. */
+    area = &mmu->dynamicArea4K;
+    area->mapLogical  = gcvNULL;
+    area->stlbLogical = gcvNULL;
 
     /* Create the page table mutex. */
     gcmkONERROR(gckOS_CreateMutex(os, &mmu->pageTableMutex));
 
+    gcmkONERROR(gckOS_QueryOption(os, "mmu", &mmuEnabled));
+
     if (hardware->mmuVersion == 0)
     {
-        area->pageTableSize = MmuSize;
+        area->stlbSize = MmuSize;
 
         /* Construct address space management table. */
         gcmkONERROR(gckOS_Allocate(mmu->os,
-                                   area->pageTableSize,
+                                   area->stlbSize,
                                    &pointer));
 
         area->mapLogical = pointer;
 
+        pool = gcdMMU_PGTABLE_POOL;
+
 #if gcdENABLE_CACHEABLE_COMMAND_BUFFER
         allocFlag |= gcvALLOC_FLAG_CACHEABLE;
 #endif
 
         /* Construct page table read by GPU. */
-        gcmkONERROR(gckOS_AllocateNonPagedMemory(mmu->os,
-                    gcvFALSE,
+        gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+                    Kernel,
+                    4096,
+                    gcvVIDMEM_TYPE_COMMAND,
                     allocFlag,
-                    &area->pageTableSize,
-                    &area->pageTablePhysical,
-                    (gctPOINTER)&area->pageTableLogical));
+                    &area->stlbSize,
+                    &pool,
+                    &area->stlbVideoMem));
+
+        /* Lock for kernel side CPU access. */
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+                    Kernel,
+                    area->stlbVideoMem,
+                    gcvFALSE,
+                    gcvFALSE,
+                    &pointer));
+
+        area->stlbLogical = pointer;
 
+        /* Get CPU physical address. */
+        gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+                    Kernel,
+                    area->stlbVideoMem,
+                    0,
+                    &area->stlbPhysical));
+
+        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(mmu->os,
+                    area->stlbPhysical,
+                    &area->stlbPhysical));
 
         /* Compute number of entries in page table. */
-        gcmkSAFECASTSIZET(area->pageTableEntries, area->pageTableSize / sizeof(gctUINT32));
+        gcmkSAFECASTSIZET(area->stlbEntries, area->stlbSize / sizeof(gctUINT32));
 
         /* Mark all pages as free. */
         map      = area->mapLogical;
 
-        _FillPageTable(area->pageTableLogical, area->pageTableEntries, mmu->safeAddress);
+        _FillPageTable(area->stlbLogical, area->stlbEntries, mmu->safeAddress);
+
+        gcmkDUMP(mmu->os,
+                 "#[mmu0: fill with safe address]");
+
+        gcmkDUMP(mmu->os,
+                 "@[physical.fill 0x%010llX 0x%08X 0x%08lX]",
+                 (unsigned long long)area->stlbPhysical,
+                 area->stlbLogical[0],
+                 (unsigned long)area->stlbSize);
 
-        map[0] = (area->pageTableEntries << 8) | gcvMMU_FREE;
+        map[0] = (area->stlbEntries << 8) | gcvMMU_FREE;
         map[1] = ~0U;
         area->heapList  = 0;
         area->freeNodes = gcvFALSE;
@@ -1430,71 +1701,61 @@ _Construct(
 
         if (gcmIS_SUCCESS(status))
         {
-            status = gckOS_QueryOption(mmu->os, "contiguousSize", &contiguousSize);
+            status = gckOS_QueryOption(mmu->os, "contiguousSize", &data);
+            contiguousSize = (gctSIZE_T)data;
         }
 
         if (gcmIS_SUCCESS(status) && contiguousSize)
         {
-            mmu->contiguousBaseAddress = contiguousBase - Kernel->hardware->baseAddress;
+            /* Convert to GPU address. */
+            mmu->contiguousBaseAddress = (gctUINT32)(contiguousBase - Kernel->hardware->baseAddress);
         }
-
     }
     else
     {
-        /* Allocate the 4K mode MTLB table. */
         mmu->mtlbSize = gcdMMU_MTLB_SIZE;
 
+        pool = gcdMMU_PGTABLE_POOL;
+
 #if gcdENABLE_CACHEABLE_COMMAND_BUFFER
         allocFlag |= gcvALLOC_FLAG_CACHEABLE;
 #endif
 
-        gcmkONERROR(
-            gckOS_AllocateNonPagedMemory(os,
-                                         gcvFALSE,
-                                         allocFlag,
-                                         &mmu->mtlbSize,
-                                         &mmu->mtlbPhysical,
-                                         &pointer));
+        /* 1K mode is 1024 byte aligned. */
+        gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+                    Kernel,
+                    1024,
+                    gcvVIDMEM_TYPE_COMMAND,
+                    allocFlag | gcvALLOC_FLAG_4K_PAGES,
+                    &mmu->mtlbSize,
+                    &pool,
+                    &mmu->mtlbVideoMem));
+
+        /* Lock for kernel side CPU access. */
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+                    Kernel,
+                    mmu->mtlbVideoMem,
+                    gcvFALSE,
+                    gcvFALSE,
+                    &pointer));
 
         mmu->mtlbLogical = pointer;
 
-        area->dynamicMappingStart = gcvINVALID_ADDRESS;
-
-#if gcdPROCESS_ADDRESS_SPACE
-        _FillPageTable(pointer, mmu->mtlbSize / 4, gcdMMU_MTLB_EXCEPTION);
-
-        /* Allocate a array to store stlbs. */
-        gcmkONERROR(gckOS_Allocate(os, mmu->mtlbSize, &mmu->stlbs));
-
-        gckOS_ZeroMemory(mmu->stlbs, mmu->mtlbSize);
-
-        for (i = 0; i < gcdMAX_GPU_COUNT; i++)
-        {
-            gcmkONERROR(gckOS_AtomConstruct(os, &mmu->pageTableDirty[i]));
-        }
+        mmu->dynamicArea4K.mappingStart = gcvINVALID_ADDRESS;
+        mmu->dynamicArea1M.mappingStart = gcvINVALID_ADDRESS;
 
-        _SetupProcessAddressSpace(mmu);
+        /* Get mtlb table physical. */
+        gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+                    Kernel,
+                    mmu->mtlbVideoMem,
+                    0,
+                    &mmu->mtlbPhysical));
 
-        /* Map kernel command buffer in MMU. */
-        for (i = 0; i < gcdCOMMAND_QUEUES; i++)
-        {
-            gcmkONERROR(gckOS_GetPhysicalAddress(
-                mmu->os,
-                Kernel->command->queues[i].logical,
-                &gpuPhysical
-                ));
+        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
+                      mmu->os,
+                      mmu->mtlbPhysical,
+                      &mmu->mtlbPhysical));
 
-            gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
-                mmu->os,
-                gpuPhysical,
-                &gpuPhysical
-                ));
-
-            gcmkSAFECASTPHYSADDRT(gpuAddress, gpuPhysical);
-
-            gcmkONERROR(gckMMU_FlatMapping(mmu, gpuAddress, 1));
-        }
-#else
         /* Invalid all the entries. */
         gcmkONERROR(
             gckOS_ZeroMemory(pointer, mmu->mtlbSize));
@@ -1503,7 +1764,8 @@ _Construct(
             gckOS_QueryOption(mmu->os, "physBase", &physBase));
 
         gcmkONERROR(
-            gckOS_QueryOption(mmu->os, "physSize", &physSize));
+            gckOS_QueryOption(mmu->os, "physSize", &data));
+        physSize = (gctSIZE_T)data;
 
         gcmkONERROR(
             gckOS_CPUPhysicalToGPUPhysical(mmu->os, physBase, &gpuPhysical));
@@ -1513,107 +1775,148 @@ _Construct(
         if (physSize)
         {
             /* Setup user specified flat mapping. */
-            gcmkONERROR(_FillFlatMapping(mmu, gpuAddress, physSize, gcvNULL));
+            gcmkONERROR(_FillFlatMapping(mmu, gpuAddress, physSize, gcvFALSE, gcvFALSE, gcvNULL));
         }
 
-#ifndef EMULATOR
         if (!_ReadPageEntry(mmu->mtlbLogical + 0))
         {
             gctUINT32 mtlbEntry;
             /*
-             * Reserved 0~4MB space.
-             * 64KB page size, Ingore exception, Not Present.
+             * Reserved the first mtlb.
+             * 1MB page size, Ingore exception, Not Present.
              */
-            mtlbEntry = (1 << 2)
+            mtlbEntry = (1 << 3)
                       | (0 << 1)
                       | (0 << 0);
 
             _WritePageEntry(mmu->mtlbLogical + 0, mtlbEntry);
+
+            gcmkDUMP(mmu->os, "#[mmu-mtlb: reserved 16M space, slot: 0]");
+            gcmkDUMP(mmu->os,
+                     "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+                     (unsigned long long)mmu->mtlbPhysical,
+                     mmu->mtlbLogical[0], 4);
+
+            /* Store the gpu virtual ranges */
+            mmu->gpuAddressRanges[mmu->gpuAddressRangeCount].start = 0;
+            mmu->gpuAddressRanges[mmu->gpuAddressRangeCount].end   = (16 << 20) - 1;
+            mmu->gpuAddressRanges[mmu->gpuAddressRangeCount].size  = (16 << 20);
+            mmu->gpuAddressRanges[mmu->gpuAddressRangeCount].flag  = gcvFLATMAP_DIRECT;
+            mmu->gpuAddressRangeCount++;
         }
-#endif
 
         status = gckOS_QueryOption(mmu->os, "contiguousBase", &contiguousBase);
 
         if (gcmIS_SUCCESS(status))
         {
-            status = gckOS_QueryOption(mmu->os, "contiguousSize", &contiguousSize);
+            status = gckOS_QueryOption(mmu->os, "contiguousSize", &data);
+            contiguousSize = (gctSIZE_T)data;
         }
 
         if (gcmIS_SUCCESS(status) && contiguousSize)
         {
             gctUINT64 gpuContiguousBase;
-            gctUINT32 contiguousBaseAddress;
+            gctUINT32 contiguousBaseAddress = 0;
 
             gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(mmu->os, contiguousBase, &gpuContiguousBase));
 
             /* Setup flat mapping for reserved memory (VIDMEM). */
-            gcmkONERROR(_FillFlatMapping(mmu, gpuContiguousBase, contiguousSize, &contiguousBaseAddress));
+            gcmkONERROR(_FillFlatMapping(mmu, gpuContiguousBase, contiguousSize, gcvFALSE, gcvTRUE, &contiguousBaseAddress));
 
-            mmu->contiguousBaseAddress = contiguousBaseAddress;
+            if (mmuEnabled)
+            {
+                mmu->contiguousBaseAddress = contiguousBaseAddress;
+            }
+            else
+            {
+                gcmkSAFECASTPHYSADDRT(mmu->contiguousBaseAddress, gpuContiguousBase);
+            }
         }
 
         status = gckOS_QueryOption(mmu->os, "externalBase", &externalBase);
 
         if (gcmIS_SUCCESS(status))
         {
-            status = gckOS_QueryOption(mmu->os, "externalSize", &externalSize);
+            status = gckOS_QueryOption(mmu->os, "externalSize", &data);
+            externalSize = (gctSIZE_T)data;
         }
 
         if (gcmIS_SUCCESS(status) && externalSize)
         {
             gctUINT64 gpuExternalBase;
-            gctUINT32 externalBaseAddress;
+            gctUINT32 externalBaseAddress = 0;
 
             gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(mmu->os, externalBase, &gpuExternalBase));
 
             /* Setup flat mapping for external memory. */
-            gcmkONERROR(_FillFlatMapping(mmu, gpuExternalBase, externalSize, &externalBaseAddress));
+            gcmkONERROR(_FillFlatMapping(mmu, gpuExternalBase, externalSize, gcvFALSE, gcvTRUE, &externalBaseAddress));
 
             mmu->externalBaseAddress = externalBaseAddress;
         }
+    }
 
-        gcmkONERROR(_SetupDynamicSpace(mmu));
-#endif
+    /* A 64 byte for safe address, we use 256 here. */
+    mmu->safePageSize = 256;
 
-        /* Flush MTLB table. */
-        gcmkONERROR(gckOS_CacheClean(
-            os,
-            0,
-            mmu->mtlbPhysical,
-            0,
-            mmu->mtlbLogical,
-            mmu->mtlbSize
-            ));
-    }
+    pool = gcdMMU_PGTABLE_POOL;
 
-    mmu->safePageSize = 4096;
+    /* Allocate safe page from video memory. */
+    gcmkONERROR(gckKERNEL_AllocateVideoMemory(
+        Kernel,
+        256,
+        gcvVIDMEM_TYPE_COMMAND,
+        gcvALLOC_FLAG_CONTIGUOUS | gcvALLOC_FLAG_4K_PAGES,
+        &mmu->safePageSize,
+        &pool,
+        &mmu->safePageVideoMem
+        ));
 
-    gcmkONERROR(gckOS_AllocateContiguous(
-        os,
+    /* Lock for kernel side CPU access. */
+    gcmkONERROR(gckVIDMEM_NODE_LockCPU(
+        Kernel,
+        mmu->safePageVideoMem,
+        gcvFALSE,
         gcvFALSE,
-        &mmu->safePageSize,
-        &mmu->safePagePhysical,
         &mmu->safePageLogical
         ));
 
-    gcmkONERROR(gckOS_GetPhysicalAddress(
-        os,
-        mmu->safePageLogical,
-        &gpuPhysical
+    /* Get CPU physical address. */
+    gcmkONERROR(gckVIDMEM_NODE_GetPhysical(
+        Kernel,
+        mmu->safePageVideoMem,
+        0,
+        &mmu->safePagePhysical
         ));
 
     gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(
         os,
-        gpuPhysical,
-        &gpuPhysical
+        mmu->safePagePhysical,
+        &mmu->safePagePhysical
         ));
 
-    gcmkSAFECASTPHYSADDRT(mmu->safeAddress, gpuPhysical);
+    gcmkSAFECASTPHYSADDRT(mmu->safeAddress, mmu->safePagePhysical);
 
     gckOS_ZeroMemory(mmu->safePageLogical, mmu->safePageSize);
 
+    gcmkDUMP(mmu->os, "#[safe page]");
+    gcmkDUMP(mmu->os,
+            "@[physical.fill 0x%010llX 0x%08X 0x%08lX]",
+            (unsigned long long)mmu->safePagePhysical,
+            0,
+            (unsigned long)mmu->safePageSize);
+
+    gcmkDUMP_BUFFER(
+        mmu->os,
+        gcvDUMP_BUFFER_KERNEL_COMMAND,
+        mmu->safePageLogical,
+        mmu->safeAddress,
+        mmu->safePageSize
+        );
+
     gcmkONERROR(gckQUEUE_Allocate(os, &mmu->recentFreedAddresses, 16));
 
+    mmu->sRAMMapped = gcvFALSE;
+
     /* Return the gckMMU object pointer. */
     *Mmu = mmu;
 
@@ -1630,21 +1933,16 @@ OnError:
             gcmkVERIFY_OK(
                 gckOS_Free(os, (gctPOINTER) area->mapLogical));
 
-
             gcmkVERIFY_OK(
-                gckOS_FreeContiguous(os,
-                                     area->pageTablePhysical,
-                                     (gctPOINTER) area->pageTableLogical,
-                                     area->pageTableSize));
+                gckVIDMEM_NODE_Dereference(Kernel,
+                                           area->stlbVideoMem));
         }
 
         if (mmu->mtlbLogical != gcvNULL)
         {
             gcmkVERIFY_OK(
-                gckOS_FreeContiguous(os,
-                                     mmu->mtlbPhysical,
-                                     (gctPOINTER) mmu->mtlbLogical,
-                                     mmu->mtlbSize));
+                gckVIDMEM_NODE_Dereference(Kernel,
+                                           mmu->mtlbVideoMem));
         }
 
         if (mmu->pageTableMutex != gcvNULL)
@@ -1663,8 +1961,33 @@ OnError:
         gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, mmu));
     }
 
-    /* Return the status. */
-    gcmkFOOTER();
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+_FreeAddressArea(
+    gckKERNEL Kernel,
+    gcsADDRESS_AREA * Area
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+
+    if (Area->mapLogical != gcvNULL)
+    {
+        gcmkVERIFY_OK(
+            gckOS_Free(Kernel->os, (gctPOINTER) Area->mapLogical));
+    }
+
+    if (Area->stlbLogical != gcvNULL)
+    {
+        /* Free page table. */
+        gcmkVERIFY_OK(
+            gckVIDMEM_NODE_Dereference(Kernel,
+                                       Area->stlbVideoMem));
+    }
+
     return status;
 }
 
@@ -1688,7 +2011,8 @@ _Destroy(
     IN gckMMU Mmu
     )
 {
-    gctUINT32 i;
+    gckKERNEL kernel = Mmu->hardware->kernel;
+
     gcmkHEADER_ARG("Mmu=0x%x", Mmu);
 
     /* Verify the arguments. */
@@ -1699,13 +2023,11 @@ _Destroy(
         gcsMMU_STLB_CHUNK_PTR pre = Mmu->staticSTLB;
         Mmu->staticSTLB = pre->next;
 
-        if (pre->physical != gcvNULL)
+        if (pre->videoMem)
         {
             gcmkVERIFY_OK(
-                gckOS_FreeContiguous(Mmu->os,
-                    pre->physical,
-                    pre->logical,
-                    pre->size));
+                gckVIDMEM_NODE_Dereference(kernel,
+                                           pre->videoMem));
         }
 
         if (pre->mtlbEntryNum != 0)
@@ -1720,6 +2042,17 @@ _Destroy(
                     pre->mtlbIndex + i);
 #endif
             }
+
+            gcmkDUMP(Mmu->os,
+                     "#[mmu-mtlb: clean up slot: %d - %d]",
+                     pre->mtlbIndex,
+                     pre->mtlbIndex + pre->mtlbEntryNum - 1);
+
+            gcmkDUMP(Mmu->os,
+                     "@[physical.fill 0x%010llX 0x%08X 0x%08lX]",
+                     (unsigned long long)(Mmu->mtlbPhysical + pre->mtlbIndex * 4),
+                     Mmu->mtlbLogical[pre->mtlbIndex],
+                     (unsigned long)(pre->mtlbEntryNum * 4));
         }
 
         gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, pre));
@@ -1728,64 +2061,25 @@ _Destroy(
     if (Mmu->hardware->mmuVersion != 0)
     {
         gcmkVERIFY_OK(
-                gckOS_FreeContiguous(Mmu->os,
-                    Mmu->mtlbPhysical,
-                    (gctPOINTER) Mmu->mtlbLogical,
-                    Mmu->mtlbSize));
+            gckVIDMEM_NODE_Dereference(kernel,
+                                       Mmu->mtlbVideoMem));
     }
 
-    for (i = 0; i < gcvADDRESS_AREA_COUNT; i++)
-    {
-        gcsADDRESS_AREA_PTR area = &Mmu->area[i];
-
-        /* Free address space management table. */
-        if (area->mapLogical != gcvNULL)
-        {
-            gcmkVERIFY_OK(
-                gckOS_Free(Mmu->os, (gctPOINTER) area->mapLogical));
-        }
-
-        if (area->pageTableLogical != gcvNULL)
-        {
-            /* Free page table. */
-            gcmkVERIFY_OK(
-                gckOS_FreeContiguous(Mmu->os,
-                                     area->pageTablePhysical,
-                                     (gctPOINTER) area->pageTableLogical,
-                                     area->pageTableSize));
-        }
-    }
+    /* Free address area. */
+    gcmkVERIFY_OK(_FreeAddressArea(kernel, &Mmu->dynamicArea4K));
+#if gcdENABLE_GPU_1M_PAGE
+    gcmkVERIFY_OK(_FreeAddressArea(kernel, &Mmu->dynamicArea1M));
+#endif
+    gcmkVERIFY_OK(_FreeAddressArea(kernel, &Mmu->secureArea));
 
     /* Delete the page table mutex. */
     gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->pageTableMutex));
 
-#if gcdPROCESS_ADDRESS_SPACE
-    for (i = 0; i < Mmu->mtlbSize / 4; i++)
-    {
-        struct _gcsMMU_STLB_CHUNK *stlb = ((struct _gcsMMU_STLB_CHUNK **)Mmu->stlbs)[i];
-
-        if (stlb)
-        {
-            gcmkVERIFY_OK(gckOS_FreeContiguous(
-                Mmu->os,
-                stlb->physical,
-                stlb->logical,
-                stlb->size));
-
-            gcmkOS_SAFE_FREE(Mmu->os, stlb);
-        }
-    }
-
-    gcmkOS_SAFE_FREE(Mmu->os, Mmu->stlbs);
-#endif
-
     if (Mmu->safePageLogical != gcvNULL)
     {
-        gcmkVERIFY_OK(gckOS_FreeContiguous(
-            Mmu->os,
-            Mmu->safePagePhysical,
-            Mmu->safePageLogical,
-            Mmu->safePageSize
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(
+            kernel,
+            Mmu->safePageVideoMem
             ));
     }
 
@@ -1819,12 +2113,12 @@ _AdjustIndex(
 {
     gceSTATUS status;
     gctUINT32 index = Index;
-    gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea4K;
     gctUINT32_PTR map = area->mapLogical;
 
     gcmkHEADER();
 
-    for (; index < area->pageTableEntries;)
+    for (; index < area->stlbEntries;)
     {
         gctUINT32 result = 0;
         gctUINT32 nodeSize = 0;
@@ -1993,7 +2287,8 @@ gceSTATUS
 _AllocatePages(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
@@ -2006,7 +2301,7 @@ _AllocatePages(
     gctBOOL gotIt;
     gctUINT32 address;
     gctUINT32 pageCount;
-    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, Secure);
+    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, PageType, Secure);
 
     gcmkHEADER_ARG("Mmu=0x%x PageCount=%lu", Mmu, PageCount);
 
@@ -2015,7 +2310,7 @@ _AllocatePages(
     gcmkVERIFY_ARGUMENT(PageCount > 0);
     gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
 
-    if (PageCount > area->pageTableEntries)
+    if (PageCount > area->stlbEntries)
     {
         /* Not enough pages avaiable. */
         gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
@@ -2037,7 +2332,8 @@ _AllocatePages(
     {
         index = area->heapList;
 
-        if ((Mmu->hardware->mmuVersion == 0) && (Type == gcvSURF_VERTEX))
+        if ((Mmu->hardware->mmuVersion == 0) &&
+            (Type == gcvVIDMEM_TYPE_VERTEX_BUFFER))
         {
             gcmkONERROR(_AdjustIndex(
                 Mmu,
@@ -2049,7 +2345,7 @@ _AllocatePages(
         }
 
         /* Walk the heap list. */
-        for (; !gotIt && (index < area->pageTableEntries);)
+        for (; !gotIt && (index < area->stlbEntries);)
         {
             /* Check the node type. */
             switch (gcmENTRY_TYPE(map[index]))
@@ -2089,7 +2385,7 @@ _AllocatePages(
         }
 
         /* Test if we are out of memory. */
-        if (index >= area->pageTableEntries)
+        if (index >= area->stlbEntries)
         {
             if (area->freeNodes)
             {
@@ -2160,10 +2456,10 @@ _AllocatePages(
         map[index] = (pageCount << 8) | gcvMMU_USED;
     }
 
-    if (area->pageTableLogical != gcvNULL)
+    if (area->stlbLogical != gcvNULL)
     {
-    /* Return pointer to page table. */
-    *PageTable = &area->pageTableLogical[index];
+        /* Return pointer to page table. */
+        *PageTable = &area->stlbLogical[index];
     }
     else
     {
@@ -2179,12 +2475,13 @@ _AllocatePages(
     }
     else
     {
-        gctUINT32 masterOffset = index / gcdMMU_STLB_4K_ENTRY_NUM
-                               + area->dynamicMappingStart;
-        gctUINT32 slaveOffset = index % gcdMMU_STLB_4K_ENTRY_NUM;
+        gctUINT32 num = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_ENTRY_NUM : gcdMMU_STLB_4K_ENTRY_NUM;
+        gctUINT32 shift = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_SHIFT : gcdMMU_STLB_4K_SHIFT;
+        gctUINT32 masterOffset = index / num + area->mappingStart;
+        gctUINT32 slaveOffset = index % num;
 
         address = (masterOffset << gcdMMU_MTLB_SHIFT)
-                | (slaveOffset << gcdMMU_STLB_4K_SHIFT);
+                | (slaveOffset << shift);
     }
 
     if (Address != gcvNULL)
@@ -2238,17 +2535,21 @@ gceSTATUS
 _FreePages(
     IN gckMMU Mmu,
     IN gctBOOL Secure,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctSIZE_T PageCount
     )
 {
+    gctUINT32 index;
     gctUINT32_PTR node;
     gceSTATUS status;
     gctBOOL acquired = gcvFALSE;
     gctUINT32 pageCount;
     gcuQUEUEDATA data;
-    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, Secure);
+    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, PageType, gcvFALSE);
+    gctUINT32 pageSize = (PageType == gcvPAGE_TYPE_1M)
+                       ? gcdMMU_PAGE_1M_SIZE : gcdMMU_PAGE_4K_SIZE;
 
     gcmkHEADER_ARG("Mmu=0x%x PageTable=0x%x PageCount=%lu",
                    Mmu, PageTable, PageCount);
@@ -2264,7 +2565,9 @@ _FreePages(
 #endif
 
     /* Get the node by index. */
-    node = area->mapLogical + ((gctUINT32_PTR)PageTable - area->pageTableLogical);
+    index = (gctUINT32)((gctUINT32_PTR)PageTable - area->stlbLogical);
+
+    node = area->mapLogical + index;
 
     if (pageCount != _GetPageCountOfUsedNode(node))
     {
@@ -2315,12 +2618,22 @@ _FreePages(
         }
     }
 
+    gcmkDUMP(Mmu->os,
+             "#[mmu-stlb: free 0x%08X - 0x%08X]",
+             Address, Address + pageCount * pageSize - 1);
+
+    gcmkDUMP(Mmu->os,
+             "@[physical.fill 0x%010llX 0x%08X 0x%08X]",
+             (unsigned long long)(area->stlbPhysical + index * 4),
+             *(gctUINT32_PTR)PageTable,
+             pageCount * 4);
+
     /* We have free nodes. */
     area->freeNodes = gcvTRUE;
 
     /* Record freed address range. */
     data.addressData.start = Address;
-    data.addressData.end = Address + (gctUINT32)PageCount * 4096;
+    data.addressData.end = Address + (gctUINT32)PageCount * pageSize;
     gckQUEUE_Enqueue(&Mmu->recentFreedAddresses, &data);
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
@@ -2351,19 +2664,21 @@ gceSTATUS
 gckMMU_AllocatePages(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
+    IN gcePAGE_TYPE PageType,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
     )
 {
     return gckMMU_AllocatePagesEx(
-                Mmu, PageCount, gcvSURF_TYPE_UNKNOWN, gcvFALSE, PageTable, Address);
+                Mmu, PageCount, gcvVIDMEM_TYPE_GENERIC, PageType, gcvFALSE, PageTable, Address);
 }
 
 gceSTATUS
 gckMMU_AllocatePagesEx(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
@@ -2373,7 +2688,7 @@ gckMMU_AllocatePagesEx(
     gcmkPRINT("GPU virtual address is disabled.");
     return gcvSTATUS_NOT_SUPPORTED;
 #else
-    return _AllocatePages(Mmu, PageCount, Type, Secure, PageTable, Address);
+    return _AllocatePages(Mmu, PageCount, Type, PageType, Secure, PageTable, Address);
 #endif
 }
 
@@ -2381,18 +2696,20 @@ gceSTATUS
 gckMMU_FreePages(
     IN gckMMU Mmu,
     IN gctBOOL Secure,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctSIZE_T PageCount
     )
 {
-    return _FreePages(Mmu, Secure, Address, PageTable, PageCount);
+    return _FreePages(Mmu, Secure, PageType, Address, PageTable, PageCount);
 }
 
 gceSTATUS
 gckMMU_SetPage(
     IN gckMMU Mmu,
     IN gctPHYS_ADDR_T PageAddress,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Writable,
     IN gctUINT32 *PageEntry
     )
@@ -2405,7 +2722,15 @@ gckMMU_SetPage(
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
     gcmkVERIFY_ARGUMENT(PageEntry != gcvNULL);
-    gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
+
+    if (PageType == gcvPAGE_TYPE_1M)
+    {
+        gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFFFF));
+    }
+    else
+    {
+        gcmkVERIFY_ARGUMENT(!(PageAddress & 0xFFF));
+    }
 
     /* [31:0]. */
     address    = (gctUINT32)(PageAddress & 0xFFFFFFFF);
@@ -2421,207 +2746,41 @@ gckMMU_SetPage(
         _WritePageEntry(PageEntry, _SetPage(address, addressExt, gcvTRUE));
     }
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-#if gcdPROCESS_ADDRESS_SPACE
-gceSTATUS
-gckMMU_GetPageEntry(
-    IN gckMMU Mmu,
-    IN gctUINT32 Address,
-    IN gctUINT32_PTR *PageTable
-    )
-{
-    gceSTATUS status;
-    struct _gcsMMU_STLB_CHUNK *stlb;
-    struct _gcsMMU_STLB_CHUNK **stlbs = Mmu->stlbs;
-    gctUINT32 offset = _MtlbOffset(Address);
-    gctUINT32 mtlbEntry;
-    gctBOOL ace = gckHARDWARE_IsFeatureAvailable(Mmu->hardware, gcvFEATURE_ACE);
-
-    gcmkHEADER_ARG("Mmu=0x%x", Mmu);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
-    gcmkVERIFY_ARGUMENT((Address & 0xFFF) == 0);
-
-    stlb = stlbs[offset];
-
-    if (stlb == gcvNULL)
-    {
-        gcmkONERROR(_AllocateStlb(Mmu->os, &stlb));
-
-        mtlbEntry = stlb->physBase
-                  | gcdMMU_MTLB_4K_PAGE
-                  | gcdMMU_MTLB_PRESENT
-                  ;
-
-        /* Insert Slave TLB address to Master TLB entry.*/
-        _WritePageEntry(Mmu->mtlbLogical + offset, mtlbEntry);
-
-        /* Record stlb. */
-        stlbs[offset] = stlb;
-    }
-
-    *PageTable = &stlb->logical[_StlbOffset(Address)];
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-_CheckMap(
-    IN gckMMU Mmu
-    )
-{
-    gceSTATUS status;
-    gctUINT32_PTR map = area->mapLogical;
-    gctUINT32 index;
-
-    for (index = area->heapList; index < area->pageTableEntries;)
-    {
-        /* Check the node type. */
-        switch (gcmENTRY_TYPE(map[index]))
-        {
-        case gcvMMU_SINGLE:
-            /* Move to next node. */
-            index    = map[index] >> 8;
-            break;
-
-        case gcvMMU_FREE:
-            /* Move to next node. */
-            index    = map[index + 1];
-            break;
-
-        default:
-            gcmkFATAL("MMU table correcupted at index [%u] = %x!", index, map[index]);
-            gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
-        }
-    }
-
-    return gcvSTATUS_OK;
-
-OnError:
-    return status;
-}
-
-gceSTATUS
-gckMMU_FlatMapping(
-    IN gckMMU Mmu,
-    IN gctUINT32 Physical,
-    IN gctUINT32 NumPages
-    )
-{
-    gceSTATUS status;
-    gctUINT32 index = _AddressToIndex(Mmu, Physical);
-    gctUINT32 i;
-    gctUINT32_PTR pageTable;
-
-    for (i = 0; i < NumPages; i++)
-    {
-        gckMMU_GetPageEntry(Mmu, Physical + i * 4096, &pageTable);
-
-        _WritePageEntry(pageTable, _SetPage(Physical + i * 4096, 0));
-    }
-
-    gcmkONERROR(_FillFlatMapping(Mmu, PhysBase, Size, gcvNULL));
-
-    return gcvSTATUS_OK;
-
-OnError:
-
-    /* Roll back. */
-    return status;
-}
-
-gceSTATUS
-gckMMU_FreePagesEx(
-    IN gckMMU Mmu,
-    IN gctUINT32 Address,
-    IN gctSIZE_T PageCount
-    )
-{
-    gctUINT32_PTR node;
-    gceSTATUS status;
-
-#if gcdUSE_MMU_EXCEPTION
-    gctUINT32 i;
-    struct _gcsMMU_STLB_CHUNK *stlb;
-    struct _gcsMMU_STLB_CHUNK **stlbs = Mmu->stlbs;
-#endif
-
-    gcmkHEADER_ARG("Mmu=0x%x Address=0x%x PageCount=%lu",
-                   Mmu, Address, PageCount);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
-    gcmkVERIFY_ARGUMENT(PageCount > 0);
-
-    /* Get the node by index. */
-    node = area->mapLogical + _AddressToIndex(Mmu, Address);
-
-    gcmkONERROR(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
-
-    if (PageCount == 1)
-    {
-       /* Single page node. */
-        node[0] = (~((1U<<8)-1)) | gcvMMU_SINGLE;
-    }
-    else
+#ifdef DUMP_IN_KERNEL
     {
-        /* Mark the node as free. */
-        node[0] = (PageCount << 8) | gcvMMU_FREE;
-        node[1] = ~0U;
-    }
+        gctUINT32 *stlbLogical = (PageType == gcvPAGE_TYPE_1M)
+                               ? Mmu->dynamicArea1M.stlbLogical
+                               : Mmu->dynamicArea4K.stlbLogical;
 
-    /* We have free nodes. */
-    area->freeNodes = gcvTRUE;
+        gctPHYS_ADDR_T stlbPhysical = (PageType == gcvPAGE_TYPE_1M)
+                                    ? Mmu->dynamicArea1M.stlbPhysical
+                                    : Mmu->dynamicArea4K.stlbPhysical;
 
-#if gcdUSE_MMU_EXCEPTION
-    for (i = 0; i < PageCount; i++)
-    {
-        /* Get */
-        stlb = stlbs[_MtlbOffset(Address)];
+        gctPHYS_ADDR_T physical = stlbPhysical + (stlbLogical - PageEntry) * 4;
 
-        /* Enable exception */
-        stlb->logical[_StlbOffset(Address)] = gcdMMU_STLB_EXCEPTION;
+        gckDUMP(Mmu->os, "@[physical.fill 0x%010llX 0x%08X 4",
+                physical, *PageEntry);
     }
 #endif
 
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(Mmu->os, Mmu->pageTableMutex));
-
-
     /* Success. */
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
 }
-#endif
 
 gceSTATUS
 gckMMU_Flush(
     IN gckMMU Mmu,
-    IN gceSURF_TYPE Type
+    IN gceVIDMEM_TYPE Type
     )
 {
-#if !gcdPROCESS_ADDRESS_SPACE
     gckHARDWARE hardware;
-#endif
     gctUINT32 mask;
     gctINT i;
-    gctUINT j;
 
-    if (Type == gcvSURF_VERTEX || Type == gcvSURF_INDEX)
+    if (Type == gcvVIDMEM_TYPE_VERTEX_BUFFER ||
+        Type == gcvVIDMEM_TYPE_INDEX_BUFFER ||
+        Type == gcvVIDMEM_TYPE_COMMAND)
     {
         mask = gcvPAGE_TABLE_DIRTY_BIT_FE;
     }
@@ -2630,18 +2789,10 @@ gckMMU_Flush(
         mask = gcvPAGE_TABLE_DIRTY_BIT_OTHER;
     }
 
-    i = 0;
-
-#if gcdPROCESS_ADDRESS_SPACE
-    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
-    {
-        gcmkVERIFY_OK(
-            gckOS_AtomSetMask(Mmu->pageTableDirty[i], mask));
-    }
-#else
 #if gcdSHARED_PAGETABLE
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
+        gctUINT j;
         hardware = sharedPageTable->hardwares[i];
         if (hardware)
         {
@@ -2654,29 +2805,28 @@ gckMMU_Flush(
 #else
     hardware = Mmu->hardware;
 
-    for (j = 0 ; j < gcvENGINE_GPU_ENGINE_COUNT; j++)
+    for (i = 0 ; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
     {
         gcmkVERIFY_OK(
-            gckOS_AtomSetMask(hardware->pageTableDirty[j], mask));
+            gckOS_AtomSetMask(hardware->pageTableDirty[i], mask));
     }
 
     {
         gcsLISTHEAD_PTR hardwareHead;
         gcmkLIST_FOR_EACH(hardwareHead, &Mmu->hardwareList)
         {
-            hardware = gcmCONTAINEROF(hardwareHead, _gckHARDWARE, mmuHead);
+            hardware = gcmCONTAINEROF(hardwareHead, struct _gckHARDWARE, mmuHead);
 
             if (hardware != Mmu->hardware)
             {
-                for (j = 0 ; j < gcvENGINE_GPU_ENGINE_COUNT; j++)
+                for (i = 0 ; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
                 {
                     gcmkVERIFY_OK(
-                        gckOS_AtomSetMask(hardware->pageTableDirty[j], mask));
+                        gckOS_AtomSetMask(hardware->pageTableDirty[i], mask));
                 }
             }
         }
     }
-#endif
 #endif
 
     return gcvSTATUS_OK;
@@ -2685,45 +2835,40 @@ gckMMU_Flush(
 gceSTATUS
 gckMMU_DumpPageTableEntry(
     IN gckMMU Mmu,
+    IN gceAREA_TYPE AreaType,
     IN gctUINT32 Address
     )
 {
-#if gcdPROCESS_ADDRESS_SPACE
-    gcsMMU_STLB_PTR *stlbs = Mmu->stlbs;
-    gcsMMU_STLB_PTR stlbDesc = stlbs[_MtlbOffset(Address)];
-#else
     gctUINT32_PTR pageTable;
     gctUINT32 index;
     gctUINT32 mtlb, stlb;
-#endif
-    gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+    gcsADDRESS_AREA_PTR area = (AreaType == gcvAREA_TYPE_4K)
+                             ? &Mmu->dynamicArea4K : &Mmu->dynamicArea1M;
+
+    gctUINT32 stlbShift = (AreaType == gcvAREA_TYPE_4K)
+                        ? gcdMMU_STLB_4K_SHIFT : gcdMMU_STLB_1M_SHIFT;
+
+    gctUINT32 stlbMask  = (AreaType == gcvAREA_TYPE_4K)
+                        ? gcdMMU_STLB_4K_MASK : gcdMMU_STLB_1M_MASK;
+
+    gctUINT32 stlbEntryNum = (AreaType == gcvAREA_TYPE_4K)
+                           ? gcdMMU_STLB_4K_ENTRY_NUM : gcdMMU_STLB_1M_ENTRY_NUM;
 
     gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
     gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
 
     gcmkASSERT(Mmu->hardware->mmuVersion > 0);
 
-#if gcdPROCESS_ADDRESS_SPACE
-    if (stlbDesc)
-    {
-        gcmkPRINT("    STLB entry = 0x%08X",
-                  _ReadPageEntry(&stlbDesc->logical[_StlbOffset(Address)]));
-    }
-    else
-    {
-        gcmkPRINT("    MTLB entry is empty.");
-    }
-#else
-    mtlb   = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+    mtlb = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
 
-    if (mtlb >= area->dynamicMappingStart)
+    if (AreaType != gcvAREA_TYPE_FLATMAP)
     {
-        stlb   = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+        stlb = (Address & stlbMask) >> stlbShift;
 
-        pageTable = area->pageTableLogical;
+        pageTable = area->stlbLogical;
 
-        index = (mtlb - area->dynamicMappingStart)
-              * gcdMMU_STLB_4K_ENTRY_NUM
+        index = (mtlb - area->mappingStart)
+              * stlbEntryNum
               + stlb;
 
         gcmkPRINT("    Page table entry = 0x%08X", _ReadPageEntry(pageTable + index));
@@ -2733,7 +2878,7 @@ gckMMU_DumpPageTableEntry(
         gcsMMU_STLB_CHUNK_PTR stlbChunkObj = Mmu->staticSTLB;
         gctUINT32 entry = Mmu->mtlbLogical[mtlb];
 
-        stlb = (Address & gcdMMU_STLB_64K_MASK) >> gcdMMU_STLB_64K_SHIFT;
+        stlb = (Address & gcdMMU_STLB_1M_MASK) >> gcdMMU_STLB_1M_SHIFT;
 
         entry &= 0xFFFFFFF0;
 
@@ -2743,9 +2888,9 @@ gckMMU_DumpPageTableEntry(
             gctBOOL found = gcvFALSE;
             for (i = 0; i < stlbChunkObj->mtlbEntryNum; ++i)
             {
-                gctPHYS_ADDR_T stlbPhysBase = stlbChunkObj->physBase + (i * gcdMMU_STLB_64K_SIZE);
+                gctPHYS_ADDR_T stlbPhysBase = stlbChunkObj->physBase + (i * gcdMMU_STLB_1M_SIZE);
                 gctUINT32_PTR stlbLogical =
-                    (gctUINT32_PTR)((gctUINT8_PTR)stlbChunkObj->logical + (i * gcdMMU_STLB_64K_SIZE));
+                    (gctUINT32_PTR)((gctUINT8_PTR)stlbChunkObj->logical + (i * gcdMMU_STLB_1M_SIZE));
                 if (entry == stlbPhysBase)
                 {
                     gcmkPRINT("    Page table entry = 0x%08X", stlbLogical[stlb]);
@@ -2758,7 +2903,6 @@ gckMMU_DumpPageTableEntry(
             stlbChunkObj = stlbChunkObj->next;
         }
     }
-#endif
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
@@ -2798,7 +2942,8 @@ gckMMU_DumpAddressSpace(
 {
     gctUINT i;
     gctUINT next;
-    gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+    /* TODO: */
+    gcsADDRESS_AREA_PTR area = &Mmu->dynamicArea4K;
     gctUINT32_PTR map = area->mapLogical;
     gctBOOL used = gcvFALSE;
     gctUINT32 numPages;
@@ -2807,7 +2952,7 @@ gckMMU_DumpAddressSpace(
     gcmkVERIFY_OK(gckOS_AcquireMutex(Mmu->os, Mmu->pageTableMutex, gcvINFINITE));
 
     /* Find node which contains index. */
-    for (i = 0; i < area->pageTableEntries; i = next)
+    for (i = 0; i < area->stlbEntries; i = next)
     {
         switch (gcmENTRY_TYPE(map[i]))
         {
@@ -2870,7 +3015,7 @@ gckMMU_DumpRecentFreedAddress(
 gceSTATUS
 gckMMU_FillFlatMapping(
     IN gckMMU Mmu,
-    IN gctUINT32 PhysBase,
+    IN gctUINT64 PhysBase,
     IN gctSIZE_T Size
     )
 {
@@ -2879,7 +3024,7 @@ gckMMU_FillFlatMapping(
 
     if (hardware->mmuVersion)
     {
-        gcmkONERROR(_FillFlatMapping(Mmu, PhysBase, Size, gcvNULL));
+        gcmkONERROR(_FillFlatMapping(Mmu, PhysBase, Size, gcvFALSE, gcvTRUE, gcvNULL));
     }
 
     return gcvSTATUS_OK;
@@ -2891,13 +3036,15 @@ OnError:
 gceSTATUS
 gckMMU_IsFlatMapped(
     IN gckMMU Mmu,
-    OUT gctUINT32 Physical,
+    IN gctUINT64 Physical,
+    IN gctUINT32 Address,
     OUT gctBOOL *In
     )
 {
     gceSTATUS status;
     gctUINT32 i;
     gctBOOL inFlatmapping = gcvFALSE;
+
     gcmkHEADER();
 
     gcmkVERIFY_ARGUMENT(In != gcvNULL);
@@ -2907,13 +3054,29 @@ gckMMU_IsFlatMapped(
         gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
     }
 
-    for (i = 0; i < Mmu->flatMappingRangeCount; i++)
+    if (Physical != gcvINVALID_PHYSICAL_ADDRESS)
     {
-        if ((Physical >= Mmu->flatMappingRanges[i].start) &&
-            (Physical < Mmu->flatMappingRanges[i].end))
+        for (i = 0; i < Mmu->gpuPhysicalRangeCount; i++)
         {
-            inFlatmapping = gcvTRUE;
-            break;
+            if ((Physical >= Mmu->gpuPhysicalRanges[i].start) &&
+                (Physical <= Mmu->gpuPhysicalRanges[i].end))
+            {
+                inFlatmapping = gcvTRUE;
+                break;
+            }
+        }
+    }
+
+    if (Address != gcvINVALID_ADDRESS)
+    {
+        for (i = 0; i < Mmu->gpuAddressRangeCount; i++)
+        {
+            if ((Address >= Mmu->gpuAddressRanges[i].start) &&
+                (Address <= Mmu->gpuAddressRanges[i].end))
+            {
+                inFlatmapping = gcvTRUE;
+                break;
+            }
         }
     }
 
@@ -2928,53 +3091,170 @@ OnError:
 }
 
 gceSTATUS
-gckMMU_AttachHardware(
+gckMMU_SetupPerHardware(
     IN gckMMU Mmu,
-    IN gckHARDWARE Hardware
+    IN gckHARDWARE Hardware,
+    IN gckDEVICE Device
     )
 {
-    gcmkHEADER();
+    gctBOOL needMapInternalSRAM = gcvFALSE;
+    gctPHYS_ADDR_T reservedBase = gcvINVALID_PHYSICAL_ADDRESS;
+    gctPHYS_ADDR_T extSRAMBase = gcvINVALID_PHYSICAL_ADDRESS;
+    gctUINT32 reservedSize = 0;
+    gctUINT i = 0;
+    gctUINT j = 0;
+    gceSTATUS status;
+    gckKERNEL kernel = Hardware->kernel;
+
+    gcmkHEADER_ARG("Mmu=0x%x Hardware=0x%x", Mmu, Hardware);
 
     gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
 
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE, "Attach core %d", Hardware->core);
+    if (Hardware->mmuVersion == 0)
+    {
+        gcmkONERROR(gcvSTATUS_OK);
+    }
+
+    if (!Mmu->sRAMMapped)
+    {
+        /* Map all the SRAMs in MMU table. */
+        for (i = 0; i < gcvCORE_COUNT; i++)
+        {
+            reservedBase = Device->sRAMBases[i][gcvSRAM_INTERNAL];
+            reservedSize = Device->sRAMSizes[i][gcvSRAM_INTERNAL];
+            needMapInternalSRAM = reservedSize && (reservedBase != gcvINVALID_PHYSICAL_ADDRESS);
+
+            /* Map the internal SRAM. */
+            if (needMapInternalSRAM)
+            {
+                gcmkPRINT("Galcore Info: MMU mapped core%d internal SRAM base=0x%llx size=0x%x",
+                    i,
+                    reservedBase,
+                    reservedSize
+                    );
+
+                /*
+                 * Default gpu virtual base = 0.
+                 * It can be specified if not conflict with existing mapping.
+                 */
+
+                Device->sRAMBaseAddress[i][gcvSRAM_INTERNAL] = 0;
+
+                gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(
+                    Mmu->os,
+                    reservedBase,
+                    &reservedBase
+                    ));
+
+                gcmkONERROR(_FillFlatMapping(
+                    Mmu,
+                    reservedBase,
+                    reservedSize,
+                    gcvTRUE,
+                    gcvTRUE,
+                    &Device->sRAMBaseAddress[i][gcvSRAM_INTERNAL]
+                    ));
+            }
+
+            /* Map all the axi SRAMs in MMU table. */
+            for (j = gcvSRAM_EXTERNAL0; j < gcvSRAM_COUNT; j++)
+            {
+                if (Device->sRAMSizes[i][j] &&
+                   (Device->sRAMBases[i][j] != gcvINVALID_PHYSICAL_ADDRESS))
+                {
+                    gcmkPRINT("Galcore Info: MMU mapped core %d SRAM[%d] base=0x%llx size=0x%x",
+                        i,
+                        j,
+                        Device->sRAMBases[i][j],
+                        Device->sRAMSizes[i][j]
+                        );
+
+                    Device->sRAMBaseAddress[i][j] = 0;
+
+                    gcmkONERROR(gckOS_CPUPhysicalToGPUPhysical(
+                        Mmu->os,
+                        Device->sRAMBases[i][j],
+                        &extSRAMBase
+                        ));
+
+                    gcmkONERROR(_FillFlatMapping(
+                        Mmu,
+                        extSRAMBase,
+                        Device->sRAMSizes[i][j],
+                        gcvFALSE,
+                        gcvTRUE,
+                        &Device->sRAMBaseAddress[i][j]
+                        ));
+                }
+            }
+        }
+
+        Mmu->sRAMMapped = gcvTRUE;
+    }
+
+    /* Get per core SRAM hardware base address. */
+    for (i = 0; i < gcvSRAM_COUNT; i++)
+    {
+        if (Device->sRAMSizes[Hardware->core][i] &&
+           (Device->sRAMBases[Hardware->core][i] != gcvINVALID_PHYSICAL_ADDRESS))
+        {
+            kernel->sRAMBaseAddress[i] = Hardware->options.sRAMBaseAddress[i]
+                                       = Device->sRAMBaseAddress[Hardware->core][i];
+
+            kernel->sRAMSizes[i] = Device->sRAMSizes[Hardware->core][i];
+
+            gcmkPRINT("Galcore Info: MMU mapped core %d SRAM[%d] hardware address=0x%x size=0x%x",
+            Hardware->core,
+            i,
+            kernel->sRAMBaseAddress[i],
+            kernel->sRAMSizes[i]
+            );
+        }
+    }
 
     gcsLIST_Add(&Hardware->mmuHead, &Mmu->hardwareList);
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
+
+OnError:
+    /* Return the error. */
+    gcmkFOOTER();
+    return status;
 }
 
 
-#if !gcdPROCESS_ADDRESS_SPACE
 gceSTATUS
 gckMMU_GetPageEntry(
     IN gckMMU Mmu,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctUINT32_PTR *PageTable
     )
 {
     gctUINT32_PTR pageTable;
     gctUINT32 index;
-    gctUINT32 mtlb, stlb;
-    gcsADDRESS_AREA_PTR area = &Mmu->area[0];
+    gctUINT32 mtlbOffset, stlbOffset;
+    gcsADDRESS_AREA_PTR area = _GetProcessArea(Mmu, PageType, gcvFALSE);
 
     gcmkHEADER_ARG("Mmu=0x%08X Address=0x%08X", Mmu, Address);
     gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
 
     gcmkASSERT(Mmu->hardware->mmuVersion > 0);
 
-    mtlb   = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
+    mtlbOffset = (Address & gcdMMU_MTLB_MASK) >> gcdMMU_MTLB_SHIFT;
 
-    if (mtlb >= area->dynamicMappingStart)
+    if (mtlbOffset >= area->mappingStart)
     {
-        stlb   = (Address & gcdMMU_STLB_4K_MASK) >> gcdMMU_STLB_4K_SHIFT;
+        gctUINT32 stlbShift = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_SHIFT : gcdMMU_STLB_4K_SHIFT;
+        gctUINT32 stlbMask  = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_MASK : gcdMMU_STLB_4K_MASK;
+        gctUINT32 stlbEntryNum = (PageType == gcvPAGE_TYPE_1M) ? gcdMMU_STLB_1M_ENTRY_NUM : gcdMMU_STLB_4K_ENTRY_NUM;
 
-        pageTable = area->pageTableLogical;
+        stlbOffset = (Address & stlbMask) >> stlbShift;
 
-        index = (mtlb - area->dynamicMappingStart)
-            * gcdMMU_STLB_4K_ENTRY_NUM
-            + stlb;
+        pageTable = area->stlbLogical;
+
+        index = (mtlbOffset - area->mappingStart) * stlbEntryNum + stlbOffset;
 
         *PageTable = pageTable + index;
     }
@@ -2982,9 +3262,45 @@ gckMMU_GetPageEntry(
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 }
+
+gceSTATUS
+gckMMU_GetAreaType(
+    IN gckMMU Mmu,
+    IN gctUINT32 GpuAddress,
+    OUT gceAREA_TYPE *AreaType
+    )
+{
+    gctUINT32 mtlbIndex;
+    gctBOOL flatMapped;
+    gceSTATUS status = gcvSTATUS_OK;
+    gcsADDRESS_AREA_PTR area4K = &Mmu->dynamicArea4K;
+#if gcdENABLE_GPU_1M_PAGE
+    gcsADDRESS_AREA_PTR area1M = &Mmu->dynamicArea1M;
 #endif
 
-/******************************************************************************
-****************************** T E S T   C O D E ******************************
-******************************************************************************/
+    mtlbIndex = _MtlbOffset(GpuAddress);
+
+    gcmkONERROR(gckMMU_IsFlatMapped(Mmu, gcvINVALID_PHYSICAL_ADDRESS, GpuAddress, &flatMapped));
+
+    if (flatMapped)
+    {
+        *AreaType = gcvAREA_TYPE_FLATMAP;
+    }
+#if gcdENABLE_GPU_1M_PAGE
+    else if (mtlbIndex >= area1M->mappingStart && mtlbIndex <= area1M->mappingEnd)
+    {
+        *AreaType = gcvAREA_TYPE_1M;
+    }
+#endif
+    else if (mtlbIndex >= area4K->mappingStart && mtlbIndex <= area4K->mappingEnd)
+    {
+        *AreaType = gcvAREA_TYPE_4K;
+    }
+    else
+    {
+        *AreaType = gcvAREA_TYPE_UNKNOWN;
+    }
 
+OnError:
+    return status;
+}
index f6e687b..b1cdd1b 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -142,11 +142,12 @@ gceSTATUS gckVGMMU_Construct(
 
     /* Allocate the page table. */
     mmu->pageTableSize = (gctUINT32)MmuSize;
-    status = gckOS_AllocateContiguous(os,
-                                      gcvFALSE,
-                                      &mmu->pageTableSize,
-                                      &mmu->pageTablePhysical,
-                                      &mmu->pageTableLogical);
+    status = gckOS_AllocateNonPagedMemory(os,
+                                          gcvFALSE,
+                                          gcvALLOC_FLAG_CONTIGUOUS,
+                                          &mmu->pageTableSize,
+                                          &mmu->pageTablePhysical,
+                                          &mmu->pageTableLogical);
 
     if (status < 0)
     {
@@ -183,10 +184,10 @@ gceSTATUS gckVGMMU_Construct(
     if (status < 0)
     {
         /* Free the page table. */
-        gcmkVERIFY_OK(gckOS_FreeContiguous(mmu->os,
-                                      mmu->pageTablePhysical,
-                                      mmu->pageTableLogical,
-                                      mmu->pageTableSize));
+        gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(mmu->os,
+                                               mmu->pageTablePhysical,
+                                               mmu->pageTableLogical,
+                                               mmu->pageTableSize));
 
         /* Roll back. */
         gcmkVERIFY_OK(gckOS_DeleteMutex(os, mmu->mutex));
@@ -246,10 +247,10 @@ gceSTATUS gckVGMMU_Destroy(
     gcmkVERIFY_OBJECT(Mmu, gcvOBJ_MMU);
 
     /* Free the page table. */
-    gcmkVERIFY_OK(gckOS_FreeContiguous(Mmu->os,
-                                  Mmu->pageTablePhysical,
-                                  Mmu->pageTableLogical,
-                                  Mmu->pageTableSize));
+    gcmkVERIFY_OK(gckOS_FreeNonPagedMemory(Mmu->os,
+                                           Mmu->pageTablePhysical,
+                                           Mmu->pageTableLogical,
+                                           Mmu->pageTableSize));
 
     /* Roll back. */
     gcmkVERIFY_OK(gckOS_DeleteMutex(Mmu->os, Mmu->mutex));
index 92839cb..4eb3ecb 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index ee2b122..55b5fc7 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index abf5485..683964d 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 89a4333..8167b7c 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 44a1bb0..8443e77 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -57,7 +57,7 @@
 
 #if gcdENABLE_VG
 
-#define _GC_OBJ_ZONE            gcvZONE_VG
+#define _GC_OBJ_ZONE            gcdZONE_VG
 
 /******************************************************************************\
 ******************************* gckKERNEL API Code ******************************
@@ -252,7 +252,7 @@ gceSTATUS gckVGKERNEL_Destroy(
 
 /*******************************************************************************
 **
-**  gckKERNEL_Dispatch
+**  gckVGKERNEL_Dispatch
 **
 **  Dispatch a command received from the user HAL layer.
 **
@@ -273,17 +273,12 @@ gceSTATUS gckVGKERNEL_Destroy(
 */
 gceSTATUS gckVGKERNEL_Dispatch(
     IN gckKERNEL Kernel,
-    IN gctBOOL FromUser,
     IN OUT gcsHAL_INTERFACE * Interface
     )
 {
     gceSTATUS status;
     gcsHAL_INTERFACE * kernelInterface = Interface;
     gctUINT32 processID;
-    gckKERNEL kernel = Kernel;
-    gctPHYS_ADDR physical = gcvNULL;
-    gctPOINTER logical = gcvNULL;
-    gctSIZE_T bytes = 0;
     gctBOOL powerMutexAcquired = gcvFALSE;
 
     gcmkHEADER_ARG("Kernel=0x%x Interface=0x%x ", Kernel, Interface);
@@ -320,129 +315,6 @@ gceSTATUS gckVGKERNEL_Dispatch(
             ));
         break;
 
-    case gcvHAL_ALLOCATE_NON_PAGED_MEMORY:
-        bytes = (gctSIZE_T) kernelInterface->u.AllocateNonPagedMemory.bytes;
-        /* Allocate non-paged memory. */
-        gcmkERR_BREAK(gckOS_AllocateNonPagedMemory(
-            Kernel->os,
-            gcvTRUE,
-            gcvALLOC_FLAG_CONTIGUOUS,
-            &bytes,
-            &physical,
-            &logical
-            ));
-
-        kernelInterface->u.AllocateNonPagedMemory.bytes    = bytes;
-        kernelInterface->u.AllocateNonPagedMemory.logical  = gcmPTR_TO_UINT64(logical);
-        kernelInterface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical);
-        break;
-
-    case gcvHAL_FREE_NON_PAGED_MEMORY:
-        physical = gcmNAME_TO_PTR(kernelInterface->u.FreeNonPagedMemory.physical);
-
-        /* Unmap user logical out of physical memory first. */
-        gcmkERR_BREAK(gckOS_UnmapUserLogical(
-            Kernel->os,
-            physical,
-            (gctSIZE_T) kernelInterface->u.FreeNonPagedMemory.bytes,
-            gcmUINT64_TO_PTR(kernelInterface->u.FreeNonPagedMemory.logical)));
-
-
-        /* Free non-paged memory. */
-        gcmkERR_BREAK(gckOS_FreeNonPagedMemory(
-            Kernel->os,
-            (gctSIZE_T) kernelInterface->u.FreeNonPagedMemory.bytes,
-            physical,
-            gcmUINT64_TO_PTR(kernelInterface->u.FreeNonPagedMemory.logical)
-            ));
-
-        gcmRELEASE_NAME(kernelInterface->u.FreeNonPagedMemory.physical);
-        break;
-
-    case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY:
-        bytes = (gctSIZE_T) kernelInterface->u.AllocateContiguousMemory.bytes;
-        /* Allocate contiguous memory. */
-        gcmkERR_BREAK(gckOS_AllocateContiguous(
-            Kernel->os,
-            gcvTRUE,
-            &bytes,
-            &physical,
-            &logical
-            ));
-
-         kernelInterface->u.AllocateContiguousMemory.bytes    = bytes;
-         kernelInterface->u.AllocateContiguousMemory.logical  = gcmPTR_TO_UINT64(logical);
-         kernelInterface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical);
-         break;
-
-    case gcvHAL_FREE_CONTIGUOUS_MEMORY:
-        physical = gcmNAME_TO_PTR(kernelInterface->u.FreeContiguousMemory.physical);
-        /* Unmap user logical out of physical memory first. */
-        gcmkERR_BREAK(gckOS_UnmapUserLogical(
-            Kernel->os,
-            physical,
-            (gctSIZE_T) kernelInterface->u.FreeContiguousMemory.bytes,
-            gcmUINT64_TO_PTR(kernelInterface->u.FreeContiguousMemory.logical)
-            ));
-
-        /* Free contiguous memory. */
-        gcmkERR_BREAK(gckOS_FreeContiguous(
-            Kernel->os,
-            physical,
-            gcmUINT64_TO_PTR(kernelInterface->u.FreeContiguousMemory.logical),
-            (gctSIZE_T) kernelInterface->u.FreeContiguousMemory.bytes
-            ));
-
-        gcmRELEASE_NAME(kernelInterface->u.FreeContiguousMemory.physical);
-        break;
-
-    case gcvHAL_ALLOCATE_VIDEO_MEMORY:
-        gcmkERR_BREAK(gcvSTATUS_NOT_SUPPORTED);
-        break;
-
-    case gcvHAL_MAP_MEMORY:
-        /* Map memory. */
-        gcmkERR_BREAK(gckKERNEL_MapMemory(
-            Kernel,
-            gcmINT2PTR(kernelInterface->u.MapMemory.physical),
-            (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
-            &logical
-            ));
-        kernelInterface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical);
-        break;
-
-    case gcvHAL_UNMAP_MEMORY:
-        /* Unmap memory. */
-        gcmkERR_BREAK(gckKERNEL_UnmapMemory(
-            Kernel,
-            gcmINT2PTR(kernelInterface->u.MapMemory.physical),
-            (gctSIZE_T) kernelInterface->u.MapMemory.bytes,
-            gcmUINT64_TO_PTR(kernelInterface->u.MapMemory.logical),
-            processID
-            ));
-        break;
-
-    case gcvHAL_MAP_USER_MEMORY:
-
-        gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
-
-        break;
-
-    case gcvHAL_UNMAP_USER_MEMORY:
-
-        gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
-
-        break;
-
-    case gcvHAL_LOCK_VIDEO_MEMORY:
-        gcmkONERROR(gckKERNEL_LockVideoMemory(Kernel, gcvCORE_VG, processID, FromUser, Interface));
-        break;
-
-    case gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY:
-        gcmkERR_BREAK(gckKERNEL_BottomHalfUnlockVideoMemory(Kernel, processID,
-                                                            kernelInterface->u.BottomHalfUnlockVideoMemory.node));
-        break;
-
     case gcvHAL_USER_SIGNAL:
 #if !USE_NEW_LINUX_SIGNAL
         /* Dispatch depends on the user signal subcommands. */
@@ -498,28 +370,7 @@ gceSTATUS gckVGKERNEL_Dispatch(
 #endif
         break;
 
-    case gcvHAL_COMMIT:
-        /* Commit a command and context buffer. */
-        gcmkERR_BREAK(gckVGCOMMAND_Commit(
-            Kernel->vg->command,
-            gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.context),
-            gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.queue),
-            kernelInterface->u.VGCommit.entryCount,
-            gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.taskTable)
-            ));
-        break;
-
-    case gcvHAL_GET_BASE_ADDRESS:
-       /* Get base address. */
-        gcmkONERROR(
-            gckOS_GetBaseAddress(Kernel->os,
-                                 &Interface->u.GetBaseAddress.baseAddress));
-        break;
-
-    case gcvHAL_EVENT_COMMIT:
-        gcmkERR_BREAK(gcvSTATUS_NOT_SUPPORTED);
-        break;
-    case gcvHAL_READ_REGISTER:
+        case gcvHAL_READ_REGISTER:
 #if gcdREGISTER_ACCESS_FROM_USER
         {
             gceCHIPPOWERSTATE power;
@@ -585,9 +436,32 @@ gceSTATUS gckVGKERNEL_Dispatch(
         status = gcvSTATUS_NOT_SUPPORTED;
 #endif
         break;
+
+    case gcvHAL_COMMIT:
+        /* Commit a command and context buffer. */
+        gcmkERR_BREAK(gckVGCOMMAND_Commit(
+            Kernel->vg->command,
+            gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.context),
+            gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.queue),
+            kernelInterface->u.VGCommit.entryCount,
+            gcmUINT64_TO_PTR(kernelInterface->u.VGCommit.taskTable)
+            ));
+        break;
+
+    case gcvHAL_GET_BASE_ADDRESS:
+       /* Get base address. */
+        gcmkONERROR(
+            gckOS_GetBaseAddress(Kernel->os,
+                                 &Interface->u.GetBaseAddress.baseAddress));
+        break;
+
+    case gcvHAL_EVENT_COMMIT:
+        gcmkERR_BREAK(gcvSTATUS_NOT_SUPPORTED);
+        break;
+
     default:
         /* Invalid command, try gckKERNEL_Dispatch */
-        status = gckKERNEL_Dispatch(Kernel, gcvNULL, gcvTRUE, Interface);
+        status = gckKERNEL_Dispatch(Kernel, gcvNULL, Interface);
     }
 
 OnError:
index 63da883..2e58368 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 5c27cba..755063e 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -129,13 +129,13 @@ _Split(
     node->VidMem.bytes     = Node->VidMem.bytes  - Bytes;
     node->VidMem.alignment = 0;
     node->VidMem.locked    = 0;
-    node->VidMem.memory    = Node->VidMem.memory;
+    node->VidMem.parent    = Node->VidMem.parent;
     node->VidMem.pool      = Node->VidMem.pool;
-    node->VidMem.physical  = Node->VidMem.physical;
 #ifdef __QNXNTO__
     node->VidMem.processID = 0;
     node->VidMem.logical   = gcvNULL;
 #endif
+    node->VidMem.kvaddr    = gcvNULL;
 
     /* Insert node behind specified node. */
     node->VidMem.next = Node->VidMem.next;
@@ -213,152 +213,6 @@ _Merge(
 ******************************* gckVIDMEM API Code ******************************
 \******************************************************************************/
 
-/*******************************************************************************
-**
-**  gckVIDMEM_ConstructVirtual
-**
-**  Construct a new gcuVIDMEM_NODE union for virtual memory.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gctSIZE_T Bytes
-**          Number of byte to allocate.
-**
-**  OUTPUT:
-**
-**      gcuVIDMEM_NODE_PTR * Node
-**          Pointer to a variable that receives the gcuVIDMEM_NODE union pointer.
-*/
-gceSTATUS
-gckVIDMEM_ConstructVirtual(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 Flag,
-    IN gctSIZE_T Bytes,
-    OUT gcuVIDMEM_NODE_PTR * Node
-    )
-{
-    gckOS os;
-    gceSTATUS status;
-    gcuVIDMEM_NODE_PTR node = gcvNULL;
-    gctPOINTER pointer = gcvNULL;
-    gctINT i;
-
-    gcmkHEADER_ARG("Kernel=0x%x Flag=%x Bytes=%lu", Kernel, Flag, Bytes);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
-
-    /* Extract the gckOS object pointer. */
-    os = Kernel->os;
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
-
-    /* Allocate an gcuVIDMEM_NODE union. */
-    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
-
-    node = pointer;
-
-    /* Initialize gcuVIDMEM_NODE union for virtual memory. */
-    node->Virtual.kernel        = Kernel;
-    node->Virtual.contiguous    = Flag & gcvALLOC_FLAG_CONTIGUOUS;
-    node->Virtual.logical       = gcvNULL;
-#if gcdENABLE_VG
-    node->Virtual.kernelVirtual = gcvNULL;
-#endif
-    node->Virtual.secure        = (Flag & gcvALLOC_FLAG_SECURITY) != 0;
-    node->Virtual.onFault       = (Flag & gcvALLOC_FLAG_ALLOC_ON_FAULT) != 0;
-
-    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
-    {
-        node->Virtual.lockeds[i]        = 0;
-        node->Virtual.pageTables[i]     = gcvNULL;
-    }
-
-    /* Allocate the virtual memory. */
-    gcmkONERROR(
-        gckOS_AllocatePagedMemoryEx(os,
-                                    Flag,
-                                    node->Virtual.bytes = Bytes,
-                                    &node->Virtual.gid,
-                                    &node->Virtual.physical));
-
-    if (node->Virtual.onFault == gcvTRUE)
-    {
-        gcsLIST_Add(&node->Virtual.head, &Kernel->db->onFaultVidmemList);
-    }
-
-    /* Return pointer to the gcuVIDMEM_NODE union. */
-    *Node = node;
-
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                   "Created virtual node 0x%x for %u bytes @ 0x%x",
-                   node, Bytes, node->Virtual.physical);
-
-    /* Success. */
-    gcmkFOOTER_ARG("*Node=0x%x", *Node);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Roll back. */
-    if (node != gcvNULL)
-    {
-        /* Free the structure. */
-        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
-    }
-
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gckVIDMEM_DestroyVirtual
-**
-**  Destroy an gcuVIDMEM_NODE union for virtual memory.
-**
-**  INPUT:
-**
-**      gcuVIDMEM_NODE_PTR Node
-**          Pointer to a gcuVIDMEM_NODE union.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckVIDMEM_DestroyVirtual(
-    IN gcuVIDMEM_NODE_PTR Node
-    )
-{
-    gckOS os;
-
-    gcmkHEADER_ARG("Node=0x%x", Node);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Node->Virtual.kernel, gcvOBJ_KERNEL);
-
-    /* Extact the gckOS object pointer. */
-    os = Node->Virtual.kernel->os;
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
-
-    if (Node->Virtual.onFault == gcvTRUE)
-    {
-        gcsLIST_Del(&Node->Virtual.head);
-    }
-
-    /* Delete the gcuVIDMEM_NODE union. */
-    gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, Node));
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
 /*******************************************************************************
 **
 **  gckVIDMEM_Construct
@@ -370,8 +224,8 @@ gckVIDMEM_DestroyVirtual(
 **      gckOS Os
 **          Pointer to an gckOS object.
 **
-**      gctUINT32 BaseAddress
-**          Base address for the video memory heap.
+**      gctPHYS_ADDR_T PhysicalBase
+**          Base physical address for the video memory heap.
 **
 **      gctSIZE_T Bytes
 **          Number of bytes in the video memory heap.
@@ -393,7 +247,7 @@ gckVIDMEM_DestroyVirtual(
 gceSTATUS
 gckVIDMEM_Construct(
     IN gckOS Os,
-    IN gctUINT32 BaseAddress,
+    IN gctPHYS_ADDR_T PhysicalBase,
     IN gctSIZE_T Bytes,
     IN gctSIZE_T Threshold,
     IN gctSIZE_T BankSize,
@@ -407,10 +261,11 @@ gckVIDMEM_Construct(
     gctPOINTER pointer = gcvNULL;
     gctUINT32 heapBytes;
     gctUINT32 bankSize;
+    gctUINT32 base = 0;
 
-    gcmkHEADER_ARG("Os=0x%x BaseAddress=%08x Bytes=%lu Threshold=%lu "
+    gcmkHEADER_ARG("Os=0x%x PhysicalBase=%12llx Bytes=%lu Threshold=%lu "
                    "BankSize=%lu",
-                   Os, BaseAddress, Bytes, Threshold, BankSize);
+                   Os, PhysicalBase, Bytes, Threshold, BankSize);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -431,15 +286,14 @@ gckVIDMEM_Construct(
     memory->os          = Os;
 
     /* Set video memory heap information. */
-    memory->baseAddress  = BaseAddress;
+    memory->physicalBase = PhysicalBase;
     memory->bytes        = heapBytes;
     memory->freeBytes    = heapBytes;
     memory->minFreeBytes = heapBytes;
+    memory->capability   = ~0u;
     memory->threshold    = Threshold;
     memory->mutex        = gcvNULL;
 
-    BaseAddress = 0;
-
     /* Walk all possible banks. */
     for (i = 0; i < gcmCOUNTOF(memory->sentinel); ++i)
     {
@@ -453,7 +307,7 @@ gckVIDMEM_Construct(
         else
         {
             /* Compute number of bytes for this bank. */
-            bytes = gcmALIGN(BaseAddress + 1, bankSize) - BaseAddress;
+            bytes = gcmALIGN(base + 1, bankSize) - base;
 
             if (bytes > heapBytes)
             {
@@ -478,17 +332,16 @@ gckVIDMEM_Construct(
         node = pointer;
 
         /* Initialize gcuVIDMEM_NODE union. */
-        node->VidMem.memory    = memory;
+        node->VidMem.parent    = memory;
 
         node->VidMem.next      =
         node->VidMem.prev      =
         node->VidMem.nextFree  =
         node->VidMem.prevFree  = &memory->sentinel[i];
 
-        node->VidMem.offset    = BaseAddress;
+        node->VidMem.offset    = base;
         node->VidMem.bytes     = bytes;
         node->VidMem.alignment = 0;
-        node->VidMem.physical  = 0;
         node->VidMem.pool      = gcvPOOL_UNKNOWN;
 
         node->VidMem.locked    = 0;
@@ -501,6 +354,7 @@ gckVIDMEM_Construct(
 #if gcdENABLE_VG
         node->VidMem.kernelVirtual = gcvNULL;
 #endif
+        node->VidMem.kvaddr    = gcvNULL;
 
         /* Initialize the linked list of nodes. */
         memory->sentinel[i].VidMem.next     =
@@ -512,56 +366,65 @@ gckVIDMEM_Construct(
         memory->sentinel[i].VidMem.bytes = 0;
 
         /* Adjust address for next bank. */
-        BaseAddress += bytes;
-        heapBytes       -= bytes;
-        banks       ++;
+        base += bytes;
+        heapBytes   -= bytes;
+        banks ++;
     }
 
     /* Assign all the bank mappings. */
-    memory->mapping[gcvSURF_RENDER_TARGET]      = banks - 1;
-    memory->mapping[gcvSURF_BITMAP]             = banks - 1;
+    memory->mapping[gcvVIDMEM_TYPE_COLOR_BUFFER]    = banks - 1;
+    memory->mapping[gcvVIDMEM_TYPE_BITMAP]          = banks - 1;
+
+    if (banks > 1) --banks;
+    memory->mapping[gcvVIDMEM_TYPE_DEPTH_BUFFER]    = banks - 1;
+    memory->mapping[gcvVIDMEM_TYPE_HZ_BUFFER]       = banks - 1;
+
     if (banks > 1) --banks;
-    memory->mapping[gcvSURF_DEPTH]              = banks - 1;
-    memory->mapping[gcvSURF_HIERARCHICAL_DEPTH] = banks - 1;
+    memory->mapping[gcvVIDMEM_TYPE_TEXTURE]         = banks - 1;
+
     if (banks > 1) --banks;
-    memory->mapping[gcvSURF_TEXTURE]            = banks - 1;
+    memory->mapping[gcvVIDMEM_TYPE_VERTEX_BUFFER]   = banks - 1;
+
     if (banks > 1) --banks;
-    memory->mapping[gcvSURF_VERTEX]             = banks - 1;
+    memory->mapping[gcvVIDMEM_TYPE_INDEX_BUFFER]    = banks - 1;
+
     if (banks > 1) --banks;
-    memory->mapping[gcvSURF_INDEX]              = banks - 1;
+    memory->mapping[gcvVIDMEM_TYPE_TILE_STATUS]     = banks - 1;
+
     if (banks > 1) --banks;
-    memory->mapping[gcvSURF_TILE_STATUS]        = banks - 1;
+    memory->mapping[gcvVIDMEM_TYPE_COMMAND]         = banks - 1;
+
     if (banks > 1) --banks;
-    memory->mapping[gcvSURF_TYPE_UNKNOWN]       = 0;
+    memory->mapping[gcvVIDMEM_TYPE_GENERIC]         = 0;
 
 #if gcdENABLE_VG
-    memory->mapping[gcvSURF_IMAGE]   = 0;
-    memory->mapping[gcvSURF_MASK]    = 0;
-    memory->mapping[gcvSURF_SCISSOR] = 0;
+    memory->mapping[gcvVIDMEM_TYPE_IMAGE]   = 0;
+    memory->mapping[gcvVIDMEM_TYPE_MASK]    = 0;
+    memory->mapping[gcvVIDMEM_TYPE_SCISSOR] = 0;
 #endif
-    memory->mapping[gcvSURF_ICACHE]             = 0;
-    memory->mapping[gcvSURF_TXDESC]             = 0;
-    memory->mapping[gcvSURF_FENCE]              = 0;
-    memory->mapping[gcvSURF_TFBHEADER]          = 0;
+    memory->mapping[gcvVIDMEM_TYPE_ICACHE]      = 0;
+    memory->mapping[gcvVIDMEM_TYPE_TXDESC]      = 0;
+    memory->mapping[gcvVIDMEM_TYPE_FENCE]       = 0;
+    memory->mapping[gcvVIDMEM_TYPE_TFBHEADER]   = 0;
 
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
                   "[GALCORE] INDEX:         bank %d",
-                  memory->mapping[gcvSURF_INDEX]);
+                  memory->mapping[gcvVIDMEM_TYPE_INDEX_BUFFER]);
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
                   "[GALCORE] VERTEX:        bank %d",
-                  memory->mapping[gcvSURF_VERTEX]);
+                  memory->mapping[gcvVIDMEM_TYPE_VERTEX_BUFFER]);
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
                   "[GALCORE] TEXTURE:       bank %d",
-                  memory->mapping[gcvSURF_TEXTURE]);
+                  memory->mapping[gcvVIDMEM_TYPE_TEXTURE]);
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
                   "[GALCORE] RENDER_TARGET: bank %d",
-                  memory->mapping[gcvSURF_RENDER_TARGET]);
+                  memory->mapping[gcvVIDMEM_TYPE_COLOR_BUFFER]);
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
                   "[GALCORE] DEPTH:         bank %d",
-                  memory->mapping[gcvSURF_DEPTH]);
+                  memory->mapping[gcvVIDMEM_TYPE_DEPTH_BUFFER]);
     gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
                   "[GALCORE] TILE_STATUS:   bank %d",
-                  memory->mapping[gcvSURF_TILE_STATUS]);
+                  memory->mapping[gcvVIDMEM_TYPE_TILE_STATUS]);
 
     /* Allocate the mutex. */
     gcmkONERROR(gckOS_CreateMutex(Os, &memory->mutex));
@@ -683,7 +546,7 @@ gckVIDMEM_Destroy(
 **      gckOS Os
 **          Pointer to gcoOS object.
 **
-**      gceSURF_TYPE Type
+**      gceVIDMEM_TYPE Type
 **          Type of allocation.
 **
 **      gctUINT32 BaseAddress
@@ -699,7 +562,7 @@ gckVIDMEM_Destroy(
 static gceSTATUS
 _GetSurfaceBankAlignment(
     IN gckKERNEL Kernel,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     IN gctUINT32 BaseAddress,
     OUT gctUINT32_PTR AlignmentOffset
     )
@@ -719,7 +582,7 @@ _GetSurfaceBankAlignment(
 
     switch (Type)
     {
-    case gcvSURF_RENDER_TARGET:
+    case gcvVIDMEM_TYPE_COLOR_BUFFER:
         bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
 
         /* Align to the first bank. */
@@ -728,7 +591,7 @@ _GetSurfaceBankAlignment(
             ((1 << (gcdBANK_BIT_END + 1)) + 0) -  (BaseAddress & byteMask);
         break;
 
-    case gcvSURF_DEPTH:
+    case gcvVIDMEM_TYPE_DEPTH_BUFFER:
         bank = (BaseAddress & bankMask) >> (gcdBANK_BIT_START);
 
         /* Align to the third bank. */
@@ -763,7 +626,7 @@ _FindNode(
     IN gckVIDMEM Memory,
     IN gctINT Bank,
     IN gctSIZE_T Bytes,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     IN OUT gctUINT32_PTR Alignment
     )
 {
@@ -796,7 +659,7 @@ _FindNode(
         gcmkONERROR(_GetSurfaceBankAlignment(
             Kernel,
             Type,
-            node->VidMem.memory->baseAddress + node->VidMem.offset,
+            (gctUINT32)(node->VidMem.parent->physicalBase + node->VidMem.offset),
             &bankAlignment));
 
         bankAlignment = gcmALIGN(bankAlignment, *Alignment);
@@ -876,7 +739,7 @@ OnError:
 **      gctUINT32 Alignment
 **          Byte alignment for allocation.
 **
-**      gceSURF_TYPE Type
+**      gceVIDMEM_TYPE Type
 **          Type of surface to allocate (use by bank optimization).
 **
 **      gctBOOL Specified
@@ -889,13 +752,13 @@ OnError:
 **      gcuVIDMEM_NODE_PTR * Node
 **          Pointer to a variable that will hold the allocated memory node.
 */
-gceSTATUS
+static gceSTATUS
 gckVIDMEM_AllocateLinear(
     IN gckKERNEL Kernel,
     IN gckVIDMEM Memory,
     IN gctSIZE_T Bytes,
     IN gctUINT32 Alignment,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     IN gctBOOL Specified,
     OUT gcuVIDMEM_NODE_PTR * Node
     )
@@ -913,7 +776,7 @@ gckVIDMEM_AllocateLinear(
     gcmkVERIFY_OBJECT(Memory, gcvOBJ_VIDMEM);
     gcmkVERIFY_ARGUMENT(Bytes > 0);
     gcmkVERIFY_ARGUMENT(Node != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Type < gcvSURF_NUM_TYPES);
+    gcmkVERIFY_ARGUMENT(Type < gcvVIDMEM_TYPE_COUNT);
 
     /* Acquire the mutex. */
     gcmkONERROR(gckOS_AcquireMutex(Memory->os, Memory->mutex, gcvINFINITE));
@@ -1040,7 +903,7 @@ gckVIDMEM_AllocateLinear(
 
     /* Fill in the information. */
     node->VidMem.alignment = alignment;
-    node->VidMem.memory    = Memory;
+    node->VidMem.parent    = Memory;
 #ifdef __QNXNTO__
     node->VidMem.logical   = gcvNULL;
     gcmkONERROR(gckOS_GetProcessID(&node->VidMem.processID));
@@ -1086,301 +949,306 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckVIDMEM_Free
+**  gckVIDMEM_AllocateVirtual
 **
-**  Free an allocated video memory node.
+**  Construct a new gcuVIDMEM_NODE union for virtual memory.
 **
 **  INPUT:
 **
 **      gckKERNEL Kernel
 **          Pointer to an gckKERNEL object.
 **
-**      gcuVIDMEM_NODE_PTR Node
-**          Pointer to a gcuVIDMEM_NODE object.
+**      gctSIZE_T Bytes
+**          Number of byte to allocate.
 **
 **  OUTPUT:
 **
-**      Nothing.
+**      gcuVIDMEM_NODE_PTR * Node
+**          Pointer to a variable that receives the gcuVIDMEM_NODE union pointer.
 */
-gceSTATUS
-gckVIDMEM_Free(
+static gceSTATUS
+gckVIDMEM_AllocateVirtual(
     IN gckKERNEL Kernel,
-    IN gcuVIDMEM_NODE_PTR Node
+    IN gctUINT32 Flag,
+    IN gctSIZE_T Bytes,
+    OUT gcuVIDMEM_NODE_PTR * Node
     )
 {
+    gckOS os;
     gceSTATUS status;
-    gckKERNEL kernel = gcvNULL;
-    gckVIDMEM memory = gcvNULL;
-    gcuVIDMEM_NODE_PTR node;
-    gctBOOL mutexAcquired = gcvFALSE;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gctPOINTER pointer = gcvNULL;
+    gctINT i;
 
-    gcmkHEADER_ARG("Node=0x%x", Node);
+    gcmkHEADER_ARG("Kernel=0x%x Flag=%x Bytes=%lu", Kernel, Flag, Bytes);
 
     /* Verify the arguments. */
-    if ((Node == gcvNULL)
-    ||  (Node->VidMem.memory == gcvNULL)
-    )
+    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+    gcmkVERIFY_ARGUMENT(Bytes > 0);
+    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+
+    /* Extract the gckOS object pointer. */
+    os = Kernel->os;
+    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+    /* Allocate an gcuVIDMEM_NODE union. */
+    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
+
+    node = pointer;
+
+    /* Initialize gcuVIDMEM_NODE union for virtual memory. */
+    node->Virtual.kernel        = Kernel;
+    node->Virtual.contiguous    = Flag & gcvALLOC_FLAG_CONTIGUOUS;
+    node->Virtual.logical       = gcvNULL;
+    node->Virtual.kvaddr        = gcvNULL;
+    node->Virtual.bytes         = Bytes;
+#if gcdENABLE_VG
+    node->Virtual.kernelVirtual = gcvNULL;
+#endif
+    node->Virtual.secure        = (Flag & gcvALLOC_FLAG_SECURITY) != 0;
+    node->Virtual.onFault       = (Flag & gcvALLOC_FLAG_ALLOC_ON_FAULT) != 0;
+
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
     {
-        /* Invalid object. */
-        gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
+        node->Virtual.lockeds[i]        = 0;
+        node->Virtual.pageTables[i]     = gcvNULL;
     }
 
-    /**************************** Video Memory ********************************/
+    /* Allocate the virtual memory. */
+    gcmkONERROR(
+        gckOS_AllocatePagedMemory(os,
+                                  Flag,
+                                  &node->Virtual.bytes,
+                                  &node->Virtual.gid,
+                                  &node->Virtual.physical));
+
+    /* Calculate required GPU page (4096) count. */
+    /* Assume start address is 4096 aligned. */
+    node->Virtual.pageCount = (gctSIZE_T)(((gctUINT64)node->Virtual.bytes + (4096 - 1)) >> 12);
+
+    /* Return pointer to the gcuVIDMEM_NODE union. */
+    *Node = node;
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                   "Created virtual node 0x%x for %u bytes @ 0x%x",
+                   node, Bytes, node->Virtual.physical);
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Node=0x%x", *Node);
+    return gcvSTATUS_OK;
 
-    if (Node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+OnError:
+    /* Roll back. */
+    if (node != gcvNULL)
     {
-        /* Extract pointer to gckVIDMEM object owning the node. */
-        memory = Node->VidMem.memory;
+        /* Free the structure. */
+        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+    }
 
-        /* Acquire the mutex. */
-        gcmkONERROR(
-            gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
 
-        mutexAcquired = gcvTRUE;
+static gceSTATUS
+_AddToBlockList(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    VidMemBlock->next   = Kernel->vidMemBlock;
+    Kernel->vidMemBlock = VidMemBlock;
 
-#ifdef __QNXNTO__
-        /* Unmap the video memory. */
-        if (Node->VidMem.logical != gcvNULL)
+    return gcvSTATUS_OK;
+}
+
+static gceSTATUS
+_RemoveFromBlockList(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    gckVIDMEM_BLOCK vidMemBlock;
+    gckVIDMEM_BLOCK previous = gcvNULL;
+    gceHARDWARE_TYPE hwType;
+
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
+
+    for (vidMemBlock = Kernel->vidMemBlock; vidMemBlock != gcvNULL; vidMemBlock = vidMemBlock->next)
+    {
+        if (vidMemBlock->addresses[hwType] == VidMemBlock->addresses[hwType])
         {
-            gckKERNEL_UnmapVideoMemory(
-                    Kernel,
-                    Node->VidMem.logical,
-                    Node->VidMem.processID,
-                    Node->VidMem.bytes);
-            Node->VidMem.logical = gcvNULL;
+            break;
         }
+        previous = vidMemBlock;
+    }
 
-        /* Reset. */
-        Node->VidMem.processID = 0;
+    if (previous)
+    {
+        previous->next = vidMemBlock->next;
+    }
+    else
+    {
+        Kernel->vidMemBlock = vidMemBlock->next;
+    }
 
-        /* Don't try to re-free an already freed node. */
-        if ((Node->VidMem.nextFree == gcvNULL)
-        &&  (Node->VidMem.prevFree == gcvNULL)
-        )
-#endif
-        {
-#if gcdENABLE_VG
-            if (Node->VidMem.kernelVirtual)
-            {
-                gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                        "%s(%d) Unmap %x from kernel space.",
-                        __FUNCTION__, __LINE__,
-                        Node->VidMem.kernelVirtual);
-
-                gcmkVERIFY_OK(
-                    gckOS_UnmapPhysical(memory->os,
-                                        Node->VidMem.kernelVirtual,
-                                        Node->VidMem.bytes));
-
-                Node->VidMem.kernelVirtual = gcvNULL;
-            }
-#endif
-
-            /* Check if Node is already freed. */
-            if (Node->VidMem.nextFree)
-            {
-                /* Node is alread freed. */
-                gcmkONERROR(gcvSTATUS_INVALID_DATA);
-            }
-
-            /* Update the number of free bytes. */
-            memory->freeBytes += Node->VidMem.bytes;
-
-            /* Find the next free node. */
-            for (node = Node->VidMem.next;
-                 node != gcvNULL && node->VidMem.nextFree == gcvNULL;
-                 node = node->VidMem.next) ;
-
-            /* Insert this node in the free list. */
-            Node->VidMem.nextFree = node;
-            Node->VidMem.prevFree = node->VidMem.prevFree;
+    vidMemBlock->next = gcvNULL;
 
-            Node->VidMem.prevFree->VidMem.nextFree =
-            node->VidMem.prevFree                  = Node;
+    return gcvSTATUS_OK;
+}
 
-            /* Is the next node a free node and not the sentinel? */
-            if ((Node->VidMem.next == Node->VidMem.nextFree)
-            &&  (Node->VidMem.next->VidMem.bytes != 0)
-            )
-            {
-                /* Merge this node with the next node. */
-                gcmkONERROR(_Merge(memory->os, node = Node));
-                gcmkASSERT(node->VidMem.nextFree != node);
-                gcmkASSERT(node->VidMem.prevFree != node);
-            }
+static gckVIDMEM_BLOCK
+_FindFreeBlock(
+    IN gckKERNEL Kernel,
+    IN gctSIZE_T Bytes
+    )
+{
+    gckVIDMEM_BLOCK vidMemBlock;
 
-            /* Is the previous node a free node and not the sentinel? */
-            if ((Node->VidMem.prev == Node->VidMem.prevFree)
-            &&  (Node->VidMem.prev->VidMem.bytes != 0)
-            )
-            {
-                /* Merge this node with the previous node. */
-                gcmkONERROR(_Merge(memory->os, node = Node->VidMem.prev));
-                gcmkASSERT(node->VidMem.nextFree != node);
-                gcmkASSERT(node->VidMem.prevFree != node);
-            }
+    for (vidMemBlock = Kernel->vidMemBlock; vidMemBlock != gcvNULL; vidMemBlock = vidMemBlock->next)
+    {
+        if (vidMemBlock->freeBytes >= Bytes)
+        {
+            /* Found the block */
+            break;
         }
+    }
 
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
+    return vidMemBlock;
+}
 
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                       "Node 0x%x is freed.",
-                       Node);
+static gceSTATUS
+_SplitVirtualChunk(
+    IN gckOS Os,
+    IN gcuVIDMEM_NODE_PTR Node,
+    IN gctSIZE_T Bytes
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gctPOINTER pointer;
+    gctINT i;
 
-        /* Success. */
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
+    if ((Bytes <= 0) || (Bytes > Node->VirtualChunk.bytes))
+    {
+        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
     }
 
-    /*************************** Virtual Memory *******************************/
+    /* Allocate a new gcuVIDMEM_NODE object. */
+    gcmkONERROR(gckOS_Allocate(Os,
+                               gcmSIZEOF(gcuVIDMEM_NODE),
+                               &pointer));
 
-    /* Get gckKERNEL object. */
-    kernel = Node->Virtual.kernel;
+    node = pointer;
 
-    /* Verify the gckKERNEL object pointer. */
-    gcmkVERIFY_OBJECT(kernel, gcvOBJ_KERNEL);
+    /* Intialize the new gcuVIDMEM_NODE. */
+    node->VirtualChunk.offset = Node->VirtualChunk.offset + Bytes;
+    node->VirtualChunk.bytes  = Node->VirtualChunk.bytes - Bytes;
+    node->VirtualChunk.parent = Node->VirtualChunk.parent;
+    node->VirtualChunk.kernel = Node->VirtualChunk.kernel;
+    node->VirtualChunk.kvaddr = gcvNULL;
 
-#if gcdENABLE_VG
-    if (Node->Virtual.kernelVirtual)
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
     {
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                "%s(%d) Unmap %x from kernel space.",
-                __FUNCTION__, __LINE__,
-                Node->Virtual.kernelVirtual);
-
-        gcmkVERIFY_OK(
-            gckOS_UnmapPhysical(kernel->os,
-                                Node->Virtual.kernelVirtual,
-                                Node->Virtual.bytes));
-
-        Node->Virtual.kernelVirtual = gcvNULL;
+        node->VirtualChunk.lockeds[i] = 0;
     }
-#endif
 
-    /* Free the virtual memory. */
-    gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os,
-                                        Node->Virtual.physical,
-                                        Node->Virtual.bytes));
+    /* Insert chunk behind specified chunk. */
+    node->VirtualChunk.next  = Node->VirtualChunk.next;
+    node->VirtualChunk.prev  = Node;
+    Node->VirtualChunk.next = node->VirtualChunk.next->VirtualChunk.prev = node;
 
-    /* Destroy the gcuVIDMEM_NODE union. */
-    gcmkVERIFY_OK(gckVIDMEM_DestroyVirtual(Node));
+    /* Insert free chunk behind specified chunk. */
+    node->VirtualChunk.nextFree  = Node->VirtualChunk.nextFree;
+    node->VirtualChunk.prevFree  = Node;
+    Node->VirtualChunk.nextFree = node->VirtualChunk.nextFree->VirtualChunk.prevFree = node;
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
+    /* Adjust size of specified chunk. */
+    Node->VirtualChunk.bytes = Bytes;
 
 OnError:
-    if (mutexAcquired)
-    {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(
-            memory->os, memory->mutex
-            ));
-    }
-
-    /* Return the status. */
-    gcmkFOOTER();
     return status;
 }
 
-/*map to kernel space*/
-gceSTATUS
-gckVIDMEM_NODE_LockCPU(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
-    OUT gctPOINTER * Logical
+static gceSTATUS
+_MergeVirtualChunk(
+    IN gckOS Os,
+    IN gcuVIDMEM_NODE_PTR Node
     )
 {
-    gceSTATUS status = gcvSTATUS_FALSE;
-    gckVIDMEM_NODE ObjNode = gcvNULL;
-    gcuVIDMEM_NODE_PTR node = gcvNULL;
-    gctPOINTER logical = gcvNULL;
-    gctBOOL acquired = gcvFALSE;
-    gckOS os = Kernel->os;
+    gcuVIDMEM_NODE_PTR node;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &ObjNode));
-    node = ObjNode->node;
-    gcmkONERROR(gckOS_AcquireMutex(os, ObjNode->mutex, gcvINFINITE));
-    acquired = gcvTRUE;
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM){
-        gcmkONERROR(
-                    gckOS_CreateKernelMapping(os,
-                                              node->VidMem.memory->physical,
-                                              node->VidMem.offset,
-                                              node->VidMem.bytes,
-                                              &logical));
-    }else{
-        gcmkONERROR(
-                    gckOS_CreateKernelMapping(os,
-                                              node->Virtual.physical,
-                                              0,
-                                              node->Virtual.bytes,
-                                              &logical));
-    }
-    *Logical = logical;
-    gcmkONERROR(gckVIDMEM_NODE_Dereference(Kernel, ObjNode));
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, ObjNode->mutex));
-    return gcvSTATUS_OK;
-OnError:
-    if (acquired)
+    node = Node->VirtualChunk.next;
+
+    if (Node->VirtualChunk.offset + Node->VirtualChunk.bytes != node->VirtualChunk.offset)
     {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, ObjNode->mutex));
+        /* Corrupted heap. */
+        gcmkASSERT(
+            Node->VirtualChunk.offset + Node->VirtualChunk.bytes == node->VirtualChunk.offset);
+
+        return gcvSTATUS_HEAP_CORRUPTED;
     }
 
-    /* Return the status. */
+    /* Merge. */
+    Node->VirtualChunk.bytes += node->VirtualChunk.bytes;
+
+    /* Unlink next node from linked list. */
+    Node->VirtualChunk.next     = node->VirtualChunk.next;
+    Node->VirtualChunk.nextFree = node->VirtualChunk.nextFree;
+
+    Node->VirtualChunk.next->VirtualChunk.prev         =
+    Node->VirtualChunk.nextFree->VirtualChunk.prevFree = Node;
+
+    /* Free the next node. */
+    status = gcmkOS_SAFE_FREE(Os, node);
     return status;
 }
 
-gceSTATUS
-gckVIDMEM_NODE_UnlockCPU(
+static gctBOOL
+_IsVidMemBlockFree(
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    return (VidMemBlock->freeBytes == VidMemBlock->bytes);
+}
+
+static gcuVIDMEM_NODE_PTR
+_FindVirtualChunkNode(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
-    OUT gctPOINTER Logical
+    IN gckVIDMEM_BLOCK VidMemBlock,
+    IN gctSIZE_T Bytes
     )
 {
-    gceSTATUS status = gcvSTATUS_FALSE;
-    gckVIDMEM_NODE ObjNode = gcvNULL;
-    gcuVIDMEM_NODE_PTR node = gcvNULL;
-    gctBOOL acquired = gcvFALSE;
-    gckOS os = Kernel->os;
+    gcuVIDMEM_NODE_PTR node;
 
-    gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &ObjNode));
-    node = ObjNode->node;
-    gcmkONERROR(gckOS_AcquireMutex(os, ObjNode->mutex, gcvINFINITE));
-    acquired = gcvTRUE;
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM){
-        gcmkONERROR(
-                    gckOS_DestroyKernelMapping(os,
-                                              node->VidMem.memory->physical,
-                                              Logical));
-    }else{
-        gcmkONERROR(
-                    gckOS_DestroyKernelMapping(os,
-                                              node->Virtual.physical,
-                                              Logical));
+    if (VidMemBlock->node.VirtualChunk.nextFree == gcvNULL)
+    {
+        /* No free chunk left. */
+        return gcvNULL;
     }
-    gcmkONERROR(gckVIDMEM_NODE_Dereference(Kernel, ObjNode));
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, ObjNode->mutex));
-    return gcvSTATUS_OK;
-OnError:
-    if (acquired)
+
+    for (node = VidMemBlock->node.VirtualChunk.nextFree;
+         node->VirtualChunk.bytes != 0;
+         node = node->VirtualChunk.nextFree)
     {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, ObjNode->mutex));
+        if (node->VirtualChunk.bytes >= Bytes)
+        {
+            /* Got it. */
+            return node;
+        }
     }
-    /* Return the status. */
-    return status;
-}
 
+    return gcvNULL;
+}
 
-#if !gcdPROCESS_ADDRESS_SPACE
 /*******************************************************************************
 **
-** _NeedVirtualMapping
+** _ConvertPhysical
 **
-**  Whether setup GPU page table for video node.
+**  Convert CPU physical to GPU address for video node.
 **
 **  INPUT:
 **      gckKERNEL Kernel
@@ -1389,547 +1257,552 @@ OnError:
 **      gcuVIDMEM_NODE_PTR Node
 **          Pointer to a gcuVIDMEM_NODE union.
 **
-**      gceCORE  Core
+**      gceCORE Core
 **          Id of current GPU.
 **
+**      gctPHYS_ADDR_T PhysicalAddress
+**          CPU physical address
+**
 **  OUTPUT:
-**      gctBOOL * NeedMapping
-**          A pointer hold the result whether Node should be mapping.
+**      gctUINT32 * Address
+**          A pointer hold the GPU address.
 */
 static gceSTATUS
-_NeedVirtualMapping(
+_ConvertPhysical(
     IN gckKERNEL Kernel,
-    IN gceCORE  Core,
+    IN gceCORE Core,
     IN gcuVIDMEM_NODE_PTR Node,
-    OUT gctBOOL * NeedMapping
-)
+    IN gckVIDMEM_BLOCK VidMemBlock,
+    IN gctPHYS_ADDR_T PhysicalAddress,
+    OUT gctUINT32 * Address
+    )
 {
     gceSTATUS status;
-    gctPHYS_ADDR_T phys;
-    gctUINT32 address;
-    gctUINT32 end;
-    gcePOOL pool;
-    gctUINT32 offset;
-    gctUINT32 bytes;
+    gctUINT64 physical = 0;
 
     gcmkHEADER_ARG("Node=0x%X", Node);
 
-    /* Verify the arguments. */
-    gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
-    gcmkVERIFY_ARGUMENT(NeedMapping != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Core < gcdMAX_GPU_COUNT);
+    if ((Node && !Node->Virtual.contiguous) ||
+        (VidMemBlock && !VidMemBlock->contiguous))
+    {
+        /* non-contiguous, mapping is required. */
+        status = gcvSTATUS_NOT_SUPPORTED;
+        goto OnError;
+    }
 
-    if (Node->Virtual.contiguous)
+    if ((Node && Node->Virtual.secure) ||
+        (VidMemBlock && VidMemBlock->secure))
     {
-#if gcdENABLE_VG
-        if (Core == gcvCORE_VG)
-        {
-            *NeedMapping = gcvFALSE;
-        }
-        else
-#endif
-        if (Node->Virtual.secure)
-        {
-            *NeedMapping = gcvTRUE;
-        }
-        else
-        {
-            /* Convert logical address into a physical address. */
-            gcmkONERROR(gckOS_UserLogicalToPhysical(
-                Kernel->os, Node->Virtual.logical, &phys
-                ));
+        /* Secure, mapping is forced. */
+        status = gcvSTATUS_NOT_SUPPORTED;
+        goto OnError;
+    }
 
-            if (phys > gcvMAXUINT32)
-            {
-                *NeedMapping = gcvTRUE;
-            }
-            else
-            {
-                gcmkSAFECASTPHYSADDRT(address, phys);
+    /* Convert to GPU physical address. */
+    gckOS_CPUPhysicalToGPUPhysical(Kernel->os, PhysicalAddress, &physical);
 
-                if (!gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_MMU))
-                {
-                    gcmkASSERT(address >= Kernel->hardware->baseAddress);
+#if gcdENABLE_VG
+    if (Core == gcvCORE_VG)
+    {
+        /* VG MMU can always support contiguous. */
+        *Address = (gctUINT32)physical;
+        gcmkFOOTER_ARG("*Address=0x%X", *Address);
+        return gcvSTATUS_OK;
+    }
+#endif
 
-                    /* Subtract baseAddress to get a GPU address used for programming. */
-                    address -= Kernel->hardware->baseAddress;
+    if ((physical > gcvMAXUINT32) ||
+        (Node && (physical + Node->Virtual.bytes - 1 > gcvMAXUINT32)) ||
+        (VidMemBlock && (physical + VidMemBlock->bytes - 1 > gcvMAXUINT32)))
+    {
+        /* Above 4G (32bit), mapping is required currently. */
+        status = gcvSTATUS_NOT_SUPPORTED;
+        goto OnError;
+    }
 
-                    /* If part of region is belong to gcvPOOL_VIRTUAL,
-                    ** whole region has to be mapped. */
-                    gcmkSAFECASTSIZET(bytes, Node->Virtual.bytes);
-                    end = address + bytes - 1;
+    if (!gckHARDWARE_IsFeatureAvailable(Kernel->hardware, gcvFEATURE_MMU))
+    {
+        if (physical < Kernel->hardware->baseAddress)
+        {
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
+        }
 
-                    gcmkONERROR(gckHARDWARE_SplitMemory(
-                                Kernel->hardware, end, &pool, &offset
-                                ));
+        /* Subtract baseAddress to get a GPU address used for programming. */
+        physical -= Kernel->hardware->baseAddress;
 
-                    *NeedMapping = (pool == gcvPOOL_VIRTUAL);
-                }
-                else
-                {
-                    gctBOOL flatMapped;
+        /* 2G upper is virtual space, better to move to gckHARDWARE section. */
+        if (physical + Node->Virtual.bytes > 0x80000000)
+        {
+            /* End is above 2G, ie virtual space. */
+            status = gcvSTATUS_NOT_SUPPORTED;
+            goto OnError;
+        }
 
-                    gcmkONERROR(gckMMU_IsFlatMapped(Kernel->mmu, address, &flatMapped));
+        *Address = (gctUINT32)physical;
 
-                    *NeedMapping = !flatMapped;
-                }
-            }
-        }
+        gcmkFOOTER_ARG("*Address=0x%X", *Address);
+        return gcvSTATUS_OK;
     }
     else
     {
-        *NeedMapping = gcvTRUE;
-    }
+        gctBOOL flatMapped;
 
-    gcmkFOOTER_ARG("*NeedMapping=%d", *NeedMapping);
-    return gcvSTATUS_OK;
+        gcmkONERROR(gckMMU_IsFlatMapped(Kernel->mmu, physical, gcvINVALID_ADDRESS, &flatMapped));
 
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-#endif
-
-#if gcdPROCESS_ADDRESS_SPACE
-gcsGPU_MAP_PTR
-_FindGPUMap(
-    IN gcsGPU_MAP_PTR Head,
-    IN gctINT ProcessID
-    )
-{
-    gcsGPU_MAP_PTR map = Head;
-
-    while (map)
-    {
-        if (map->pid == ProcessID)
+        if (!flatMapped)
         {
-            return map;
+            status = gcvSTATUS_NOT_SUPPORTED;
+            goto OnError;
         }
 
-        map = map->next;
+        *Address = (gctUINT32)physical;
+
+        gcmkFOOTER_ARG("*Address=0x%X", *Address);
+        return gcvSTATUS_OK;
     }
 
-    return gcvNULL;
+OnError:
+    gcmkFOOTER();
+    return status;
 }
 
-gcsGPU_MAP_PTR
-_CreateGPUMap(
-    IN gckOS Os,
-    IN gcsGPU_MAP_PTR *Head,
-    IN gcsGPU_MAP_PTR *Tail,
-    IN gctINT ProcessID
+static gceSTATUS
+gckVIDMEM_MapVidMemBlock(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock
     )
 {
-    gcsGPU_MAP_PTR gpuMap;
-    gctPOINTER pointer = gcvNULL;
+    gceSTATUS status;
+    gckOS os = Kernel->os;
+    gctPHYS_ADDR_T physAddr;
+    gceHARDWARE_TYPE hwType;
 
-    gckOS_Allocate(Os, sizeof(gcsGPU_MAP), &pointer);
+    gcmkHEADER_ARG("Kernel=%p VidMemBlock=%p", Kernel, VidMemBlock);
 
-    if (pointer == gcvNULL)
-    {
-        return gcvNULL;
-    }
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
 
-    gpuMap = pointer;
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+    gcmkASSERT(VidMemBlock->pageCount > 0);
 
-    gckOS_ZeroMemory(pointer, sizeof(gcsGPU_MAP));
+    gcmkONERROR(
+        gckOS_GetPhysicalFromHandle(os,
+                                    VidMemBlock->physical,
+                                    0,
+                                    &physAddr));
+
+    status = _ConvertPhysical(Kernel,
+                              Kernel->core,
+                              gcvNULL,
+                              VidMemBlock,
+                              physAddr,
+                              &VidMemBlock->addresses[hwType]);
+    if (gcmIS_ERROR(status))
+    {
+        /* Allocate pages inside the MMU. */
+        gcmkONERROR(
+            gckMMU_AllocatePagesEx(Kernel->mmu,
+                                   VidMemBlock->pageCount,
+                                   VidMemBlock->type,
+                                   gcvPAGE_TYPE_1M,
+                                   VidMemBlock->secure,
+                                   &VidMemBlock->pageTables[hwType],
+                                   &VidMemBlock->addresses[hwType]));
+
+        if (VidMemBlock->onFault != gcvTRUE)
+        {
+            /* Map the pages. */
+            gcmkONERROR(
+                gckOS_Map1MPages(os,
+                                 Kernel->core,
+                                 VidMemBlock->physical,
+                                 VidMemBlock->pageCount,
+                                 VidMemBlock->addresses[hwType],
+                                 VidMemBlock->pageTables[hwType],
+                                 gcvTRUE,
+                                 VidMemBlock->type));
+        }
 
-    gpuMap->pid = ProcessID;
+        gcmkONERROR(gckMMU_Flush(Kernel->mmu, VidMemBlock->type));
 
-    if (!*Head)
-    {
-        *Head = *Tail = gpuMap;
+        /* Calculate the GPU virtual address. */
+        VidMemBlock->addresses[hwType] |= (gctUINT32) (physAddr & ((1 << 20) - 1));
     }
-    else
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                   "Mapped video memory block 0x%x to 0x%08X",
+                   VidMemBlock,
+                   VidMemBlock->addresses[hwType]);
+
+    return gcvSTATUS_OK;
+
+OnError:
+    if (VidMemBlock->pageTables[hwType] != gcvNULL)
     {
-        gpuMap->prev = *Tail;
-        (*Tail)->next = gpuMap;
-        *Tail = gpuMap;
+        /* Free the pages from the MMU. */
+        gcmkVERIFY_OK(
+            gckMMU_FreePages(Kernel->mmu,
+                             VidMemBlock->secure,
+                             gcvPAGE_TYPE_1M,
+                             VidMemBlock->addresses[hwType],
+                             VidMemBlock->pageTables[hwType],
+                             VidMemBlock->pageCount));
+
+        VidMemBlock->pageTables[hwType] = gcvNULL;
     }
 
-    return gpuMap;
+    gcmkFOOTER();
+    return status;
 }
 
-void
-_DestroyGPUMap(
-    IN gckOS Os,
-    IN gcsGPU_MAP_PTR *Head,
-    IN gcsGPU_MAP_PTR *Tail,
-    IN gcsGPU_MAP_PTR gpuMap
+static gceSTATUS
+_UnmapVidMemBlock(
+    IN gckMMU Mmu,
+    IN gceHARDWARE_TYPE HwType,
+    IN gckVIDMEM_BLOCK VidMemBlock
     )
 {
+    gceSTATUS status;
 
-    if (gpuMap == *Head)
-    {
-        if ((*Head = gpuMap->next) == gcvNULL)
-        {
-            *Tail = gcvNULL;
-        }
-    }
-    else
+    gcmkHEADER_ARG("Mmu=%p VidMemBlock=%p", Mmu, VidMemBlock);
+
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+
+    if (VidMemBlock->pageTables[HwType] != gcvNULL)
     {
-        gpuMap->prev->next = gpuMap->next;
-        if (gpuMap == *Tail)
-        {
-            *Tail = gpuMap->prev;
-        }
-        else
-        {
-            gpuMap->next->prev = gpuMap->prev;
-        }
+        /* Free the pages from the MMU. */
+        gcmkONERROR(
+            gckMMU_FreePages(Mmu,
+                             VidMemBlock->secure,
+                             gcvPAGE_TYPE_1M,
+                             VidMemBlock->addresses[HwType],
+                             VidMemBlock->pageTables[HwType],
+                             VidMemBlock->pageCount));
+
+        VidMemBlock->pageTables[HwType] = gcvNULL;
     }
 
-    gcmkOS_SAFE_FREE(Os, gpuMap);
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
 }
-#endif
 
-/*******************************************************************************
-**
-**  gckVIDMEM_Lock
-**
-**  Lock a video memory node and return its hardware specific address.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gcuVIDMEM_NODE_PTR Node
-**          Pointer to a gcuVIDMEM_NODE union.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * Address
-**          Pointer to a variable that will hold the hardware specific address.
-**
-**      gctUINT32 * PhysicalAddress
-**          Pointer to a variable that will hold the bus address of a contiguous
-**          video node.
-*/
-gceSTATUS
-gckVIDMEM_Lock(
+static gceSTATUS
+gckVIDMEM_BLOCK_Construct(
     IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    IN gctBOOL Cacheable,
-    OUT gctUINT32 * Address,
-    OUT gctUINT32 * Gid,
-    OUT gctUINT64 * PhysicalAddress
+    IN gctSIZE_T BlockSize,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    OUT gckVIDMEM_BLOCK * VidMemBlock
     )
 {
     gceSTATUS status;
-    gctBOOL acquired = gcvFALSE;
-    gctBOOL locked = gcvFALSE;
-    gckOS os = gcvNULL;
-#if !gcdPROCESS_ADDRESS_SPACE
-    gctBOOL needMapping = gcvFALSE;
-#endif
-    gctUINT64 physicalAddress = ~0ULL;
-    gcuVIDMEM_NODE_PTR node = Node->node;
-    gctSIZE_T pageSize;
-    gctUINT32 pageMask;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckOS os = Kernel->os;
+    gctPOINTER pointer;
+    gctINT i;
 
-    gcmkHEADER_ARG("Node=0x%x", Node);
+    gcmkHEADER_ARG("Kernel=0x%x BlockSize=%lu Type=%x Flag=%x", Kernel, BlockSize, Type);
 
     /* Verify the arguments. */
-    gcmkVERIFY_ARGUMENT(Address != gcvNULL);
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+    gcmkVERIFY_ARGUMENT(BlockSize > 0);
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+
+    /* Allocate an gckVIDMEM_BLOCK object. */
+    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_BLOCK), &pointer));
+
+    vidMemBlock = pointer;
+
+    /* Initialize the gckVIDMEM_BLOCK object. */
+    vidMemBlock->object.type = gcvOBJ_VIDMEM_BLOCK;
+    vidMemBlock->os          = os;
+    vidMemBlock->bytes       = BlockSize;
+    vidMemBlock->freeBytes   = BlockSize;
+    /* 1M page count. */
+    vidMemBlock->pageCount   = (gctUINT32)(BlockSize >> 20);
+    vidMemBlock->type        = Type;
+    vidMemBlock->contiguous  = Flag & gcvALLOC_FLAG_CONTIGUOUS;
+    vidMemBlock->secure      = (Flag & gcvALLOC_FLAG_SECURITY) != 0;
+    vidMemBlock->onFault     = (Flag & gcvALLOC_FLAG_ALLOC_ON_FAULT) != 0;
+    vidMemBlock->mutex       = gcvNULL;
+    vidMemBlock->physical    = gcvNULL;
+
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
+    {
+        vidMemBlock->pageTables[i] = gcvNULL;
+    }
 
-    /* Extract the gckOS object pointer. */
-    os = Kernel->os;
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+    /* Allocate the mutex. */
+    gcmkONERROR(gckOS_CreateMutex(os, &vidMemBlock->mutex));
 
-    if ((node == gcvNULL)
-    ||  (node->VidMem.memory == gcvNULL)
-    )
+    /* Allocate one gcuVIDMEM_NODE union. */
+    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), &pointer));
+
+    node = pointer;
+
+    if (!vidMemBlock->contiguous)
     {
-        /* Invalid object. */
-        gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
+        Flag |= gcvALLOC_FLAG_1M_PAGES;
     }
 
-    /* Grab the mutex. */
-    gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE));
-    acquired = gcvTRUE;
+    /* Alloc 1M page size aligned memory block. */
+    gcmkONERROR(
+        gckOS_AllocatePagedMemory(os,
+                                  Flag,
+                                  &BlockSize,
+                                  &vidMemBlock->gid,
+                                  &vidMemBlock->physical));
 
-    /**************************** Video Memory ********************************/
+    /* Map current hardware mmu table with 1M pages for this video memory block. */
+    gcmkONERROR(gckVIDMEM_MapVidMemBlock(Kernel, vidMemBlock));
 
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+    /* Initialize gcuVIDMEM_NODE union for virtual memory. */
+    node->VirtualChunk.kernel     = Kernel;
+    node->VirtualChunk.offset     = 0;
+    node->VirtualChunk.bytes      = BlockSize;
+    node->VirtualChunk.kvaddr     = gcvNULL;
+    node->VirtualChunk.logical    = gcvNULL;
+    node->VirtualChunk.parent     = vidMemBlock;
+
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
     {
-        gctUINT32 offset;
+        node->VirtualChunk.lockeds[i] = 0;
+    }
 
-        if (Cacheable == gcvTRUE)
-        {
-            gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
-        }
+    /* Initialize the virtual chunk linked-list. */
+    node->VirtualChunk.next     =
+    node->VirtualChunk.prev     =
+    node->VirtualChunk.nextFree =
+    node->VirtualChunk.prevFree = &vidMemBlock->node;
 
-        /* Increment the lock count. */
-        node->VidMem.locked ++;
+    vidMemBlock->node.VirtualChunk.next =
+    vidMemBlock->node.VirtualChunk.prev =
+    vidMemBlock->node.VirtualChunk.nextFree =
+    vidMemBlock->node.VirtualChunk.prevFree = node;
 
-        gcmkSAFECASTSIZET(offset, node->VidMem.offset);
-        physicalAddress = node->VidMem.memory->baseAddress
-                        + offset
-                        + node->VidMem.alignment;
+    vidMemBlock->node.VirtualChunk.bytes = 0;
 
-        if (node->VidMem.pool == gcvPOOL_LOCAL_EXTERNAL)
-        {
-            *Address = Kernel->externalBaseAddress + offset;
-        }
-        else
+    *VidMemBlock = vidMemBlock;
+
+    gcmkFOOTER_ARG("*VidMemBlock=0x%x", *VidMemBlock);
+
+    return gcvSTATUS_OK;
+
+OnError:
+    if (vidMemBlock != gcvNULL)
+    {
+        if (vidMemBlock->physical)
         {
-            gcmkASSERT(node->VidMem.pool == gcvPOOL_SYSTEM);
-            *Address = Kernel->contiguousBaseAddress + offset;
+            gcmkVERIFY_OK(gckOS_FreePagedMemory(os,
+                                                vidMemBlock->physical,
+                                                vidMemBlock->bytes));
         }
-
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                      "Locked node 0x%x (%d) @ 0x%08X",
-                      node,
-                      node->VidMem.locked,
-                      *Address);
     }
 
-    /*************************** Virtual Memory *******************************/
-
-    else
+    if (node != gcvNULL)
     {
+        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+    }
 
-        *Gid = node->Virtual.gid;
+    gcmkFOOTER();
+    return status;
+}
 
-#if gcdPAGED_MEMORY_CACHEABLE
-        /* Force video memory cacheable. */
-        Cacheable = gcvTRUE;
-#endif
+static gceSTATUS
+gckVIDMEM_BLOCK_Destroy(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK VidMemBlock
+    )
+{
+    gckDEVICE device = Kernel->device;
+    gctINT i;
 
-        gcmkONERROR(
-            gckOS_LockPages(os,
-                            node->Virtual.physical,
-                            node->Virtual.bytes,
-                            Cacheable,
-                            &node->Virtual.logical,
-                            &node->Virtual.pageCount));
-
-        gcmkONERROR(gckOS_UserLogicalToPhysical(
-            os,
-            node->Virtual.logical,
-            &physicalAddress
-            ));
+    gcmkHEADER_ARG("Kernel=%p VidMemBlock=%p", Kernel, VidMemBlock);
 
-#if gcdENABLE_VG
-        node->Virtual.physicalAddress = physicalAddress;
-#endif
+    /* Verify the arguments. */
+    gcmkVERIFY_ARGUMENT(Kernel != gcvNULL);
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
 
-#if !gcdPROCESS_ADDRESS_SPACE
-        /* Increment the lock count. */
-        if (node->Virtual.lockeds[Kernel->core] ++ == 0)
+    if (VidMemBlock->physical)
+    {
+        gcmkVERIFY_OK(gckOS_FreePagedMemory(Kernel->os,
+                                            VidMemBlock->physical,
+                                            VidMemBlock->bytes));
+    }
+
+    for (i = 0; i < gcvHARDWARE_NUM_TYPES; i++)
+    {
+        if (VidMemBlock->pageTables[i])
         {
-            locked = gcvTRUE;
+            gcmkVERIFY_OK(_UnmapVidMemBlock(device->mmus[i], i, VidMemBlock));
+        }
+    }
 
-            gcmkONERROR(_NeedVirtualMapping(Kernel, Kernel->core, node, &needMapping));
+    /* Free the mutex. */
+    gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, VidMemBlock->mutex));
 
-            if (needMapping == gcvFALSE)
-            {
-                /* Get hardware specific address. */
-#if gcdENABLE_VG
-                if (Kernel->vg != gcvNULL)
-                {
-                    gcmkONERROR(gckVGHARDWARE_ConvertLogical(
-                                Kernel->vg->hardware,
-                                node->Virtual.logical,
-                                gcvTRUE,
-                                &node->Virtual.addresses[Kernel->core]));
-                }
-                else
-#endif
-                {
-                    gcmkONERROR(gckHARDWARE_ConvertLogical(
-                                Kernel->hardware,
-                                node->Virtual.logical,
-                                gcvTRUE,
-                                &node->Virtual.addresses[Kernel->core]));
-                }
-            }
-            else
-            {
-#if gcdSECURITY
-                gctPHYS_ADDR physicalArrayPhysical;
-                gctPOINTER physicalArrayLogical;
-
-                gcmkONERROR(gckOS_AllocatePageArray(
-                    os,
-                    node->Virtual.physical,
-                    node->Virtual.pageCount,
-                    &physicalArrayLogical,
-                    &physicalArrayPhysical
-                    ));
+    /* Free the virtual chunk. */
+    gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, VidMemBlock->node.VirtualChunk.next));
 
-                gcmkONERROR(gckKERNEL_SecurityMapMemory(
-                    Kernel,
-                    physicalArrayLogical,
-                    node->Virtual.pageCount,
-                    &node->Virtual.addresses[Kernel->core]
-                    ));
+    /* Free the video memory block. */
+    gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, VidMemBlock));
 
-                gcmkONERROR(gckOS_FreeNonPagedMemory(
-                    os,
-                    1,
-                    physicalArrayPhysical,
-                    physicalArrayLogical
-                    ));
-#else
-#if gcdENABLE_VG
-                if (Kernel->vg != gcvNULL)
-                {
-                    /* Allocate pages inside the MMU. */
-                    gcmkONERROR(
-                        gckVGMMU_AllocatePages(Kernel->vg->mmu,
-                                             node->Virtual.pageCount,
-                                             &node->Virtual.pageTables[Kernel->core],
-                                             &node->Virtual.addresses[Kernel->core]));
-                }
-                else
-#endif
-                {
-                    /* Allocate pages inside the MMU. */
-                    gcmkONERROR(
-                        gckMMU_AllocatePagesEx(Kernel->mmu,
-                                             node->Virtual.pageCount,
-                                             node->Virtual.type,
-                                             node->Virtual.secure,
-                                             &node->Virtual.pageTables[Kernel->core],
-                                             &node->Virtual.addresses[Kernel->core]));
-                }
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+}
 
-                if (node->Virtual.onFault != gcvTRUE)
-                {
-#if gcdENABLE_TRUST_APPLICATION
-#if gcdENABLE_VG
-                    if (Kernel->core != gcvCORE_VG && Kernel->hardware->options.secureMode == gcvSECURE_IN_TA)
-#else
-                    if (Kernel->hardware->options.secureMode == gcvSECURE_IN_TA)
-#endif
-                    {
-                        gcmkONERROR(gckKERNEL_MapInTrustApplicaiton(
-                            Kernel,
-                            node->Virtual.logical,
-                            node->Virtual.physical,
-                            node->Virtual.addresses[Kernel->core],
-                            node->Virtual.pageCount
-                            ));
-                    }
-                    else
-#endif
-                    {
-                        /* Map the pages. */
-                        gcmkONERROR(gckOS_MapPagesEx(os,
-                            Kernel->core,
-                            node->Virtual.physical,
-                            node->Virtual.pageCount,
-                            node->Virtual.addresses[Kernel->core],
-                            node->Virtual.pageTables[Kernel->core],
-                            gcvTRUE,
-                            node->Virtual.type));
-                    }
-                }
+static gceSTATUS
+_AllocateVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_BLOCK  VidMemBlock,
+    IN gceVIDMEM_TYPE Type,
+    INOUT gctSIZE_T *Bytes,
+    OUT gcuVIDMEM_NODE_PTR *Node
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    gctBOOL acquired = gcvFALSE;
+    gcuVIDMEM_NODE_PTR node;
+    gctSIZE_T bytes;
 
-#if gcdENABLE_VG
-                if (Kernel->core == gcvCORE_VG)
-                {
-                    gcmkONERROR(gckVGMMU_Flush(Kernel->vg->mmu));
-                }
-                else
-#endif
-                {
-                    gcmkONERROR(gckMMU_Flush(Kernel->mmu, node->Virtual.type));
-                }
-#endif
-            }
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                           "Mapped virtual node 0x%x to 0x%08X",
-                           node,
-                           node->Virtual.addresses[Kernel->core]);
-        }
+    gcmkHEADER_ARG("Kernel=%p VidMemBlock=%p Type=%x Bytes=%zx",
+        Kernel, VidMemBlock, Type, *Bytes);
+
+    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+    gcmkVERIFY_ARGUMENT(VidMemBlock != gcvNULL);
+    gcmkVERIFY_ARGUMENT(Bytes > 0);
+    gcmkVERIFY_ARGUMENT(Type < gcvVIDMEM_TYPE_COUNT);
 
-        /* Return hardware address. */
-        *Address = node->Virtual.addresses[Kernel->core];
+    gcmkONERROR(gckOS_AcquireMutex(Kernel->os, VidMemBlock->mutex, gcvINFINITE));
 
-        if (needMapping == gcvTRUE)
-        {
+    acquired = gcvTRUE;
 
-#if gcdENABLE_VG
-            if (Kernel->core == gcvCORE_VG)
-            {
-                gcmkVERIFY_OK(gckOS_GetPageSize(os, &pageSize));
-            }
-            else
-#endif
-            {
-                pageSize = Kernel->command->pageSize;
-            }
+    bytes = gcmALIGN(*Bytes, 4096);
 
-            pageMask = (gctUINT32)pageSize - 1;
+    if (bytes > VidMemBlock->freeBytes)
+    {
+        /* No enough memory. */
+        status = gcvSTATUS_OUT_OF_MEMORY;
+        goto OnError;
+    }
 
-            *Address += (gctUINT32)physicalAddress & pageMask;
+    node = _FindVirtualChunkNode(Kernel, VidMemBlock, bytes);
+    if (node == gcvNULL)
+    {
+        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+    }
 
-            /* Need mark invalid address for virtual memory */
-            if (node->Virtual.contiguous == gcvFALSE)
-            {
-                physicalAddress = gcvINVALID_ADDRESS;
-            }
-        }
-#endif
+    if (node->VirtualChunk.bytes > bytes)
+    {
+        /* Split the chunk. */
+        _SplitVirtualChunk(Kernel->os, node, bytes);
     }
 
-    /* Release the mutex. */
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+    /* Remove the chunk from the free list. */
+    node->VirtualChunk.prevFree->VirtualChunk.nextFree = node->VirtualChunk.nextFree;
+    node->VirtualChunk.nextFree->VirtualChunk.prevFree = node->VirtualChunk.prevFree;
+    node->VirtualChunk.nextFree = node->VirtualChunk.prevFree = gcvNULL;
 
-    *PhysicalAddress = (gctUINT64)physicalAddress;
+    /* Fill in the information. */
+    node->VirtualChunk.parent = VidMemBlock;
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Address=%08x", *Address);
-    return gcvSTATUS_OK;
+    VidMemBlock->freeBytes -= node->VirtualChunk.bytes;
+
+    *Bytes = bytes;
+    *Node  = node;
 
 OnError:
-    if (locked)
+    if (acquired)
     {
-        if (node->Virtual.pageTables[Kernel->core] != gcvNULL)
-        {
-#if gcdENABLE_VG
-            if (Kernel->vg != gcvNULL)
-            {
-                /* Free the pages from the MMU. */
-                gcmkVERIFY_OK(
-                    gckVGMMU_FreePages(Kernel->vg->mmu,
-                                     node->Virtual.pageTables[Kernel->core],
-                                     node->Virtual.pageCount));
-            }
-            else
-#endif
-            {
-                /* Free the pages from the MMU. */
-                gcmkVERIFY_OK(
-                    gckMMU_FreePages(Kernel->mmu,
-                                     node->Virtual.secure,
-                                     node->Virtual.addresses[Kernel->core],
-                                     node->Virtual.pageTables[Kernel->core],
-                                     node->Virtual.pageCount));
-            }
-            node->Virtual.pageTables[Kernel->core]  = gcvNULL;
-        }
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, VidMemBlock->mutex));
+    }
 
-        /* Unlock the pages. */
-        gcmkVERIFY_OK(
-            gckOS_UnlockPages(os,
-                              node->Virtual.physical,
-                              node->Virtual.bytes,
-                              node->Virtual.logical
-                              ));
+    return status;
+}
+
+static gceSTATUS
+gckVIDMEM_AllocateVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN gctSIZE_T Bytes,
+    OUT gcuVIDMEM_NODE_PTR * Node
+    )
+{
+    gckOS os;
+    gceSTATUS status;
+    gcuVIDMEM_NODE_PTR node;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
+    gctSIZE_T blockSize;
+    gctBOOL acquired = gcvFALSE;
 
-        node->Virtual.lockeds[Kernel->core]--;
+    gcmkHEADER_ARG("Kernel=0x%x Flag=%x Bytes=%lu", Kernel, Flag, Bytes);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+    gcmkVERIFY_ARGUMENT(Bytes > 0);
+    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
+
+    /* Extract the gckOS object pointer. */
+    os = Kernel->os;
+    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+    /* Acquire the vidMem block mutex */
+    gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Kernel->vidMemBlockMutex, gcvINFINITE));
+    acquired = gcvTRUE;
+
+    /* Find the free vidmem block. */
+    vidMemBlock = _FindFreeBlock(Kernel, Bytes);
+    if (!vidMemBlock)
+    {
+        /* Not found, construct new block. */
+        blockSize = gcmALIGN(Bytes, gcd1M_PAGE_SIZE);
+
+        gcmkONERROR(
+            gckVIDMEM_BLOCK_Construct(Kernel,
+                                      blockSize,
+                                      Type,
+                                      Flag,
+                                      &vidMemBlock));
+
+        gcmkONERROR(_AddToBlockList(Kernel, vidMemBlock));
     }
 
+    /* Allocate virtual chunk node in the found block. */
+    gcmkONERROR(
+        _AllocateVirtualChunk(Kernel,
+                              vidMemBlock,
+                              Type,
+                              &Bytes,
+                              &node));
+
+    /* Return pointer to the gcuVIDMEM_NODE union. */
+    *Node = node;
+
+    /* Release the vidMem block mutex. */
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidMemBlockMutex));
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                   "Created virtual node 0x%x for %u bytes @ 0x%x",
+                   node, Bytes, node->Virtual.physical);
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Node=0x%x", *Node);
+    return gcvSTATUS_OK;
+
+OnError:
     if (acquired)
     {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
+        /* Release the vidMem block mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->vidMemBlockMutex));
     }
 
     /* Return the status. */
@@ -1939,9 +1812,9 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckVIDMEM_Unlock
+**  gckVIDMEM_Free
 **
-**  Unlock a video memory node.
+**  Free an allocated video memory node.
 **
 **  INPUT:
 **
@@ -1949,513 +1822,940 @@ OnError:
 **          Pointer to an gckKERNEL object.
 **
 **      gcuVIDMEM_NODE_PTR Node
-**          Pointer to a locked gcuVIDMEM_NODE union.
-**
-**      gceSURF_TYPE Type
-**          Type of surface to unlock.
-**
-**      gctBOOL * Asynchroneous
-**          Pointer to a variable specifying whether the surface should be
-**          unlocked asynchroneously or not.
+**          Pointer to a gcuVIDMEM_NODE object.
 **
 **  OUTPUT:
 **
-**      gctBOOL * Asynchroneous
-**          Pointer to a variable receiving the number of bytes used in the
-**          command buffer specified by 'Commands'.  If gcvNULL, there is no
-**          command buffer.
+**      Nothing.
 */
-gceSTATUS
-gckVIDMEM_Unlock(
+static gceSTATUS
+gckVIDMEM_Free(
     IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    IN gceSURF_TYPE Type,
-    IN OUT gctBOOL * Asynchroneous
+    IN gcuVIDMEM_NODE_PTR Node
     )
 {
     gceSTATUS status;
-    gckOS os = gcvNULL;
-    gctBOOL acquired = gcvFALSE;
-    gcuVIDMEM_NODE_PTR node = Node->node;
-
-    gcmkHEADER_ARG("Node=0x%x Type=%d *Asynchroneous=%d",
-                   Node, Type, gcmOPT_VALUE(Asynchroneous));
-
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
+    gckKERNEL kernel = gcvNULL;
+    gckVIDMEM memory = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
+    gcuVIDMEM_NODE_PTR node;
+    gctBOOL mutexAcquired = gcvFALSE;
+    gctBOOL vbMutexAcquired = gcvFALSE;
+    gctBOOL vbListMutexAcquired = gcvFALSE;
 
-    /* Get the gckOS object pointer. */
-    os = Kernel->os;
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+    gcmkHEADER_ARG("Node=0x%x", Node);
 
     /* Verify the arguments. */
-    if ((node == gcvNULL)
-    ||  (node->VidMem.memory == gcvNULL)
+    if ((Node == gcvNULL)
+    ||  (Node->VidMem.parent == gcvNULL)
     )
     {
         /* Invalid object. */
         gcmkONERROR(gcvSTATUS_INVALID_OBJECT);
     }
 
-    /* Grab the mutex. */
-    gcmkONERROR(gckOS_AcquireMutex(os, Node->mutex, gcvINFINITE));
-    acquired = gcvTRUE;
+    vidMemBlock = Node->VirtualChunk.parent;
 
     /**************************** Video Memory ********************************/
 
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+    if (Node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
-        if (node->VidMem.locked <= 0)
-        {
-            /* The surface was not locked. */
-            status = gcvSTATUS_MEMORY_UNLOCKED;
-            goto OnError;
-        }
+        /* Extract pointer to gckVIDMEM object owning the node. */
+        memory = Node->VidMem.parent;
+
+        /* Acquire the mutex. */
+        gcmkONERROR(
+            gckOS_AcquireMutex(memory->os, memory->mutex, gcvINFINITE));
+
+        mutexAcquired = gcvTRUE;
 
-        if (Asynchroneous != gcvNULL)
+        if (Node->VidMem.kvaddr)
         {
-            /* Schedule an event to sync with GPU. */
-            *Asynchroneous = gcvTRUE;
+            gcmkONERROR(
+                gckOS_DestroyKernelMapping(Kernel->os,
+                                           Node->VidMem.parent->physical,
+                                           Node->VidMem.kvaddr));
+
+            Node->VidMem.kvaddr = gcvNULL;
         }
-        else
+
+#ifdef __QNXNTO__
+        /* Unmap the video memory. */
+        if (Node->VidMem.logical != gcvNULL)
         {
-            /* Decrement the lock count. */
-            node->VidMem.locked --;
+            gckKERNEL_UnmapVideoMemory(
+                Kernel,
+                Node->VidMem.logical,
+                Node->VidMem.processID,
+                Node->VidMem.bytes
+                );
+
+            Node->VidMem.logical = gcvNULL;
         }
 
-        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                      "Unlocked node 0x%x (%d)",
-                      node,
-                      node->VidMem.locked);
-    }
+        /* Reset. */
+        Node->VidMem.processID = 0;
 
-    /*************************** Virtual Memory *******************************/
+        /* Don't try to re-free an already freed node. */
+        if ((Node->VidMem.nextFree == gcvNULL)
+        &&  (Node->VidMem.prevFree == gcvNULL)
+        )
+#endif
+        {
+#if gcdENABLE_VG
+            if (Node->VidMem.kernelVirtual)
+            {
+                gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                        "%s(%d) Unmap %x from kernel space.",
+                        __FUNCTION__, __LINE__,
+                        Node->VidMem.kernelVirtual);
 
-    else
-    {
+                gcmkVERIFY_OK(
+                    gckOS_UnmapPhysical(memory->os,
+                                        Node->VidMem.kernelVirtual,
+                                        Node->VidMem.bytes));
 
+                Node->VidMem.kernelVirtual = gcvNULL;
+            }
+#endif
 
-        if (Asynchroneous == gcvNULL)
-        {
-#if !gcdPROCESS_ADDRESS_SPACE
-            if (node->Virtual.lockeds[Kernel->core] == 0)
+            /* Check if Node is already freed. */
+            if (Node->VidMem.nextFree)
             {
-                status = gcvSTATUS_MEMORY_UNLOCKED;
-                goto OnError;
+                /* Node is alread freed. */
+                gcmkONERROR(gcvSTATUS_INVALID_DATA);
             }
 
-            /* Decrement lock count. */
-            -- node->Virtual.lockeds[Kernel->core];
+            /* Update the number of free bytes. */
+            memory->freeBytes += Node->VidMem.bytes;
+
+            /* Find the next free node. */
+            for (node = Node->VidMem.next;
+                 node != gcvNULL && node->VidMem.nextFree == gcvNULL;
+                 node = node->VidMem.next) ;
+
+            /* Insert this node in the free list. */
+            Node->VidMem.nextFree = node;
+            Node->VidMem.prevFree = node->VidMem.prevFree;
+
+            Node->VidMem.prevFree->VidMem.nextFree =
+            node->VidMem.prevFree                  = Node;
 
-            /* See if we can unlock the resources. */
-            if (node->Virtual.lockeds[Kernel->core] == 0)
+            /* Is the next node a free node and not the sentinel? */
+            if ((Node->VidMem.next == Node->VidMem.nextFree)
+            &&  (Node->VidMem.next->VidMem.bytes != 0)
+            )
             {
-#if gcdSECURITY
-                if (node->Virtual.addresses[Kernel->core] > 0x80000000)
-                {
-                    gcmkONERROR(gckKERNEL_SecurityUnmapMemory(
-                        Kernel,
-                        node->Virtual.addresses[Kernel->core],
-                        node->Virtual.pageCount
-                        ));
-                }
-#else
-                /* Free the page table. */
-                if (node->Virtual.pageTables[Kernel->core] != gcvNULL)
-                {
-#if gcdENABLE_VG
-                    if (Kernel->vg != gcvNULL)
-                    {
-                        gcmkONERROR(
-                            gckVGMMU_FreePages(Kernel->vg->mmu,
-                                             node->Virtual.pageTables[Kernel->core],
-                                             node->Virtual.pageCount));
-                    }
-                    else
-#endif
-                    {
-                        gcmkONERROR(
-                            gckMMU_FreePages(Kernel->mmu,
-                                             node->Virtual.secure,
-                                             node->Virtual.addresses[Kernel->core],
-                                             node->Virtual.pageTables[Kernel->core],
-                                             node->Virtual.pageCount));
-                    }
-
-                    gcmkONERROR(gckOS_UnmapPages(
-                        Kernel->os,
-                        node->Virtual.pageCount,
-                        node->Virtual.addresses[Kernel->core]
-                        ));
+                /* Merge this node with the next node. */
+                gcmkONERROR(_Merge(memory->os, node = Node));
+                gcmkASSERT(node->VidMem.nextFree != node);
+                gcmkASSERT(node->VidMem.prevFree != node);
+            }
 
-                    /* Mark page table as freed. */
-                    node->Virtual.pageTables[Kernel->core] = gcvNULL;
-                }
-#endif
+            /* Is the previous node a free node and not the sentinel? */
+            if ((Node->VidMem.prev == Node->VidMem.prevFree)
+            &&  (Node->VidMem.prev->VidMem.bytes != 0)
+            )
+            {
+                /* Merge this node with the previous node. */
+                gcmkONERROR(_Merge(memory->os, node = Node->VidMem.prev));
+                gcmkASSERT(node->VidMem.nextFree != node);
+                gcmkASSERT(node->VidMem.prevFree != node);
             }
+        }
 
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                           "Unmapped virtual node 0x%x from 0x%08X",
-                           node, node->Virtual.addresses[Kernel->core]);
-#endif
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(memory->os, memory->mutex));
 
-        }
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                       "Node 0x%x is freed.",
+                       Node);
 
-        else
+        /* Success. */
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        gcmkONERROR(gckOS_AcquireMutex(vidMemBlock->os, vidMemBlock->mutex, gcvINFINITE));
+        vbMutexAcquired = gcvTRUE;
+        kernel = Node->VirtualChunk.kernel;
+
+        if (Node->VirtualChunk.kvaddr)
         {
             gcmkONERROR(
-                gckOS_UnlockPages(os,
-                              node->Virtual.physical,
-                              node->Virtual.bytes,
-                              node->Virtual.logical));
+                gckOS_DestroyKernelMapping(kernel->os,
+                                           vidMemBlock->physical,
+                                           Node->VirtualChunk.kvaddr));
 
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
-                           "Scheduled unlock for virtual node 0x%x",
-                           node);
-
-            /* Schedule the surface to be unlocked. */
-            *Asynchroneous = gcvTRUE;
+            Node->VirtualChunk.kvaddr = gcvNULL;
         }
-    }
 
-    /* Release the mutex. */
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
-    acquired = gcvFALSE;
+        /* Handle the free chunk in the linked-list */
+        {
+            /* Check if chunk is in free list. */
+            if (Node->VirtualChunk.nextFree)
+            {
+                /* Chunk is already freed. */
+                gcmkONERROR(gcvSTATUS_INVALID_DATA);
+            }
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
-    return gcvSTATUS_OK;
+            vidMemBlock->freeBytes += Node->VirtualChunk.bytes;
 
-OnError:
-    if (acquired)
-    {
-        /* Release the mutex. */
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mutex));
-    }
+            /* Find the next free chunk. */
+            for (node = Node->VirtualChunk.next;
+                 node != gcvNULL && node->VirtualChunk.nextFree == gcvNULL;
+                 node = node->VirtualChunk.next);
 
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
+            /* Insert this chunk in the free list. */
+            Node->VirtualChunk.nextFree = node;
+            Node->VirtualChunk.prevFree = node->VirtualChunk.prevFree;
 
-#if gcdPROCESS_ADDRESS_SPACE
-gceSTATUS
-gckVIDMEM_Node_Lock(
-    IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    OUT gctUINT32 *Address
-    )
-{
-    gceSTATUS           status;
-    gckOS               os;
-    gcuVIDMEM_NODE_PTR  node = Node->node;
-    gcsGPU_MAP_PTR      gpuMap;
-    gctPHYS_ADDR        physical = gcvNULL;
-    gctUINT32           phys = gcvINVALID_ADDRESS;
-    gctUINT32           processID;
-    gcsLOCK_INFO_PTR    lockInfo;
-    gctUINT32           pageCount;
-    gckMMU              mmu;
-    gctUINT32           i;
-    gctUINT32_PTR       pageTableEntry;
-    gctUINT32           offset = 0;
-    gctBOOL             acquired = gcvFALSE;
-
-    gcmkHEADER_ARG("Node = %x", Node);
+            Node->VirtualChunk.prevFree->VirtualChunk.nextFree =
+            node->VirtualChunk.prevFree = Node;
 
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+            /* Is the next chunk a free chunk. */
+            if ((Node->VirtualChunk.next == Node->VirtualChunk.nextFree)
+            &&  (Node->VirtualChunk.next->VirtualChunk.bytes != 0)
+            )
+            {
+                /* Merge this chunk with the next chunk. */
+                gcmkONERROR(_MergeVirtualChunk(vidMemBlock->os, node = Node));
+                gcmkASSERT(node->VirtualChunk.nextFree != node);
+                gcmkASSERT(node->VirtualChunk.prevFree != node);
+            }
 
-    os = Kernel->os;
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+            /* Is the previous chunk a free chunk. */
+            if ((Node->VirtualChunk.prev == Node->VirtualChunk.prevFree)
+            &&  (Node->VirtualChunk.prev->VirtualChunk.bytes != 0)
+            )
+            {
+                /* Merge this chunk with the previous chunk. */
+                gcmkONERROR(_MergeVirtualChunk(vidMemBlock->os, node = Node->VirtualChunk.prev));
+                gcmkASSERT(node->VirtualChunk.nextFree != node);
+                gcmkASSERT(node->VirtualChunk.prevFree != node);
+            }
+        }
 
-    gcmkONERROR(gckOS_GetProcessID(&processID));
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(vidMemBlock->os, vidMemBlock->mutex));
 
-    gcmkONERROR(gckKERNEL_GetProcessMMU(Kernel, &mmu));
+        /* Acquire the vidMem block mutex */
+        gcmkONERROR(gckOS_AcquireMutex(vidMemBlock->os, kernel->vidMemBlockMutex, gcvINFINITE));
+        vbListMutexAcquired = gcvTRUE;
 
-    gcmkONERROR(gckOS_AcquireMutex(os, Node->mapMutex, gcvINFINITE));
-    acquired = gcvTRUE;
+        /* Only free the vidmem block when all the chunks are freed. */
+        if (_IsVidMemBlockFree(vidMemBlock))
+        {
+            gcmkONERROR(_RemoveFromBlockList(kernel, vidMemBlock));
 
-    /* Get map information for current process. */
-    gpuMap = _FindGPUMap(Node->mapHead, processID);
+            gcmkONERROR(gckVIDMEM_BLOCK_Destroy(kernel, vidMemBlock));
+        }
 
-    if (gpuMap == gcvNULL)
-    {
-        gpuMap = _CreateGPUMap(os, &Node->mapHead, &Node->mapTail, processID);
+        /* Release the vidMem block mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(vidMemBlock->os, kernel->vidMemBlockMutex));
 
-        if (gpuMap == gcvNULL)
-        {
-            gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
-        }
+        /* Success. */
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
     }
 
-    lockInfo = &gpuMap->lockInfo;
-
-    if (lockInfo->lockeds[Kernel->core] ++ == 0)
-    {
-        /* Get necessary information. */
-        if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
-        {
-            phys = node->VidMem.memory->baseAddress
-                 + node->VidMem.offset
-                 + node->VidMem.alignment;
-
-            /* GPU page table use 4K page. */
-            pageCount = ((phys + node->VidMem.bytes + 4096 - 1) >> 12)
-                      - (phys >> 12);
-
-            offset = phys & 0xFFF;
-        }
-        else
-        {
-            pageCount = node->Virtual.pageCount;
-            physical = node->Virtual.physical;
-        }
+    /*************************** Virtual Memory *******************************/
 
-        /* Allocate pages inside the MMU. */
-        gcmkONERROR(gckMMU_AllocatePages(
-            mmu,
-            pageCount,
-            &lockInfo->pageTables[Kernel->core],
-            &lockInfo->GPUAddresses[Kernel->core]));
+    /* Get gckKERNEL object. */
+    kernel = Node->Virtual.kernel;
 
-        /* Record MMU from which pages are allocated.  */
-        lockInfo->lockMmus[Kernel->core] = mmu;
+    /* Verify the gckKERNEL object pointer. */
+    gcmkVERIFY_OBJECT(kernel, gcvOBJ_KERNEL);
 
-        pageTableEntry = lockInfo->pageTables[Kernel->core];
+#if gcdENABLE_VG
+    if (Node->Virtual.kernelVirtual)
+    {
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                "%s(%d) Unmap %x from kernel space.",
+                __FUNCTION__, __LINE__,
+                Node->Virtual.kernelVirtual);
 
-        /* Fill page table entries. */
-        if (phys != gcvINVALID_ADDRESS)
-        {
-            gctUINT32 address = lockInfo->GPUAddresses[Kernel->core];
-            for (i = 0; i < pageCount; i++)
-            {
-                gckMMU_GetPageEntry(mmu, address, &pageTableEntry);
-                gckMMU_SetPage(mmu, phys & 0xFFFFF000, pageTableEntry);
-                phys += 4096;
-                address += 4096;
-                pageTableEntry += 1;
-            }
-        }
-        else
-        {
-            gctUINT32 address = lockInfo->GPUAddresses[Kernel->core];
-            gcmkASSERT(physical != gcvNULL);
-            gcmkONERROR(gckOS_MapPagesEx(os,
-                Kernel->core,
-                physical,
-                pageCount,
-                address,
-                pageTableEntry));
-        }
+        gcmkVERIFY_OK(
+            gckOS_UnmapPhysical(kernel->os,
+                                Node->Virtual.kernelVirtual,
+                                Node->Virtual.bytes));
 
-        gcmkONERROR(gckMMU_Flush(mmu, Node->type));
+        Node->Virtual.kernelVirtual = gcvNULL;
     }
+#endif
 
-    *Address = lockInfo->GPUAddresses[Kernel->core] + offset;
+    if (Node->Virtual.kvaddr)
+    {
+        gcmkVERIFY_OK(
+            gckOS_DestroyKernelMapping(kernel->os,
+                                       Node->Virtual.physical,
+                                       Node->Virtual.kvaddr));
+    }
 
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mapMutex));
-    acquired = gcvFALSE;
+    /* Free the virtual memory. */
+    gcmkVERIFY_OK(gckOS_FreePagedMemory(kernel->os,
+                                        Node->Virtual.physical,
+                                        Node->Virtual.bytes));
 
+    /* Delete the gcuVIDMEM_NODE union. */
+    gcmkVERIFY_OK(gcmkOS_SAFE_FREE(kernel->os, Node));
 
+    /* Success. */
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if (acquired)
-    {
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, Node->mapMutex));
-    }
-
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckVIDMEM_NODE_Unlock(
-    IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    IN gctUINT32 ProcessID
-    )
-{
-    gceSTATUS           status;
-    gcsGPU_MAP_PTR      gpuMap;
-    gcsLOCK_INFO_PTR    lockInfo;
-    gckMMU              mmu;
-    gcuVIDMEM_NODE_PTR  node;
-    gctUINT32           pageCount;
-    gctBOOL             acquired = gcvFALSE;
-
-    gcmkHEADER_ARG("Kernel=0x%08X, Node = %x, ProcessID=%d",
-                   Kernel, Node, ProcessID);
-
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-    gcmkVERIFY_ARGUMENT(Node != gcvNULL);
-
-    gcmkONERROR(gckOS_AcquireMutex(Kernel->os, Node->mapMutex, gcvINFINITE));
-    acquired = gcvTRUE;
-
-    /* Get map information for current process. */
-    gpuMap = _FindGPUMap(Node->mapHead, ProcessID);
-
-    if (gpuMap == gcvNULL)
+    if (mutexAcquired)
     {
-        /* No mapping for this process. */
-        gcmkONERROR(gcvSTATUS_INVALID_DATA);
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(
+            memory->os, memory->mutex
+            ));
     }
 
-    lockInfo = &gpuMap->lockInfo;
-
-    if (--lockInfo->lockeds[Kernel->core] == 0)
+    if (vbMutexAcquired)
     {
-        node = Node->node;
-
-        /* Get necessary information. */
-        if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
-        {
-            gctUINT32 phys = node->VidMem.memory->baseAddress
-                           + node->VidMem.offset
-                           + node->VidMem.alignment;
-
-            /* GPU page table use 4K page. */
-            pageCount = ((phys + node->VidMem.bytes + 4096 - 1) >> 12)
-                      - (phys >> 12);
-        }
-        else
-        {
-            pageCount = node->Virtual.pageCount;
-        }
-
-        /* Get MMU which allocates pages. */
-        mmu = lockInfo->lockMmus[Kernel->core];
-
-        /* Free virtual spaces in page table. */
-        gcmkVERIFY_OK(gckMMU_FreePagesEx(
-            mmu,
-            lockInfo->GPUAddresses[Kernel->core],
-            pageCount
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(
+            vidMemBlock->os, vidMemBlock->mutex
             ));
-
-        _DestroyGPUMap(Kernel->os, &Node->mapHead, &Node->mapTail, gpuMap);
     }
 
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Node->mapMutex));
-    acquired = gcvFALSE;
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    if (acquired)
+    if (vbListMutexAcquired)
     {
-        gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Node->mapMutex));
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(
+            vidMemBlock->os, Kernel->vidMemBlockMutex));
     }
 
+    /* Return the status. */
     gcmkFOOTER();
     return status;
 }
-#endif
 
 /*******************************************************************************
 **
-**  gckVIDMEM_HANDLE_Allocate
+**  gckVIDMEM_Lock
 **
-**  Allocate a handle for a gckVIDMEM_NODE object.
+**  Lock a video memory node and return its hardware specific address.
 **
 **  INPUT:
 **
 **      gckKERNEL Kernel
 **          Pointer to an gckKERNEL object.
 **
-**      gckVIDMEM_NODE Node
-**          Pointer to a gckVIDMEM_NODE object.
+**      gcuVIDMEM_NODE_PTR Node
+**          Pointer to a gcuVIDMEM_NODE union.
 **
 **  OUTPUT:
 **
-**      gctUINT32 * Handle
-**          Pointer to a variable receiving a handle represent this
-**          gckVIDMEM_NODE in userspace.
+**      gctUINT32 * Address
+**          Pointer to a variable that will hold the hardware specific address.
+**
+**      gctUINT32 * PhysicalAddress
+**          Pointer to a variable that will hold the bus address of a contiguous
+**          video node.
 */
-gceSTATUS
-gckVIDMEM_HANDLE_Allocate(
+static gceSTATUS
+gckVIDMEM_Lock(
     IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    OUT gctUINT32 * Handle
+    IN gcuVIDMEM_NODE_PTR Node,
+    OUT gctUINT32 * Address
     )
 {
-    gceSTATUS status;
-    gctUINT32 processID           = 0;
-    gctPOINTER pointer            = gcvNULL;
-    gctPOINTER handleDatabase     = gcvNULL;
-    gctPOINTER mutex              = gcvNULL;
-    gctUINT32 handle              = 0;
-    gckVIDMEM_HANDLE handleObject = gcvNULL;
-    gckOS os                      = Kernel->os;
+    gckOS os;
 
-    gcmkHEADER_ARG("Kernel=0x%X, Node=0x%X", Kernel, Node);
+    gcmkHEADER_ARG("Kernel=%p Node=%p", Kernel, Node);
 
-    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+    /* Extract the gckOS object pointer. */
+    os = Kernel->os;
 
-    /* Allocate a gckVIDMEM_HANDLE object. */
-    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_HANDLE), &pointer));
+    /* Increment the lock count. */
+    if (Node->VidMem.locked++ == 0)
+    {
+        gctUINT32 address;
+        gctUINT32 offset = (gctUINT32)Node->VidMem.offset;
 
-    gcmkVERIFY_OK(gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsVIDMEM_HANDLE)));
+        switch (Node->VidMem.pool)
+        {
+        case gcvPOOL_LOCAL_EXTERNAL:
+            address = Kernel->externalBaseAddress + offset;
+            break;
+        case gcvPOOL_LOCAL_INTERNAL:
+            address = Kernel->internalBaseAddress + offset;
+            break;
+        case gcvPOOL_SRAM:
+            address = Kernel->sRAMBaseAddress[Kernel->sRAMIndex] + offset;
+            break;
+        default:
+            gcmkASSERT(Node->VidMem.pool == gcvPOOL_SYSTEM);
+        case gcvPOOL_SYSTEM:
+            address = Kernel->contiguousBaseAddress + offset;
+            break;
+        }
 
-    handleObject = pointer;
+        /* Save address. */
+        Node->VidMem.address = address;
+    }
 
-    gcmkONERROR(gckOS_AtomConstruct(os, &handleObject->reference));
+    *Address = Node->VidMem.address;
 
-    /* Set default reference count to 1. */
-    gckOS_AtomSet(os, handleObject->reference, 1);
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                  "Locked node 0x%x (%d) @ 0x%08X",
+                  Node,
+                  Node->VidMem.locked,
+                  *Address);
 
-    gcmkVERIFY_OK(gckOS_GetProcessID(&processID));
+    gcmkFOOTER_ARG("*Address=0x%08X", *Address);
+    return gcvSTATUS_OK;
+}
 
-    gcmkONERROR(
-        gckKERNEL_FindHandleDatbase(Kernel,
-                                    processID,
-                                    &handleDatabase,
-                                    &mutex));
+static gceSTATUS
+gckVIDMEM_LockVirtual(
+    IN gckKERNEL Kernel,
+    IN gcuVIDMEM_NODE_PTR Node,
+    OUT gctUINT32 * Address
+    )
+{
+    gceSTATUS status;
+    gctPHYS_ADDR_T physicalAddress;
+    gctBOOL locked = gcvFALSE;
+    gckOS os = Kernel->os;
+    gceHARDWARE_TYPE hwType;
+
+    gcmkHEADER_ARG("Kernel=%p Node=%p", Kernel, Node);
+
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
 
-    /* Allocate a handle for this object. */
     gcmkONERROR(
-        gckKERNEL_AllocateIntegerId(handleDatabase, handleObject, &handle));
+        gckOS_GetPhysicalFromHandle(os,
+                                    Node->Virtual.physical,
+                                    0,
+                                    &physicalAddress));
 
-    handleObject->node = Node;
-    handleObject->handle = handle;
+    /* Expect 4096 aligned. */
+    gcmkASSERT((physicalAddress & 0xFFF) == 0);
 
-    *Handle = handle;
+#if gcdENABLE_VG
+    Node->Virtual.physicalAddress = physicalAddress;
+#endif
 
-    gcmkFOOTER_ARG("*Handle=%d", *Handle);
+    /* Increment the lock count. */
+    if (Node->Virtual.lockeds[hwType]++ == 0)
+    {
+        locked = gcvTRUE;
+
+        status = _ConvertPhysical(
+            Kernel,
+            Kernel->core,
+            Node,
+            gcvNULL,
+            physicalAddress,
+            &Node->Virtual.addresses[hwType]
+            );
+
+        if (gcmIS_ERROR(status))
+        {
+            /* Do GPU address mapping. */
+#if gcdSECURITY
+            gctPHYS_ADDR physicalArrayPhysical;
+            gctPOINTER physicalArrayLogical;
+
+            gcmkONERROR(gckOS_AllocatePageArray(
+                os,
+                Node->Virtual.physical,
+                Node->Virtual.pageCount,
+                &physicalArrayLogical,
+                &physicalArrayPhysical
+                ));
+
+            gcmkONERROR(gckKERNEL_SecurityMapMemory(
+                Kernel,
+                physicalArrayLogical,
+                Node->Virtual.pageCount,
+                &Node->Virtual.addresses[hwType]
+                ));
+
+            gcmkONERROR(gckOS_FreeNonPagedMemory(
+                os,
+                physicalArrayPhysical,
+                physicalArrayLogical,
+                1
+                ));
+#else
+#if gcdENABLE_VG
+            if (Kernel->vg != gcvNULL)
+            {
+                /* Allocate pages inside the MMU. */
+                gcmkONERROR(
+                    gckVGMMU_AllocatePages(Kernel->vg->mmu,
+                                           Node->Virtual.pageCount,
+                                           &Node->Virtual.pageTables[hwType],
+                                           &Node->Virtual.addresses[hwType]));
+            }
+            else
+#endif
+            {
+                /* Allocate pages inside the MMU. */
+                gcmkONERROR(
+                    gckMMU_AllocatePagesEx(Kernel->mmu,
+                                           Node->Virtual.pageCount,
+                                           Node->Virtual.type,
+                                           gcvPAGE_TYPE_4K,
+                                           Node->Virtual.secure,
+                                           &Node->Virtual.pageTables[hwType],
+                                           &Node->Virtual.addresses[hwType]));
+            }
+
+            if (Node->Virtual.onFault != gcvTRUE)
+            {
+#if gcdENABLE_TRUST_APPLICATION
+#if gcdENABLE_VG
+                if (Kernel->core != gcvCORE_VG && Kernel->hardware->options.secureMode == gcvSECURE_IN_TA)
+#else
+                if (Kernel->hardware->options.secureMode == gcvSECURE_IN_TA)
+#endif
+                {
+                    gcmkONERROR(gckKERNEL_MapInTrustApplicaiton(
+                        Kernel,
+                        Node->Virtual.logical,
+                        Node->Virtual.physical,
+                        Node->Virtual.addresses[hwType],
+                        Node->Virtual.pageCount
+                        ));
+                }
+                else
+#endif
+                {
+                    gcmkDUMP(os, "#[mmu: dynamic mapping: address=0x%08X pageCount=%lu]",
+                             Node->Virtual.addresses[hwType],
+                             (unsigned long)Node->Virtual.pageCount);
+
+                    /* Map the pages. */
+                    gcmkONERROR(gckOS_MapPagesEx(os,
+                        Kernel->core,
+                        Node->Virtual.physical,
+                        Node->Virtual.pageCount,
+                        Node->Virtual.addresses[hwType],
+                        Node->Virtual.pageTables[hwType],
+                        gcvTRUE,
+                        Node->Virtual.type));
+                }
+            }
+
+#if gcdENABLE_VG
+            if (Kernel->core == gcvCORE_VG)
+            {
+                gcmkONERROR(gckVGMMU_Flush(Kernel->vg->mmu));
+            }
+            else
+#endif
+            {
+                gcmkONERROR(gckMMU_Flush(Kernel->mmu, Node->Virtual.type));
+            }
+#endif
+
+            /* GPU MMU page size is fixed at 4096 now. */
+            Node->Virtual.addresses[hwType] |= (gctUINT32)physicalAddress & (4096 - 1);
+        }
+
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                       "Mapped virtual node 0x%x to 0x%08X",
+                       Node,
+                       Node->Virtual.addresses[hwType]);
+    }
+
+    /* Return hardware address. */
+    *Address = Node->Virtual.addresses[hwType];
+
+    gcmkFOOTER_ARG("*Address=0x%08X", *Address);
     return gcvSTATUS_OK;
 
 OnError:
-    if (handleObject != gcvNULL)
+    if (locked)
     {
-        if (handleObject->reference != gcvNULL)
+        if (Node->Virtual.pageTables[hwType] != gcvNULL)
         {
-            gcmkVERIFY_OK(gckOS_AtomDestroy(os, handleObject->reference));
+#if gcdENABLE_VG
+            if (Kernel->vg != gcvNULL)
+            {
+                /* Free the pages from the MMU. */
+                gcmkVERIFY_OK(
+                    gckVGMMU_FreePages(Kernel->vg->mmu,
+                                     Node->Virtual.pageTables[hwType],
+                                     Node->Virtual.pageCount));
+            }
+            else
+#endif
+            {
+                /* Free the pages from the MMU. */
+                gcmkVERIFY_OK(
+                    gckMMU_FreePages(Kernel->mmu,
+                                     Node->Virtual.secure,
+                                     gcvPAGE_TYPE_4K,
+                                     Node->Virtual.addresses[hwType],
+                                     Node->Virtual.pageTables[hwType],
+                                     Node->Virtual.pageCount));
+            }
+
+            Node->Virtual.pageTables[hwType] = gcvNULL;
         }
 
-        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, handleObject));
+        Node->Virtual.lockeds[hwType]--;
     }
 
     gcmkFOOTER();
     return status;
 }
 
-gceSTATUS
-gckVIDMEM_NODE_Reference(
+static gceSTATUS
+gckVIDMEM_LockVirtualChunk(
     IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node
+    IN gcuVIDMEM_NODE_PTR Node,
+    OUT gctUINT32 * Address
     )
 {
-    gctINT32 oldValue;
-    gcmkHEADER_ARG("Kernel=0x%X Node=0x%X", Kernel, Node);
+    gceSTATUS status = gcvSTATUS_OK;
+    gckVIDMEM_BLOCK vidMemBlock = Node->VirtualChunk.parent;
+    gceHARDWARE_TYPE hwType;
 
-    gckOS_AtomIncrement(Kernel->os, Node->reference, &oldValue);
+    gcmkHEADER_ARG("Kernel=%p Node=%p", Kernel, Node);
 
-    gcmkFOOTER_NO();
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
+
+    gcmkASSERT(vidMemBlock != gcvNULL);
+
+    /* Increment the lock count. */
+    if (Node->VirtualChunk.lockeds[hwType]++ == 0)
+    {
+        if (!vidMemBlock->pageTables[hwType])
+        {
+            /* Map current hardware mmu table with 1M pages for this video memory block. */
+            gcmkONERROR(gckVIDMEM_MapVidMemBlock(Kernel, vidMemBlock));
+        }
+
+        Node->VirtualChunk.addresses[hwType] = vidMemBlock->addresses[hwType]
+                                             + (gctUINT32)Node->VirtualChunk.offset;
+    }
+
+    /* Return hardware address. */
+    *Address = Node->VirtualChunk.addresses[hwType];
+
+    gcmkFOOTER_ARG("*Address=0x%08X", *Address);
+
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+/*******************************************************************************
+**
+**  gckVIDMEM_Unlock
+**
+**  Unlock a video memory node.
+**
+**  INPUT:
+**
+**      gckKERNEL Kernel
+**          Pointer to an gckKERNEL object.
+**
+**      gcuVIDMEM_NODE_PTR Node
+**          Pointer to a locked gcuVIDMEM_NODE union.
+**
+**      gctBOOL * Asynchroneous
+**          Pointer to a variable specifying whether the surface should be
+**          unlocked asynchroneously or not.
+**
+**  OUTPUT:
+**
+**      gctBOOL * Asynchroneous
+**          Pointer to a variable receiving the number of bytes used in the
+**          command buffer specified by 'Commands'.  If gcvNULL, there is no
+**          command buffer.
+*/
+static gceSTATUS
+gckVIDMEM_Unlock(
+    IN gckKERNEL Kernel,
+    IN gcuVIDMEM_NODE_PTR Node,
+    IN OUT gctBOOL * Asynchroneous
+    )
+{
+    gceSTATUS status;
+
+    gcmkHEADER_ARG("Node=0x%x *Asynchroneous=%d",
+                   Node, gcmOPT_VALUE(Asynchroneous));
+
+    if (Node->VidMem.locked <= 0)
+    {
+        /* The surface was not locked. */
+        gcmkONERROR(gcvSTATUS_MEMORY_UNLOCKED);
+    }
+
+    if (Asynchroneous != gcvNULL)
+    {
+        /* Schedule an event to sync with GPU. */
+        *Asynchroneous = gcvTRUE;
+    }
+    else
+    {
+        /* Decrement the lock count. */
+        Node->VidMem.locked--;
+    }
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                  "Unlocked node %p (%d)",
+                  Node,
+                  Node->VidMem.locked);
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+gckVIDMEM_UnlockVirtual(
+    IN gckKERNEL Kernel,
+    IN gcuVIDMEM_NODE_PTR Node,
+    IN OUT gctBOOL * Asynchroneous
+    )
+{
+    gceSTATUS status;
+    gceHARDWARE_TYPE hwType;
+
+    gcmkHEADER_ARG("Node=0x%x *Asynchroneous=%d",
+                   Node, gcmOPT_VALUE(Asynchroneous));
+
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
+
+    if (Asynchroneous != gcvNULL)
+    {
+        /* Schedule the surface to be unlocked. */
+        *Asynchroneous = gcvTRUE;
+    }
+    else
+    {
+        if (Node->Virtual.lockeds[hwType] == 0)
+        {
+            gcmkONERROR(gcvSTATUS_MEMORY_UNLOCKED);
+        }
+
+        /* Decrement lock count. */
+        --Node->Virtual.lockeds[hwType];
+
+        /* See if we can unlock the resources. */
+        if (Node->Virtual.lockeds[hwType] == 0)
+        {
+            gctUINT32 address;
+
+            /* Adjust address to page aligned for underlying functions. */
+            address = Node->Virtual.addresses[hwType] & ~(4096 - 1);
+
+#if gcdSECURITY
+            if (Node->Virtual.addresses[hwType] > 0x80000000)
+            {
+                gcmkONERROR(gckKERNEL_SecurityUnmapMemory(
+                    Kernel,
+                    address,
+                    Node->Virtual.pageCount
+                    ));
+            }
+#else
+            /* Free the page table. */
+            if (Node->Virtual.pageTables[hwType] != gcvNULL)
+            {
+#if gcdENABLE_VG
+                if (Kernel->vg != gcvNULL)
+                {
+                    gcmkONERROR(
+                        gckVGMMU_FreePages(Kernel->vg->mmu,
+                                         Node->Virtual.pageTables[hwType],
+                                         Node->Virtual.pageCount));
+                }
+                else
+#endif
+                {
+                    gcmkONERROR(
+                        gckMMU_FreePages(Kernel->mmu,
+                                         Node->Virtual.secure,
+                                         gcvPAGE_TYPE_4K,
+                                         address,
+                                         Node->Virtual.pageTables[hwType],
+                                         Node->Virtual.pageCount));
+                }
+
+                gcmkONERROR(gckOS_UnmapPages(
+                    Kernel->os,
+                    Node->Virtual.pageCount,
+                    address
+                    ));
+
+                /* Mark page table as freed. */
+                Node->Virtual.pageTables[hwType] = gcvNULL;
+            }
+#endif
+        }
+
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                       "Unmapped virtual node %p from 0x%08X",
+                       Node, Node->Virtual.addresses[hwType]);
+    }
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+static gceSTATUS
+gckVIDMEM_UnlockVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gcuVIDMEM_NODE_PTR Node,
+    IN OUT gctBOOL * Asynchroneous
+    )
+{
+    gceSTATUS status;
+    gceHARDWARE_TYPE hwType;
+
+    gcmkHEADER_ARG("Node=0x%x *Asynchroneous=%d",
+                   Node, gcmOPT_VALUE(Asynchroneous));
+
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
+
+    if (Asynchroneous != gcvNULL)
+    {
+        /* Schedule an event to sync with GPU. */
+        *Asynchroneous = gcvTRUE;
+    }
+    else
+    {
+        if (Node->VirtualChunk.lockeds[hwType] == 0)
+        {
+            /* The surface was not locked. */
+            gcmkONERROR(gcvSTATUS_MEMORY_UNLOCKED);
+        }
+
+        /* Unmap and free pages when video memory free. */
+
+        /* Decrement the lock count. */
+        --Node->VirtualChunk.lockeds[hwType];
+    }
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_VIDMEM,
+                  "Unlocked node %p (%d)",
+                  Node,
+                  Node->VirtualChunk.lockeds[hwType]);
+
+    /* Success. */
+    gcmkFOOTER_ARG("*Asynchroneous=%d", gcmOPT_VALUE(Asynchroneous));
+    return gcvSTATUS_OK;
+
+OnError:
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+/*******************************************************************************
+**
+**  gckVIDMEM_HANDLE_Allocate
+**
+**  Allocate a handle for a gckVIDMEM_NODE object.
+**
+**  INPUT:
+**
+**      gckKERNEL Kernel
+**          Pointer to an gckKERNEL object.
+**
+**      gckVIDMEM_NODE Node
+**          Pointer to a gckVIDMEM_NODE object.
+**
+**  OUTPUT:
+**
+**      gctUINT32 * Handle
+**          Pointer to a variable receiving a handle represent this
+**          gckVIDMEM_NODE in userspace.
+*/
+gceSTATUS
+gckVIDMEM_HANDLE_Allocate(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE Node,
+    OUT gctUINT32 * Handle
+    )
+{
+    gceSTATUS status;
+    gctUINT32 processID           = 0;
+    gctPOINTER pointer            = gcvNULL;
+    gctPOINTER handleDatabase     = gcvNULL;
+    gctPOINTER mutex              = gcvNULL;
+    gctUINT32 handle              = 0;
+    gckVIDMEM_HANDLE handleObject = gcvNULL;
+    gckOS os                      = Kernel->os;
+
+    gcmkHEADER_ARG("Kernel=0x%X, Node=0x%X", Kernel, Node);
+
+    gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+
+    /* Allocate a gckVIDMEM_HANDLE object. */
+    gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_HANDLE), &pointer));
+
+    gcmkVERIFY_OK(gckOS_ZeroMemory(pointer, gcmSIZEOF(gcsVIDMEM_HANDLE)));
+
+    handleObject = pointer;
+
+    gcmkONERROR(gckOS_AtomConstruct(os, &handleObject->reference));
+
+    /* Set default reference count to 1. */
+    gckOS_AtomSet(os, handleObject->reference, 1);
+
+    gcmkVERIFY_OK(gckOS_GetProcessID(&processID));
+
+    gcmkONERROR(
+        gckKERNEL_FindHandleDatbase(Kernel,
+                                    processID,
+                                    &handleDatabase,
+                                    &mutex));
+
+    /* Allocate a handle for this object. */
+    gcmkONERROR(
+        gckKERNEL_AllocateIntegerId(handleDatabase, handleObject, &handle));
+
+    handleObject->node = Node;
+    handleObject->handle = handle;
+
+    *Handle = handle;
+
+    gcmkFOOTER_ARG("*Handle=%d", *Handle);
     return gcvSTATUS_OK;
+
+OnError:
+    if (handleObject != gcvNULL)
+    {
+        if (handleObject->reference != gcvNULL)
+        {
+            gcmkVERIFY_OK(gckOS_AtomDestroy(os, handleObject->reference));
+        }
+
+        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, handleObject));
+    }
+
+    gcmkFOOTER();
+    return status;
 }
 
 gceSTATUS
@@ -2563,8 +2863,9 @@ OnError:
 }
 
 gceSTATUS
-gckVIDMEM_HANDLE_LookupAndReference(
+gckVIDMEM_HANDLE_Lookup(
     IN gckKERNEL Kernel,
+    IN gctUINT32 ProcessID,
     IN gctUINT32 Handle,
     OUT gckVIDMEM_NODE * Node
     )
@@ -2574,33 +2875,25 @@ gckVIDMEM_HANDLE_LookupAndReference(
     gckVIDMEM_NODE node           = gcvNULL;
     gctPOINTER database           = gcvNULL;
     gctPOINTER mutex              = gcvNULL;
-    gctUINT32 processID           = 0;
     gctBOOL acquired              = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
-
-    gckOS_GetProcessID(&processID);
+    gcmkHEADER_ARG("Kernel=0x%X ProcessID=%d Handle=%d",
+                   Kernel, ProcessID, Handle);
 
     gcmkONERROR(
-        gckKERNEL_FindHandleDatbase(Kernel, processID, &database, &mutex));
+        gckKERNEL_FindHandleDatbase(Kernel, ProcessID, &database, &mutex));
 
     gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
     acquired = gcvTRUE;
 
-    /* Translate handle to gckVIDMEM_HANDLE object. */
     gcmkONERROR(
         gckKERNEL_QueryIntegerId(database, Handle, (gctPOINTER *)&handleObject));
 
-    /* Get gckVIDMEM_NODE object. */
     node = handleObject->node;
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
     acquired = gcvFALSE;
 
-    /* Reference this gckVIDMEM_NODE object. */
-    gcmkVERIFY_OK(gckVIDMEM_NODE_Reference(Kernel, node));
-
-    /* Return result. */
     *Node = node;
 
     gcmkFOOTER_ARG("*Node=%d", *Node);
@@ -2617,9 +2910,9 @@ OnError:
 }
 
 gceSTATUS
-gckVIDMEM_HANDLE_Lookup(
+gckVIDMEM_HANDLE_Lookup2(
     IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
+    IN gcsDATABASE_PTR Database,
     IN gctUINT32 Handle,
     OUT gckVIDMEM_NODE * Node
     )
@@ -2631,11 +2924,11 @@ gckVIDMEM_HANDLE_Lookup(
     gctPOINTER mutex              = gcvNULL;
     gctBOOL acquired              = gcvFALSE;
 
-    gcmkHEADER_ARG("Kernel=0x%X ProcessID=%d Handle=%d",
-                   Kernel, ProcessID, Handle);
+    gcmkHEADER_ARG("Kernel=0x%X Database=%p Handle=%d",
+                   Kernel, Database, Handle);
 
-    gcmkONERROR(
-        gckKERNEL_FindHandleDatbase(Kernel, ProcessID, &database, &mutex));
+    database = Database->handleDatabase;
+    mutex = Database->handleDatabaseMutex;
 
     gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
     acquired = gcvTRUE;
@@ -2663,44 +2956,22 @@ OnError:
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckVIDMEM_NODE_Allocate
-**
-**  Allocate a gckVIDMEM_NODE object.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gcuVIDMEM_NODE_PTR Node
-**          Pointer to a gcuVIDMEM_NODE union.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * Handle
-**          Pointer to a variable receiving a handle represent this
-**          gckVIDMEM_NODE in userspace.
-*/
-gceSTATUS
-gckVIDMEM_NODE_Allocate(
+
+static gceSTATUS
+gckVIDMEM_NODE_Construct(
     IN gckKERNEL Kernel,
     IN gcuVIDMEM_NODE_PTR VideoNode,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     IN gcePOOL Pool,
-    IN gctUINT32 * Handle
+    OUT gckVIDMEM_NODE * NodeObject
     )
 {
     gceSTATUS status;
     gckVIDMEM_NODE node = gcvNULL;
     gctPOINTER pointer  = gcvNULL;
-    gctUINT32 handle    = 0;
-    gckOS os            = Kernel->os;
+    gckOS os = Kernel->os;
     gctUINT i;
 
-    gcmkHEADER_ARG("Kernel=0x%X VideoNode=0x%X", Kernel, VideoNode);
-
     /* Construct a node. */
     gcmkONERROR(gckOS_Allocate(os, gcmSIZEOF(gcsVIDMEM_NODE), &pointer));
 
@@ -2719,10 +2990,6 @@ gckVIDMEM_NODE_Allocate(
     node->type = Type;
     node->pool = Pool;
 
-#if gcdPROCESS_ADDRESS_SPACE
-    gcmkONERROR(gckOS_CreateMutex(os, &node->mapMutex));
-#endif
-
     gcmkONERROR(gckOS_AtomConstruct(os, &node->reference));
 
     gcmkONERROR(gckOS_CreateMutex(os, &node->mutex));
@@ -2735,103 +3002,914 @@ gckVIDMEM_NODE_Allocate(
     /* Reference is 1 by default . */
     gckOS_AtomSet(os, node->reference, 1);
 
-    /* Create a handle to represent this node. */
-    gcmkONERROR(gckVIDMEM_HANDLE_Allocate(Kernel, node, &handle));
+    gcmkVERIFY_OK(
+        gckOS_AcquireMutex(Kernel->os,
+                           Kernel->db->videoMemListMutex,
+                           gcvINFINITE));
+
+    /* Add into video memory node list. */
+    gcsLIST_Add(&node->link, &Kernel->db->videoMemList);
+
+    gcmkVERIFY_OK(
+        gckOS_ReleaseMutex(Kernel->os, Kernel->db->videoMemListMutex));
+
+    *NodeObject = node;
+
+    return gcvSTATUS_OK;
+
+OnError:
+    if (node != gcvNULL)
+    {
+        if (node->mutex)
+        {
+            gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mutex));
+        }
+
+        if (node->reference != gcvNULL)
+        {
+            gcmkVERIFY_OK(gckOS_AtomDestroy(os, node->reference));
+        }
+
+        for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+        {
+            if (node->sync[i].signal != gcvNULL)
+            {
+                gcmkVERIFY_OK(gckOS_DestroySignal(os, node->sync[i].signal));
+            }
+        }
+
+        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+    }
+
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_AllocateLinear(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM VideoMemory,
+    IN gcePOOL Pool,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Alignment,
+    IN gctBOOL Specified,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gckVIDMEM_NODE * NodeObject
+    )
+{
+    gceSTATUS status;
+    gctSIZE_T bytes = *Bytes;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+
+    gcmkHEADER_ARG("Kernel=%p VideoMemory=%p Pool=%d Alignment=%d Type=%d *Bytes=%u",
+                   Kernel, VideoMemory, Pool, Alignment, Type, bytes);
+
+    gcmkONERROR(
+        gckVIDMEM_AllocateLinear(Kernel,
+                                 VideoMemory,
+                                 bytes,
+                                 Alignment,
+                                 Type,
+                                 Specified,
+                                 &node));
+
+    /* Update pool. */
+    node->VidMem.pool = Pool;
+    bytes = node->VidMem.bytes;
+
+    /* Construct a node. */
+    gcmkONERROR(
+        gckVIDMEM_NODE_Construct(Kernel, node, Type, Pool, &nodeObject));
+
+    *Bytes = bytes;
+    *NodeObject = nodeObject;
+
+    gcmkFOOTER_ARG("*Bytes=%u *NodeObject=%p", bytes, nodeObject);
+    return gcvSTATUS_OK;
+
+OnError:
+    if (node)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, node));
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_AllocateVirtual(
+    IN gckKERNEL Kernel,
+    IN gcePOOL Pool,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gckVIDMEM_NODE * NodeObject
+    )
+{
+    gceSTATUS status;
+    gctSIZE_T bytes = *Bytes;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+
+    gcmkHEADER_ARG("Kernel=%p Pool=%d Type=%d Flag=%x *Bytes=%u",
+                   Kernel, Pool, Type, Flag, bytes);
+
+    gcmkONERROR(
+        gckVIDMEM_AllocateVirtual(Kernel, Flag, bytes, &node));
+
+    /* Update type. */
+    node->Virtual.type = Type;
+    bytes = node->Virtual.bytes;
+
+    /* Construct a node. */
+    gcmkONERROR(
+        gckVIDMEM_NODE_Construct(Kernel, node, Type, Pool, &nodeObject));
+
+    *Bytes = bytes;
+    *NodeObject = nodeObject;
+
+    gcmkFOOTER_ARG("*Bytes=%u *NodeObject=%p", bytes, nodeObject);
+    return gcvSTATUS_OK;
+
+OnError:
+    if (node)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, node));
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_AllocateVirtualChunk(
+    IN gckKERNEL Kernel,
+    IN gcePOOL Pool,
+    IN gceVIDMEM_TYPE Type,
+    IN gctUINT32 Flag,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gckVIDMEM_NODE * NodeObject
+    )
+{
+    gceSTATUS status;
+    gctSIZE_T bytes = *Bytes;
+    gcuVIDMEM_NODE_PTR node = gcvNULL;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
+
+    gcmkHEADER_ARG("Kernel=%p Pool=%d Type=%d Flag=%x *Bytes=%u",
+                   Kernel, Pool, Type, Flag, bytes);
+
+    gcmkONERROR(
+        gckVIDMEM_AllocateVirtualChunk(Kernel, Type, Flag, bytes, &node));
+
+    bytes = node->VirtualChunk.bytes;
+
+    /* Construct a node. */
+    gcmkONERROR(
+        gckVIDMEM_NODE_Construct(Kernel, node, Type, Pool, &nodeObject));
+
+    *Bytes = bytes;
+    *NodeObject = nodeObject;
+
+    gcmkFOOTER_ARG("*Bytes=%u *NodeObject=%p", bytes, nodeObject);
+    return gcvSTATUS_OK;
+
+OnError:
+    if (node)
+    {
+        gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, node));
+    }
+
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Reference(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject
+    )
+{
+    gctINT32 oldValue;
+    gcmkHEADER_ARG("Kernel=0x%X NodeObject=0x%X", Kernel, NodeObject);
+
+    gcmkVERIFY_ARGUMENT(NodeObject != gcvNULL);
+
+    gckOS_AtomIncrement(Kernel->os, NodeObject->reference, &oldValue);
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Dereference(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject
+    )
+{
+    gctINT32 oldValue   = 0;
+    gctPOINTER database = Kernel->db->nameDatabase;
+    gctPOINTER mutex    = Kernel->db->nameDatabaseMutex;
+    gctUINT i;
+
+    gcmkHEADER_ARG("Kernel=0x%X NodeObject=0x%X", Kernel, NodeObject);
+    gcmkVERIFY_ARGUMENT(NodeObject != gcvNULL);
+
+    gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+
+    gcmkVERIFY_OK(gckOS_AtomDecrement(Kernel->os, NodeObject->reference, &oldValue));
+
+    if (oldValue == 1 && NodeObject->name)
+    {
+        /* Free name if exists. */
+        gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, NodeObject->name));
+    }
+
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
+
+    if (oldValue == 1)
+    {
+        gcmkVERIFY_OK(
+            gckOS_AcquireMutex(Kernel->os,
+                               Kernel->db->videoMemListMutex,
+                               gcvINFINITE));
+
+        /* Remove from video memory node list. */
+        gcsLIST_Del(&NodeObject->link);
+
+        gcmkVERIFY_OK(
+            gckOS_ReleaseMutex(Kernel->os, Kernel->db->videoMemListMutex));
+
+        /* Free gcuVIDMEM_NODE. */
+        gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, NodeObject->node));
+
+        gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, NodeObject->reference));
+
+        gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, NodeObject->mutex));
+
+        for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+        {
+            if (NodeObject->sync[i].signal != gcvNULL)
+            {
+                gcmkVERIFY_OK(gckOS_DestroySignal(Kernel->os, NodeObject->sync[i].signal));
+            }
+        }
+
+        /* Should not cause recursive call since tsNode->tsNode should be NULL */
+        if (NodeObject->tsNode)
+        {
+            gcmkASSERT(!NodeObject->tsNode->tsNode);
+            gckVIDMEM_NODE_Dereference(Kernel, NodeObject->tsNode);
+        }
+
+        gcmkOS_SAFE_FREE(Kernel->os, NodeObject);
+    }
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_GetReference(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctINT32 * ReferenceCount
+    )
+{
+    gctINT32 value;
+
+    gckOS_AtomGet(Kernel->os, NodeObject->reference, &value);
+
+    *ReferenceCount = value;
+    return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Lock(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctUINT32 * Address
+    )
+{
+    gceSTATUS status;
+    gckOS os = Kernel->os;
+    gctBOOL acquired = gcvFALSE;
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+
+    gcmkHEADER_ARG("NodeObject=%p", NodeObject);
+
+    /* Grab the mutex. */
+    gcmkONERROR(gckOS_AcquireMutex(os, NodeObject->mutex, gcvINFINITE));
+    acquired = gcvTRUE;
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        gcmkONERROR(gckVIDMEM_Lock(Kernel, node, Address));
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        gcmkONERROR(gckVIDMEM_LockVirtualChunk(Kernel, node, Address));
+    }
+    else
+    {
+        gcmkONERROR(gckVIDMEM_LockVirtual(Kernel, node, Address));
+    }
+
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, NodeObject->mutex));
+
+    gcmkFOOTER_ARG("*Address=0x%08X", *Address);
+    return gcvSTATUS_OK;
+
+OnError:
+    if (acquired)
+    {
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, NodeObject->mutex));
+    }
+
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_Unlock(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctUINT32 ProcessID,
+    IN OUT gctBOOL * Asynchroneous
+    )
+{
+    gceSTATUS status;
+    gckOS os = Kernel->os;
+    gctBOOL acquired = gcvFALSE;
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+
+    gcmkHEADER_ARG("NodeObject=%p Asynchroneous=%p", NodeObject, Asynchroneous);
+
+    /* Grab the mutex. */
+    gcmkONERROR(gckOS_AcquireMutex(os, NodeObject->mutex, gcvINFINITE));
+    acquired = gcvTRUE;
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        gcmkONERROR(gckVIDMEM_Unlock(Kernel, node, Asynchroneous));
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        gcmkONERROR(gckVIDMEM_UnlockVirtualChunk(Kernel, node, Asynchroneous));
+    }
+    else
+    {
+        gcmkONERROR(gckVIDMEM_UnlockVirtual(Kernel, node, Asynchroneous));
+    }
+
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, NodeObject->mutex));
+
+    gcmkFOOTER_ARG("*Asynchroneous=0x%08X", gcmOPT_VALUE(Asynchroneous));
+    return gcvSTATUS_OK;
+
+OnError:
+    if (acquired)
+    {
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, NodeObject->mutex));
+    }
+
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_CleanCache(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctSIZE_T Offset,
+    IN gctPOINTER Logical,
+    IN gctSIZE_T Bytes
+    )
+{
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gctPHYS_ADDR physHandle = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+    gceSTATUS status;
+
+    gcmkHEADER_ARG("Kernel=%p NodeObject=%d Offset=0x%llx Logical=%p Bytes=0x%llx",
+                   Kernel, NodeObject, Offset, Logical, Bytes);
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        gcmkONERROR(gckOS_MemoryBarrier(Kernel->os, Logical));
+
+        /* Reserved pool can't be cacheable */
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physHandle = vidMemBlock->physical;
+    }
+    else
+    {
+        physHandle = node->Virtual.physical;
+    }
+
+    gcmkONERROR(gckOS_CacheFlush(
+        Kernel->os,
+        0,
+        physHandle,
+        Offset,
+        Logical,
+        Bytes
+        ));
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_InvalidateCache(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctSIZE_T Offset,
+    IN gctPOINTER Logical,
+    IN gctSIZE_T Bytes
+    )
+{
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gctPHYS_ADDR physHandle = gcvNULL;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+    gceSTATUS status;
+
+    gcmkHEADER_ARG("Kernel=%p NodeObject=%d Offset=0x%llx Logical=%p Bytes=0x%llx",
+                   Kernel, NodeObject, Offset, Logical, Bytes);
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        /* Reserved pool can't be cacheable */
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physHandle = vidMemBlock->physical;
+    }
+    else
+    {
+        physHandle = node->Virtual.physical;
+    }
+
+    gcmkONERROR(gckOS_CacheInvalidate(
+        Kernel->os,
+        0,
+        physHandle,
+        Offset,
+        Logical,
+        Bytes
+        ));
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_GetLockCount(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctINT32 * LockCount
+    )
+{
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+    gctINT32 lockCount = 0;
+    gctINT i = 0;
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        lockCount = node->VidMem.locked;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        for (; i < gcvHARDWARE_NUM_TYPES; i++)
+        {
+            lockCount += node->VirtualChunk.lockeds[i];
+        }
+    }
+    else
+    {
+
+        for (; i < gcvHARDWARE_NUM_TYPES; i++)
+        {
+            lockCount += node->Virtual.lockeds[i];
+        }
+    }
+
+    *LockCount = lockCount;
+
+    return gcvSTATUS_OK;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_LockCPU(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctBOOL Cacheable,
+    IN gctBOOL FromUser,
+    OUT gctPOINTER * Logical
+    )
+{
+    gceSTATUS status;
+    gckOS os = Kernel->os;
+    gctBOOL acquired = gcvFALSE;
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+    gctPOINTER logical = gcvNULL;
+
+    gcmkHEADER_ARG("NodeObject=%p", NodeObject);
+
+    /* Grab the mutex. */
+    gcmkONERROR(gckOS_AcquireMutex(os, NodeObject->mutex, gcvINFINITE));
+    acquired = gcvTRUE;
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        if (Cacheable == gcvTRUE)
+        {
+            gcmkONERROR(gcvSTATUS_INVALID_REQUEST);
+        }
+
+        if (FromUser)
+        {
+            /* Map video memory pool to user space. */
+#ifdef __QNXNTO__
+            if (node->VidMem.logical == gcvNULL)
+            {
+                gcmkONERROR(
+                    gckKERNEL_MapVideoMemory(Kernel,
+                                             gcvTRUE,
+                                             node->VidMem.pool,
+                                             (gctUINT32)node->VidMem.offset,
+                                             (gctUINT32)node->VidMem.bytes,
+                                             &node->VidMem.logical));
+            }
+
+            logical = node->VidMem.logical;
+#else
+            gcmkONERROR(
+                gckKERNEL_MapVideoMemory(Kernel,
+                                         gcvTRUE,
+                                         node->VidMem.pool,
+                                         (gctUINT32)node->VidMem.offset,
+                                         (gctUINT32)node->VidMem.bytes,
+                                         &logical));
+#endif
+        }
+        else
+        {
+            /* Map video memory pool to kernel space. */
+            if (!node->VidMem.kvaddr)
+            {
+                gcmkONERROR(
+                    gckOS_CreateKernelMapping(os,
+                                              node->VidMem.parent->physical,
+                                              node->VidMem.offset,
+                                              node->VidMem.bytes,
+                                              &node->VidMem.kvaddr));
+            }
+
+            logical = node->VidMem.kvaddr;
+        }
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        if (FromUser)
+        {
+            /* Lock the entire vidmem block. */
+            gcmkONERROR(
+                gckOS_LockPages(os,
+                                vidMemBlock->physical,
+                                vidMemBlock->bytes,
+                                Cacheable,
+                                &logical));
+
+            /* Get the logical with offset in block. */
+            logical = (uint8_t *)logical + node->VirtualChunk.offset;
+            node->VirtualChunk.logical = logical;
+        }
+        else
+        {
+            /* Map once and will cancel map when free. */
+            if (!node->VirtualChunk.kvaddr)
+            {
+                gcmkONERROR(
+                    gckOS_CreateKernelMapping(os,
+                                              vidMemBlock->physical,
+                                              node->VirtualChunk.offset,
+                                              node->VirtualChunk.bytes,
+                                              &logical));
+            }
+
+            node->VirtualChunk.kvaddr = logical;
+        }
+    }
+    else
+    {
+        if (FromUser)
+        {
+            gcmkONERROR(
+                gckOS_LockPages(os,
+                                node->Virtual.physical,
+                                node->Virtual.bytes,
+                                Cacheable,
+                                &logical));
+
+            node->Virtual.logical = logical;
+        }
+        else
+        {
+            /* Map once and will cancel map when free. */
+            if (!node->Virtual.kvaddr)
+            {
+                gcmkONERROR(
+                    gckOS_CreateKernelMapping(os,
+                                              node->Virtual.physical,
+                                              0,
+                                              node->Virtual.bytes,
+                                              &node->Virtual.kvaddr));
+            }
+
+            logical = node->Virtual.kvaddr;
+        }
+    }
+
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, NodeObject->mutex));
+
+    *Logical = logical;
+
+    gcmkFOOTER_ARG("*Logical=%p", logical);
+    return gcvSTATUS_OK;
+
+OnError:
+    if (acquired)
+    {
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, NodeObject->mutex));
+    }
+
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_UnlockCPU(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctUINT32 ProcessID,
+    IN gctBOOL FromUser
+    )
+{
+    gceSTATUS status;
+    gckOS os = Kernel->os;
+    gctBOOL acquired = gcvFALSE;
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+
+    gcmkHEADER_ARG("NodeObject=%p", NodeObject);
+
+    /* Grab the mutex. */
+    gcmkONERROR(gckOS_AcquireMutex(os, NodeObject->mutex, gcvINFINITE));
+    acquired = gcvTRUE;
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        if (FromUser)
+        {
+            /* Do nothing here. */
+        }
+        else
+        {
+            /*
+             * Kernel side may lock for CPU access for multiple times. Since
+             * we don't have lock counts currently, we don't cancel CPU
+             * mapping here, and will cancel at 'free' instead.
+             */
+            /*
+            gcmkONERROR(
+                gckOS_DestroyKernelMapping(os,
+                                           node->VidMem.parent->physical,
+                                           node->VidMem.kvaddr));
+
+            node->VidMem.kvaddr = gcvNULL;
+             */
+        }
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        if (FromUser)
+        {
+            gcmkONERROR(
+                gckOS_UnlockPages(os,
+                                  vidMemBlock->physical,
+                                  vidMemBlock->bytes,
+                                  node->VirtualChunk.logical));
+        }
+        else
+        {
+            /* Nothing to do. */
+        }
+    }
+    else
+    {
+        if (FromUser)
+        {
+            gcmkONERROR(
+                gckOS_UnlockPages(os,
+                                  node->Virtual.physical,
+                                  node->Virtual.bytes,
+                                  node->Virtual.logical));
+        }
+        else
+        {
+            /*
+             * Kernel side may lock for CPU access for multiple times. Since
+             * we don't have lock counts currently, we don't cancel CPU
+             * mapping here, and will cancel at 'free' instead.
+             */
+            /*
+            gcmkONERROR(
+                gckOS_DestroyKernelMapping(os,
+                                           node->Virtual.physical,
+                                           node->Virtual.kvaddr));
+
+            node->Virtual.kvaddr = gcvNULL;
+             */
+        }
+    }
 
-    *Handle = handle;
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(os, NodeObject->mutex));
 
-    gcmkFOOTER_ARG("*Handle=%d", *Handle);
+    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 
 OnError:
-    if (node != gcvNULL)
+    if (acquired)
     {
-#if gcdPROCESS_ADDRESS_SPACE
-        if (node->mapMutex != gcvNULL)
-        {
-            gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mapMutex));
-        }
-#endif
+        /* Release the mutex. */
+        gcmkVERIFY_OK(gckOS_ReleaseMutex(os, NodeObject->mutex));
+    }
 
-        if (node->mutex)
+    /* Return the status. */
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckVIDMEM_NODE_GetPhysical(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    IN gctUINT32 Offset,
+    OUT gctPHYS_ADDR_T * PhysicalAddress
+    )
+{
+    gceSTATUS status;
+    gckOS os = Kernel->os;
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
+
+    gcmkHEADER_ARG("NodeObject=%p", NodeObject);
+
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        if (Offset >= node->VidMem.bytes)
         {
-            gcmkVERIFY_OK(gckOS_DeleteMutex(os, node->mutex));
+            /* Exceeds node size. */
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
         }
 
-        if (node->reference != gcvNULL)
+        *PhysicalAddress = node->VidMem.parent->physicalBase
+                         + node->VidMem.offset
+                         + Offset;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        if (Offset >= node->VirtualChunk.bytes)
         {
-            gcmkVERIFY_OK(gckOS_AtomDestroy(os, node->reference));
+            /* Exceeds node size. */
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
         }
 
-        for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
+        gcmkONERROR(
+            gckOS_GetPhysicalFromHandle(os,
+                                        vidMemBlock->physical,
+                                        (gctUINT32)node->VirtualChunk.offset + Offset,
+                                        PhysicalAddress));
+    }
+    else
+    {
+        if (Offset >= node->Virtual.bytes)
         {
-            if (node->sync[i].signal != gcvNULL)
-            {
-                gcmkVERIFY_OK(gckOS_DestroySignal(os, node->sync[i].signal));
-            }
+            /* Exceeds node size. */
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
         }
 
-        gcmkVERIFY_OK(gcmkOS_SAFE_FREE(os, node));
+        gcmkONERROR(
+            gckOS_GetPhysicalFromHandle(os,
+                                        node->Virtual.physical,
+                                        Offset,
+                                        PhysicalAddress));
     }
 
+    gcmkFOOTER_ARG("*PhysicalAddress=0x%llx", *PhysicalAddress);
+    return gcvSTATUS_OK;
+
+OnError:
     gcmkFOOTER();
     return status;
 }
 
 gceSTATUS
-gckVIDMEM_NODE_Dereference(
+gckVIDMEM_NODE_GetGid(
     IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctUINT32 * Gid
     )
 {
-    gctINT32 oldValue   = 0;
-    gctPOINTER database = Kernel->db->nameDatabase;
-    gctPOINTER mutex    = Kernel->db->nameDatabaseMutex;
-    gctUINT i;
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
-    gcmkHEADER_ARG("Kernel=0x%X Node=0x%X", Kernel, Node);
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+    {
+        *Gid = 0;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        *Gid = vidMemBlock->gid;
+    }
+    else
+    {
+        *Gid = node->Virtual.gid;
+    }
 
-    gcmkVERIFY_OK(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
+    return gcvSTATUS_OK;
+}
 
-    gcmkVERIFY_OK(gckOS_AtomDecrement(Kernel->os, Node->reference, &oldValue));
+gceSTATUS
+gckVIDMEM_NODE_GetSize(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gctSIZE_T * Size
+    )
+{
+    gcuVIDMEM_NODE_PTR node = NodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
-    if (oldValue == 1 && Node->name)
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
-        /* Free name if exists. */
-        gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Node->name));
+        *Size = node->VidMem.bytes;
     }
-
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
-
-    if (oldValue == 1)
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
     {
-        /* Free gcuVIDMEM_NODE. */
-        gcmkVERIFY_OK(gckVIDMEM_Free(Kernel, Node->node));
-        gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Node->reference));
-#if gcdPROCESS_ADDRESS_SPACE
-        gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mapMutex));
-#endif
-        gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Node->mutex));
+        *Size = node->VirtualChunk.bytes;
+    }
+    else
+    {
+        *Size = node->Virtual.bytes;
+    }
 
-        for (i = 0; i < gcvENGINE_GPU_ENGINE_COUNT; i++)
-        {
-            if (Node->sync[i].signal != gcvNULL)
-            {
-                gcmkVERIFY_OK(gckOS_DestroySignal(Kernel->os, Node->sync[i].signal));
-            }
-        }
+    return gcvSTATUS_OK;
+}
 
-        /* Should not cause recursive call since tsNode->tsNode should be NULL */
-        if (Node->tsNode)
-        {
-            gcmkASSERT(!Node->tsNode->tsNode);
-            gckVIDMEM_NODE_Dereference(Kernel, Node->tsNode);
-        }
+gceSTATUS
+gckVIDMEM_NODE_GetType(
+    IN gckKERNEL Kernel,
+    IN gckVIDMEM_NODE NodeObject,
+    OUT gceVIDMEM_TYPE * Type,
+    OUT gcePOOL * Pool
+    )
+{
+    if (Type)
+    {
+        *Type = NodeObject->type;
+    }
 
-        gcmkOS_SAFE_FREE(Kernel->os, Node);
+    if (Pool)
+    {
+        *Pool = NodeObject->pool;
     }
 
-    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 }
 
@@ -2860,16 +3938,23 @@ static struct sg_table *_dmabuf_map(struct dma_buf_attachment *attachment,
     do
     {
         gcuVIDMEM_NODE_PTR node = nodeObject->node;
+        gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
         gctPHYS_ADDR physical = gcvNULL;
         gctSIZE_T offset = 0;
         gctSIZE_T bytes = 0;
 
-        if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+        if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
         {
-            physical = node->VidMem.memory->physical;
+            physical = node->VidMem.parent->physical;
             offset = node->VidMem.offset;
             bytes = node->VidMem.bytes;
         }
+        else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+        {
+            physical = vidMemBlock->physical;
+            offset = node->VirtualChunk.offset;
+            bytes = node->VirtualChunk.bytes;
+        }
         else
         {
             physical = node->Virtual.physical;
@@ -2906,16 +3991,22 @@ static int _dmabuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
 {
     gckVIDMEM_NODE nodeObject = dmabuf->priv;
     gcuVIDMEM_NODE_PTR node = nodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gctPHYS_ADDR physical = gcvNULL;
     gctSIZE_T skipPages = vma->vm_pgoff;
     gctSIZE_T numPages = PAGE_ALIGN(vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
     gceSTATUS status = gcvSTATUS_OK;
 
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
-        physical = node->VidMem.memory->physical;
+        physical = node->VidMem.parent->physical;
         skipPages += (node->VidMem.offset >> PAGE_SHIFT);
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physical  = vidMemBlock->physical;
+        skipPages += (node->VirtualChunk.offset >> PAGE_SHIFT);
+    }
     else
     {
         physical = node->Virtual.physical;
@@ -2938,26 +4029,32 @@ static void *_dmabuf_kmap(struct dma_buf *dmabuf, unsigned long offset)
 {
     gckVIDMEM_NODE nodeObject = dmabuf->priv;
     gcuVIDMEM_NODE_PTR node = nodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gctINT8_PTR kvaddr = gcvNULL;
     gctPHYS_ADDR physical = gcvNULL;
     gctSIZE_T bytes = 0;
-    gctSIZE_T pageCount = 0;
 
     offset = (offset << PAGE_SHIFT);
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
-        physical = node->VidMem.memory->physical;
+        physical = node->VidMem.parent->physical;
         offset += node->VidMem.offset;
         bytes = node->VidMem.bytes;
     }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physical = vidMemBlock->physical;
+        offset += node->VirtualChunk.offset;
+        bytes = node->VirtualChunk.bytes;
+    }
     else
     {
         physical = node->Virtual.physical;
         bytes = node->Virtual.bytes;
     }
 
-    if (gcmIS_SUCCESS(gckOS_CreateKernelVirtualMapping(
-            nodeObject->kernel->os, physical, bytes, (gctPOINTER*)&kvaddr, &pageCount)))
+    if (gcmIS_SUCCESS(gckOS_CreateKernelMapping(
+            nodeObject->kernel->os, physical, 0, bytes, (gctPOINTER*)&kvaddr)))
     {
         kvaddr += offset;
     }
@@ -2969,24 +4066,27 @@ static void _dmabuf_kunmap(struct dma_buf *dmabuf, unsigned long offset, void *p
 {
     gckVIDMEM_NODE nodeObject = dmabuf->priv;
     gcuVIDMEM_NODE_PTR node = nodeObject->node;
+    gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
     gctINT8_PTR kvaddr = (gctINT8_PTR)ptr - (offset << PAGE_SHIFT);
     gctPHYS_ADDR physical = gcvNULL;
-    gctSIZE_T bytes = 0;
 
-    if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+    if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
     {
-        physical = node->VidMem.memory->physical;
+        physical = node->VidMem.parent->physical;
         kvaddr -= node->VidMem.offset;
-        bytes = node->VidMem.bytes;
+    }
+    else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+    {
+        physical = vidMemBlock->physical;
+        kvaddr -= node->VirtualChunk.offset;
     }
     else
     {
         physical = node->Virtual.physical;
-        bytes = node->Virtual.bytes;
     }
 
-    gcmkVERIFY_OK(gckOS_DestroyKernelVirtualMapping(
-            nodeObject->kernel->os, physical, bytes, (gctPOINTER*)&kvaddr));
+    gcmkVERIFY_OK(gckOS_DestroyKernelMapping(
+            nodeObject->kernel->os, physical, (gctPOINTER*)&kvaddr));
 }
 
 static struct dma_buf_ops _dmabuf_ops =
@@ -3015,7 +4115,7 @@ static struct dma_buf_ops _dmabuf_ops =
 gceSTATUS
 gckVIDMEM_NODE_Export(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
+    IN gckVIDMEM_NODE NodeObject,
     IN gctINT32 Flags,
     OUT gctPOINTER *DmaBuf,
     OUT gctINT32 *FD
@@ -3023,29 +4123,30 @@ gckVIDMEM_NODE_Export(
 {
 #if defined(CONFIG_DMA_SHARED_BUFFER)
     gceSTATUS status = gcvSTATUS_OK;
-    gckVIDMEM_NODE nodeObject = gcvNULL;
-    gctUINT32 processID = 0;
     struct dma_buf *dmabuf = gcvNULL;
 
-    gcmkHEADER_ARG("Kernel=%p Handle=0x%x", Kernel, Handle);
-
-    gckOS_GetProcessID(&processID);
-    gcmkONERROR(gckVIDMEM_HANDLE_Lookup(Kernel, processID, Handle, &nodeObject));
+    gcmkHEADER_ARG("Kernel=%p NodeObject=0x%x", Kernel, NodeObject);
 
-    dmabuf = nodeObject->dmabuf;
+    dmabuf = NodeObject->dmabuf;
     if (!dmabuf)
     {
         gctSIZE_T bytes = 0;
         gctPHYS_ADDR physical = gcvNULL;
-        gcuVIDMEM_NODE_PTR node = nodeObject->node;
+        gcuVIDMEM_NODE_PTR node = NodeObject->node;
+        gckVIDMEM_BLOCK vidMemBlock = node->VirtualChunk.parent;
 
-        if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+        if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
         {
-            physical = node->VidMem.memory->physical;
+            physical = node->VidMem.parent->physical;
             bytes = node->VidMem.bytes;
             /* Align export size. when allocate memory from VIDMEM, the actual node size may not same with aligned size. */
             bytes = bytes & ~(PAGE_SIZE - 1);
         }
+        else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+        {
+            physical = vidMemBlock->physical;
+            bytes = node->VirtualChunk.bytes;
+        }
         else
         {
             physical = node->Virtual.physical;
@@ -3061,12 +4162,12 @@ gckVIDMEM_NODE_Export(
             exp_info.ops = &_dmabuf_ops;
             exp_info.size = bytes;
             exp_info.flags = Flags;
-            exp_info.priv = nodeObject;
+            exp_info.priv = NodeObject;
             dmabuf = dma_buf_export(&exp_info);
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
-            dmabuf = dma_buf_export(nodeObject, &_dmabuf_ops, bytes, Flags, NULL);
+            dmabuf = dma_buf_export(NodeObject, &_dmabuf_ops, bytes, Flags, NULL);
 #else
-            dmabuf = dma_buf_export(nodeObject, &_dmabuf_ops, bytes, Flags);
+            dmabuf = dma_buf_export(NodeObject, &_dmabuf_ops, bytes, Flags);
 #endif
         }
 
@@ -3076,13 +4177,13 @@ gckVIDMEM_NODE_Export(
         }
 
         /* Reference this gckVIDMEM_NODE object. */
-        gckVIDMEM_NODE_Reference(Kernel, nodeObject);
-        nodeObject->dmabuf = dmabuf;
+        gckVIDMEM_NODE_Reference(Kernel, NodeObject);
+        NodeObject->dmabuf = dmabuf;
     }
 
     if (DmaBuf)
     {
-        *DmaBuf = nodeObject->dmabuf;
+        *DmaBuf = NodeObject->dmabuf;
     }
 
     if (FD)
@@ -3106,69 +4207,44 @@ OnError:
 #endif
 }
 
-
-/*******************************************************************************
-**
-**  gckVIDMEM_NODE_Name
-**
-**  Naming a gckVIDMEM_NODE object.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gctUINT32 Handle
-**          Handle to a gckVIDMEM_NODE object.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * Name
-**          Pointer to a variable receiving a name which can be pass to another
-**          process.
-*/
 gceSTATUS
 gckVIDMEM_NODE_Name(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
+    IN gckVIDMEM_NODE NodeObject,
     OUT gctUINT32 * Name
     )
 {
     gceSTATUS status;
-    gckVIDMEM_NODE node = gcvNULL;
     gctUINT32 name      = 0;
-    gctUINT32 processID = 0;
     gctPOINTER database = Kernel->db->nameDatabase;
     gctPOINTER mutex    = Kernel->db->nameDatabaseMutex;
     gctBOOL acquired    = gcvFALSE;
     gctBOOL referenced  = gcvFALSE;
-    gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+    gcmkHEADER_ARG("Kernel=0x%X NodeObject=%p", Kernel, NodeObject);
 
     gcmkVERIFY_ARGUMENT(Name != gcvNULL);
 
-    gcmkONERROR(gckOS_GetProcessID(&processID));
-
     gcmkONERROR(gckOS_AcquireMutex(Kernel->os, mutex, gcvINFINITE));
     acquired = gcvTRUE;
 
-    gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+    gcmkONERROR(gckVIDMEM_NODE_Reference(Kernel, NodeObject));
     referenced = gcvTRUE;
 
-    if (node->name == 0)
+    if (NodeObject->name == 0)
     {
         /* Name this node. */
-        gcmkONERROR(gckKERNEL_AllocateIntegerId(database, node, &name));
-        node->name = name;
+        gcmkONERROR(gckKERNEL_AllocateIntegerId(database, NodeObject, &name));
+        NodeObject->name = name;
     }
     else
     {
-        name = node->name;
+        name = NodeObject->name;
     }
 
     gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
     acquired = gcvFALSE;
 
-    gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+    gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, NodeObject));
 
     *Name = name;
 
@@ -3178,7 +4254,7 @@ gckVIDMEM_NODE_Name(
 OnError:
     if (referenced)
     {
-        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, NodeObject));
     }
 
     if (acquired)
@@ -3190,31 +4266,11 @@ OnError:
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckVIDMEM_NODE_Import
-**
-**  Import a gckVIDMEM_NODE object.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gctUINT32 Name
-**          Name of a gckVIDMEM_NODE object.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * Handle
-**          Pointer to a variable receiving a handle represent this
-**          gckVIDMEM_NODE in userspace.
-*/
 gceSTATUS
 gckVIDMEM_NODE_Import(
     IN gckKERNEL Kernel,
     IN gctUINT32 Name,
-    OUT gctUINT32 * Handle
+    OUT gckVIDMEM_NODE * NodeObject
     )
 {
     gceSTATUS status;
@@ -3239,10 +4295,8 @@ gckVIDMEM_NODE_Import(
     gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, mutex));
     acquired = gcvFALSE;
 
-    /* Allocate a handle for current process. */
-    gcmkONERROR(gckVIDMEM_HANDLE_Allocate(Kernel, node, Handle));
-
-    gcmkFOOTER_ARG("*Handle=%d", *Handle);
+    *NodeObject = node;
+    gcmkFOOTER_ARG("*NodeObject=%p", node);
     return gcvSTATUS_OK;
 
 OnError:
@@ -3290,14 +4344,6 @@ _ReleaseFdPrivate(
 **
 **  Attach a gckVIDMEM_NODE object to a native fd.
 **
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gctUINT32 Handle
-**          Handle to a gckVIDMEM_NODE object.
-**
 **  OUTPUT:
 **
 **      gctUINT32 * Fd
@@ -3306,18 +4352,17 @@ _ReleaseFdPrivate(
 gceSTATUS
 gckVIDMEM_NODE_GetFd(
     IN gckKERNEL Kernel,
-    IN gctUINT32 Handle,
+    IN gckVIDMEM_NODE NodeObject,
     OUT gctINT * Fd
     )
 {
     gceSTATUS status;
-    gckVIDMEM_NODE node = gcvNULL;
     gctBOOL referenced  = gcvFALSE;
     gcsVIDMEM_NODE_FDPRIVATE * fdPrivate = gcvNULL;
-    gcmkHEADER_ARG("Kernel=0x%X Handle=%d", Kernel, Handle);
+    gcmkHEADER_ARG("Kernel=0x%X NodeObject=%d", Kernel, NodeObject);
 
-    /* Query and reference handle. */
-    gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
+    /* Reference node object. */
+    gcmkVERIFY_OK(gckVIDMEM_NODE_Reference(Kernel, NodeObject));
     referenced = gcvTRUE;
 
     /* Allocated fd owns a reference. */
@@ -3329,7 +4374,7 @@ gckVIDMEM_NODE_GetFd(
 
     fdPrivate->base.release = _ReleaseFdPrivate;
     fdPrivate->kernel = Kernel;
-    fdPrivate->node = node;
+    fdPrivate->node = NodeObject;
 
     /* Allocated fd owns a reference. */
     gcmkONERROR(gckOS_GetFd("vidmem", &fdPrivate->base, Fd));
@@ -3340,7 +4385,7 @@ gckVIDMEM_NODE_GetFd(
 OnError:
     if (referenced)
     {
-        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, node));
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Dereference(Kernel, NodeObject));
     }
 
     if (fdPrivate)
@@ -3356,20 +4401,18 @@ gceSTATUS
 gckVIDMEM_NODE_WrapUserMemory(
     IN gckKERNEL Kernel,
     IN gcsUSER_MEMORY_DESC_PTR Desc,
-    OUT gctUINT32 * Handle,
+    IN gceVIDMEM_TYPE Type,
+    OUT gckVIDMEM_NODE * NodeObject,
     OUT gctUINT64 * Bytes
     )
 {
     gceSTATUS status = gcvSTATUS_OK;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
     gctBOOL found = gcvFALSE;
 
     gcmkHEADER_ARG("Kernel=0x%x", Kernel);
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-    gcmkVERIFY_ARGUMENT(Desc);
-    gcmkVERIFY_ARGUMENT(Handle);
-    gcmkVERIFY_ARGUMENT(Bytes);
+    gcmkVERIFY_ARGUMENT(Desc != gcvNULL);
 
 #if defined(CONFIG_DMA_SHARED_BUFFER)
     if (Desc->flag & gcvALLOC_FLAG_DMABUF)
@@ -3392,23 +4435,30 @@ gckVIDMEM_NODE_WrapUserMemory(
         }
         else
         {
+            if (!Desc->dmabuf)
+            {
+                gcmkPRINT("Wrap user memory: invalid dmabuf from user.\n");
+
+                gcmkFOOTER();
+                return gcvSTATUS_INVALID_ARGUMENT;
+            }
+
             dmabuf = gcmUINT64_TO_PTR(Desc->dmabuf);
         }
 
         if (dmabuf->ops == &_dmabuf_ops)
         {
             gctBOOL referenced = gcvFALSE;
-            gckVIDMEM_NODE nodeObject = dmabuf->priv;
+            nodeObject = dmabuf->priv;
 
             do
             {
                 /* Reference the node. */
                 gcmkERR_BREAK(gckVIDMEM_NODE_Reference(Kernel, nodeObject));
                 referenced = gcvTRUE;
-                /* Allocate a handle for current process. */
-                gcmkERR_BREAK(gckVIDMEM_HANDLE_Allocate(Kernel, nodeObject, Handle));
                 found = gcvTRUE;
 
+                *NodeObject = nodeObject;
                 *Bytes = (gctUINT64)dmabuf->size;
             }
             while (gcvFALSE);
@@ -3426,9 +4476,14 @@ gckVIDMEM_NODE_WrapUserMemory(
         gckOS os = Kernel->os;
         gcuVIDMEM_NODE_PTR node = gcvNULL;
 
-        gcmkVERIFY_OBJECT(os, gcvOBJ_OS);
+        do
+        {
+            gctSIZE_T pageCountCpu = 0;
+            gctSIZE_T pageSizeCpu = 0;
+            gctPHYS_ADDR_T physicalAddress = 0;
+
+            gcmkVERIFY_OK(gckOS_GetPageSize(os, &pageSizeCpu));
 
-        do {
             /* Allocate an gcuVIDMEM_NODE union. */
             gcmkERR_BREAK(gckOS_Allocate(os, gcmSIZEOF(gcuVIDMEM_NODE), (gctPOINTER*)&node));
             gckOS_ZeroMemory(node, gcmSIZEOF(gcuVIDMEM_NODE));
@@ -3437,18 +4492,34 @@ gckVIDMEM_NODE_WrapUserMemory(
             node->Virtual.kernel = Kernel;
 
             /* Wrap Memory. */
-            gcmkERR_BREAK(gckOS_WrapMemory(os, Desc, &node->Virtual.bytes,
-                                           &node->Virtual.physical, &node->Virtual.contiguous));
+            gcmkERR_BREAK(
+                gckOS_WrapMemory(os,
+                                 Desc,
+                                 &node->Virtual.bytes,
+                                 &node->Virtual.physical,
+                                 &node->Virtual.contiguous,
+                                 &pageCountCpu));
+
+            /* Get base physical address. */
+            gcmkERR_BREAK(
+                gckOS_GetPhysicalFromHandle(os,
+                                            node->Virtual.physical,
+                                            0,
+                                            &physicalAddress));
 
             /* Allocate handle for this video memory. */
-            gcmkERR_BREAK(gckVIDMEM_NODE_Allocate(
+            gcmkERR_BREAK(gckVIDMEM_NODE_Construct(
                 Kernel,
                 node,
-                gcvSURF_BITMAP,
+                Type,
                 gcvPOOL_VIRTUAL,
-                Handle
+                &nodeObject
                 ));
 
+            node->Virtual.pageCount = (pageCountCpu * pageSizeCpu -
+                    (physicalAddress & (pageSizeCpu - 1) & ~(4096 - 1))) >> 12;
+
+            *NodeObject = nodeObject;
             *Bytes = (gctUINT64)node->Virtual.bytes;
         }
         while (gcvFALSE);
@@ -3466,125 +4537,151 @@ gckVIDMEM_NODE_WrapUserMemory(
 }
 
 gceSTATUS
-gckVIDMEM_SetCommitStamp(
+gckVIDMEM_NODE_SetCommitStamp(
     IN gckKERNEL Kernel,
     IN gceENGINE Engine,
-    IN gctUINT32 Handle,
+    IN gckVIDMEM_NODE NodeObject,
     IN gctUINT64 CommitStamp
     )
 {
-    gceSTATUS status;
-    gckVIDMEM_NODE node;
-    gctUINT32 processID;
-
-    gckOS_GetProcessID(&processID);
-
-    gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
-
-    node->sync[Engine].commitStamp = CommitStamp;
-
-    gckVIDMEM_NODE_Dereference(Kernel, node);
-
+    NodeObject->sync[Engine].commitStamp = CommitStamp;
     return gcvSTATUS_OK;
-
-OnError:
-    return status;
 }
 
 gceSTATUS
-gckVIDMEM_GetCommitStamp(
+gckVIDMEM_NODE_GetCommitStamp(
     IN gckKERNEL Kernel,
     IN gceENGINE Engine,
-    IN gctUINT32 Handle,
+    IN gckVIDMEM_NODE NodeObject,
     OUT gctUINT64_PTR CommitStamp
     )
 {
-    gceSTATUS status;
-    gckVIDMEM_NODE node;
-    gctUINT32 processID;
-
-    gckOS_GetProcessID(&processID);
-
-    gcmkONERROR(gckVIDMEM_HANDLE_LookupAndReference(Kernel, Handle, &node));
-
-    *CommitStamp = node->sync[Engine].commitStamp;
-
-    gckVIDMEM_NODE_Dereference(Kernel, node);
-
+    *CommitStamp = NodeObject->sync[Engine].commitStamp;
     return gcvSTATUS_OK;
-
-OnError:
-    return status;
 }
 
+/*******************************************************************************
+**
+**  gckVIDMEM_NODE_Find
+**
+**  Find gckVIDMEM_NODE object according to GPU address of specified core.
+**
+**  INPUT:
+**
+**      gckKERNEL Kernel
+**          Kernel object, specifies core.
+**
+**      gctUINT32 Address
+**          GPU address to search.
+**
+**  OUTPUT:
+**
+**      gckVIDMEM_NODE * NodeObject
+**          Pointer to a variable hold found video memory node.
+**
+**      gctUINT32 * Offset
+**          The offset of specified GPU address in found video memory node.
+*/
 gceSTATUS
-gckVIDMEM_FindVIDMEM(
+gckVIDMEM_NODE_Find(
     IN gckKERNEL Kernel,
-    IN gctUINT32 HardwareAddress,
-    OUT gcuVIDMEM_NODE_PTR * Node,
-    OUT gctUINT32_PTR PageTableEntryValue
+    IN gctUINT32 Address,
+    OUT gckVIDMEM_NODE * NodeObject,
+    OUT gctUINT32 * Offset
     )
 {
     gceSTATUS status = gcvSTATUS_NOT_FOUND;
+    gckVIDMEM_NODE nodeObject = gcvNULL;
     gcuVIDMEM_NODE_PTR node = gcvNULL;
-
+    gckVIDMEM_BLOCK vidMemBlock = gcvNULL;
     gcsLISTHEAD_PTR pos;
+    gceHARDWARE_TYPE hwType;
 
-    gcmkLIST_FOR_EACH(pos, &Kernel->db->onFaultVidmemList)
-    {
-        node = (gcuVIDMEM_NODE_PTR)gcmCONTAINEROF(pos, _gcsVIDMEM_NODE_VIRTUAL, head);
+    gcmkVERIFY_OK(
+        gckKERNEL_GetHardwareType(Kernel,
+                                  &hwType));
 
-        if (HardwareAddress >= node->Virtual.addresses[Kernel->core]
-         && (HardwareAddress <= node->Virtual.addresses[Kernel->core] - 1 + node->Virtual.bytes)
-            )
-        {
-            *Node = node;
-            status = gcvSTATUS_OK;
-            break;
-        }
-    }
+    gcmkVERIFY_OK(
+        gckOS_AcquireMutex(Kernel->os,
+                           Kernel->db->videoMemListMutex,
+                           gcvINFINITE));
 
-    if (gcmIS_SUCCESS(status))
+    gcmkLIST_FOR_EACH(pos, &Kernel->db->videoMemList)
     {
-        /* Setup map for fault address. */
-        gctUINT32 offset = HardwareAddress - node->Virtual.addresses[Kernel->core];
-        gctPHYS_ADDR_T physicalAddress;
+        nodeObject = (gckVIDMEM_NODE)gcmCONTAINEROF(pos, struct _gcsVIDMEM_NODE, link);
+        node = nodeObject->node;
+        vidMemBlock = node->VirtualChunk.parent;
 
-        offset &= ~gcdMMU_PAGE_4K_MASK;
+        if (node->VidMem.parent->object.type == gcvOBJ_VIDMEM)
+        {
+            if (!node->VidMem.locked)
+            {
+                /* Don't check against unlocked node. */
+                continue;
+            }
 
-        gckOS_PhysicalToPhysicalAddress(Kernel->os, node->Virtual.physical, offset, &physicalAddress);
+            if (Address >= node->VidMem.address &&
+                Address <= node->VidMem.address + node->VidMem.bytes - 1)
+            {
+                *NodeObject = nodeObject;
 
-        gcmkSAFECASTPHYSADDRT(*PageTableEntryValue, physicalAddress);
-    }
+                if (Offset)
+                {
+                    *Offset = Address - node->VidMem.address;
+                }
 
-    return status;
-}
+                status = gcvSTATUS_OK;
+                break;
+            }
+        }
+        else if (vidMemBlock && vidMemBlock->object.type == gcvOBJ_VIDMEM_BLOCK)
+        {
+            if (!node->VirtualChunk.lockeds[hwType])
+            {
+                /* Don't check against unlocked node. */
+                continue;
+            }
 
-/* Get the nodes of all banks. */
-gceSTATUS
-gckVIDMEM_QueryNodes(
-    IN gckKERNEL Kernel,
-    IN gcePOOL   Pool,
-    OUT gctINT32 *Count,
-    OUT gcuVIDMEM_NODE_PTR *Nodes
-    )
-{
-    gceSTATUS status = gcvSTATUS_OK;
-    gckVIDMEM   memory = gcvNULL;
+            if (Address >= node->VirtualChunk.addresses[hwType] &&
+                Address <= node->VirtualChunk.addresses[hwType] + node->VirtualChunk.bytes - 1)
+            {
+                *NodeObject = nodeObject;
 
-    do
-    {
-        status = gckKERNEL_GetVideoMemoryPool(Kernel, Pool, &memory);
-        if (status != gcvSTATUS_OK)
-            break;
+                if (Offset)
+                {
+                    *Offset = Address - node->VirtualChunk.addresses[hwType];
+                }
 
-        if (memory != gcvNULL)
+                status = gcvSTATUS_OK;
+                break;
+            }
+        }
+        else
         {
-            *Count = gcmCOUNTOF(memory->sentinel);
-            *Nodes = memory->sentinel;
+            if (!node->Virtual.lockeds[hwType])
+            {
+                /* Don't check against unlocked node. */
+                continue;
+            }
+
+            if (Address >= node->Virtual.addresses[hwType] &&
+                (Address <= node->Virtual.addresses[hwType] + node->Virtual.bytes - 1))
+            {
+                *NodeObject = nodeObject;
+
+                if (Offset)
+                {
+                    *Offset = Address - node->Virtual.addresses[hwType];
+                }
+
+                status = gcvSTATUS_OK;
+                break;
+            }
         }
     }
-    while (gcvFALSE);
+
+    gcmkVERIFY_OK(
+        gckOS_ReleaseMutex(Kernel->os, Kernel->db->videoMemListMutex));
 
     return status;
 }
index e3bac04..2077a7e 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -53,7 +53,7 @@
 *****************************************************************************/
 
 
-/*Auto created on 2018-12-18 14:20*/
+/*Auto created on 2019-04-01 09:55*/
 #ifndef _gc_feature_database_h_
 #define _gc_feature_database_h_
 
@@ -110,7 +110,7 @@ typedef struct
     gctUINT32 NNFP16_ZDP;
     gctUINT32 NN_LANES_PER_OUT_CYCLE;
     gctUINT32 MAX_OT_NUMBER;
-    gctUINT32 VIP_SRAM_WIDTH_INBYTE;
+    gctUINT32 EQUIVALENT_VIP_SRAM_WIDTH_INBYTE;
     gctUINT32 TP_ZRL_BITS;
     gctUINT32 REG_FastClear:1;
     gctUINT32 REG_SpecialAntiAliasing:1;
@@ -481,6 +481,9 @@ typedef struct
     gctUINT32 PA_LINECLIP_FIX:1;
     gctUINT32 TX_8bit_UVFrac_ROUNDING_FIX:1;
     gctUINT32 MP_ARCH:1;
+    gctUINT32 TX_NO_FIXED_FILTER:1;
+    gctUINT32 SHARE_Z:1;
+    gctUINT32 DE_2D_FAST_CLEAR:1;
     gctUINT32 VG_TS_CULLING:1;
     gctUINT32 VG_FP25:1;
     gctUINT32 VG_AYUV_INPUT_OUTPUT:1;
@@ -576,6 +579,17 @@ typedef struct
     gctUINT32 HI_REORDER_FIX:1;
     gctUINT32 TP_COEF_COMPRESSION_ENHANCEMENT:1;
     gctUINT32 VIP_DEC400:1;
+    gctUINT32 IMAGE_NOT_PACKED_IN_SRAM_FIX:1;
+    gctUINT32 IDLE_BEFORE_FLUSH_COMPLETE_FIX:1;
+    gctUINT32 NO_FLUSH_USC_FIX:1;
+    gctUINT32 COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX:1;
+    gctUINT32 XY_OFFSET_LIMITATION_FIX:1;
+    gctUINT32 USC_INVALIDATE_CACHE_LINE_FIX:1;
+    gctUINT32 LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX:1;
+    gctUINT32 KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX:1;
+    gctUINT32 NN_PER_CHANNEL_POST_MULTIPLY:1;
+    gctUINT32 NN_NO_Z_LOCATION_OFFSET:1;
+    gctUINT32 NN_PRELU:1;
 } gcsFEATURE_DATABASE;
 
 static gcsFEATURE_DATABASE gChipInfo[] = {
@@ -631,7 +645,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -1002,6 +1016,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -1097,6 +1114,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* dc0000_5560 */
     {
@@ -1150,7 +1178,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -1521,6 +1549,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -1616,6 +1647,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc200_4650 */
     {
@@ -1669,7 +1711,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -2040,6 +2082,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -2135,6 +2180,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc200_4621 */
     {
@@ -2188,7 +2244,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -2559,6 +2615,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -2654,6 +2713,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc300_4650 */
     {
@@ -2707,7 +2777,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -3078,6 +3148,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -3173,6 +3246,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc300_4650_guoke */
     {
@@ -3226,7 +3310,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -3597,6 +3681,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -3692,6 +3779,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc300_4_6_6_rc0 */
     {
@@ -3745,7 +3843,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -4116,6 +4214,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -4211,6 +4312,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc320_5007 */
     {
@@ -4264,7 +4376,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -4635,6 +4747,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -4730,6 +4845,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc320_5220 */
     {
@@ -4783,7 +4909,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -5154,6 +5280,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -5249,6 +5378,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc320_5303 */
     {
@@ -5302,7 +5442,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -5673,6 +5813,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -5768,6 +5911,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc320_5303_1 */
     {
@@ -5821,7 +5975,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -6192,6 +6346,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -6287,6 +6444,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc320_5340 */
     {
@@ -6340,7 +6508,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -6711,6 +6879,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -6806,6 +6977,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc320c_5341 */
     {
@@ -6859,7 +7041,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -7230,6 +7412,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -7325,6 +7510,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc320_5341 */
     {
@@ -7378,7 +7574,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -7749,6 +7945,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -7844,6 +8043,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520l_5_3_5_rc0 */
     {
@@ -7897,7 +8107,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -8268,6 +8478,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -8363,6 +8576,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc355_v121_rc5 */
     {
@@ -8416,7 +8640,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -8787,6 +9011,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -8882,6 +9109,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc355_v121x */
     {
@@ -8935,7 +9173,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -9306,6 +9544,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -9401,6 +9642,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc355_8Kx8K */
     {
@@ -9454,7 +9706,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -9825,6 +10077,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -9920,6 +10175,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc355_16K */
     {
@@ -9973,7 +10239,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -10344,6 +10610,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -10439,6 +10708,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc400_4633 */
     {
@@ -10492,7 +10772,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -10863,6 +11143,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -10958,6 +11241,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc600_4633 */
     {
@@ -11011,7 +11305,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -11382,6 +11676,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -11477,6 +11774,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc400_4645 */
     {
@@ -11530,7 +11838,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -11901,6 +12209,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -11996,6 +12307,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc400L_0x465x */
     {
@@ -12049,7 +12371,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -12420,6 +12742,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -12515,6 +12840,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000nano_0x4652 */
     {
@@ -12568,7 +12904,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -12939,6 +13275,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -13034,6 +13373,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000nano_0x4652 */
     {
@@ -13087,7 +13437,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -13458,6 +13808,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -13553,6 +13906,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc420_5325 */
     {
@@ -13606,7 +13970,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -13977,6 +14341,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -14072,6 +14439,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc420_5336 */
     {
@@ -14125,7 +14503,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -14496,6 +14874,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -14591,6 +14972,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc420cpd_533rc7a */
     {
@@ -14644,7 +15036,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -15015,6 +15407,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -15110,6 +15505,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc428_5421 */
     {
@@ -15163,7 +15569,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -15534,6 +15940,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -15629,6 +16038,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc428c_5_4_2_rc3a */
     {
@@ -15682,7 +16102,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -16053,6 +16473,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -16148,6 +16571,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520_5341 */
     {
@@ -16201,7 +16635,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -16572,6 +17006,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -16667,6 +17104,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520l_5341_rc1b */
     {
@@ -16720,7 +17168,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -17091,6 +17539,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -17186,6 +17637,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520l_5341_rc1c */
     {
@@ -17239,7 +17701,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -17413,7 +17875,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_SHEnhancements5 */
         0x0, /* gcFEATURE_BIT_REG_FEEnhancements2 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes16 */
-        0x1, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
         0x0, /* gcFEATURE_BIT_REG_TXEnhancements4 */
         0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
         0x0, /* gcFEATURE_BIT_REG_MCEnhancements1 */
@@ -17430,7 +17892,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_Compression2D */
         0x0, /* gcFEATURE_BIT_REG_Probe */
         0x0, /* gcFEATURE_BIT_REG_MediumPrecision */
-        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_DESupertile */
         0x0, /* gcFEATURE_BIT_REG_BugFixes19 */
         0x0, /* gcFEATURE_BIT_REG_SHEnhancements6 */
         0x0, /* gcFEATURE_BIT_REG_SHEnhancements7 */
@@ -17610,6 +18072,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x1, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -17705,6 +18170,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520_5540_rc0 */
     {
@@ -17758,7 +18234,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -18129,6 +18605,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -18224,6 +18703,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520l_5_3_4_rc2b */
     {
@@ -18277,7 +18767,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x1, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -18648,6 +19138,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -18743,6 +19236,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520c_5_5_0 */
     {
@@ -18796,7 +19300,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -19167,6 +19671,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -19262,6 +19769,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520c_5_5_4_rc1  */
     {
@@ -19315,7 +19833,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -19686,6 +20204,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -19781,6 +20302,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520sp_5_5_2_rc0a */
     {
@@ -19834,7 +20366,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -20205,6 +20737,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -20300,6 +20835,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520_v552_rc1 */
     {
@@ -20353,7 +20899,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -20724,6 +21270,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -20819,6 +21368,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc520_5_5_3_rc2a */
     {
@@ -20872,7 +21432,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -21243,6 +21803,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -21338,6 +21901,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc600L_0x465x */
     {
@@ -21391,7 +21965,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -21762,6 +22336,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -21857,6 +22434,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000nanoultra_4_6_5_rc3a */
     {
@@ -21910,7 +22498,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -22281,6 +22869,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -22376,6 +22967,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000nanoultra_4_6_5_rc3b */
     {
@@ -22429,7 +23031,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -22800,6 +23402,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -22895,6 +23500,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000nanoultra_4_6_5_rc3e */
     {
@@ -22948,7 +23564,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -23319,6 +23935,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -23414,6 +24033,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000nanoultra_4_6_5_rc3e */
     {
@@ -23467,7 +24097,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -23838,6 +24468,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -23933,6 +24566,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc620_5_5_3_rc0 */
     {
@@ -23986,7 +24630,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -24357,6 +25001,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -24452,6 +25099,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc620_5_5_5_rc0d */
     {
@@ -24505,7 +25163,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -24876,6 +25534,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -24971,6 +25632,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc620s_5_5_5_rc1b */
     {
@@ -25024,7 +25696,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -25395,6 +26067,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -25490,6 +26165,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc620tpc_5_5_6_rc0a */
     {
@@ -25543,7 +26229,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -25914,6 +26600,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -26009,6 +26698,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc860L_0x464x */
     {
@@ -26062,7 +26762,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -26433,6 +27133,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -26528,6 +27231,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc880_5106 */
     {
@@ -26581,7 +27295,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -26952,6 +27666,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -27047,6 +27764,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc880_5122 */
     {
@@ -27100,7 +27828,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -27471,6 +28199,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -27566,6 +28297,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc880TM_0x512x */
     {
@@ -27619,7 +28361,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -27990,6 +28732,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -28085,6 +28830,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc880TM_0x512x */
     {
@@ -28138,7 +28894,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -28509,6 +29265,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -28604,6 +29363,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc900_5250 */
     {
@@ -28657,7 +29427,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -29028,6 +29798,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -29123,6 +29896,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc1000_5036 */
     {
@@ -29176,7 +29960,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -29547,6 +30331,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -29642,6 +30429,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc1000_5037 */
     {
@@ -29695,7 +30493,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -30066,6 +30864,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -30161,6 +30962,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc1000_5037_1 */
     {
@@ -30214,7 +31026,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -30585,6 +31397,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -30680,6 +31495,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc1000_5039 */
     {
@@ -30733,7 +31559,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -31104,6 +31930,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -31199,6 +32028,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc1500_5246 */
     {
@@ -31252,7 +32092,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -31623,6 +32463,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -31718,6 +32561,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc2000_5108 */
     {
@@ -31771,7 +32625,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -32142,6 +32996,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -32237,6 +33094,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc2000_5140 */
     {
@@ -32290,7 +33158,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -32661,6 +33529,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -32756,6 +33627,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc2000w_5_1_4_rc0e */
     {
@@ -32809,7 +33691,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -33180,6 +34062,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -33275,6 +34160,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc2500_5422 */
     {
@@ -33328,7 +34224,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -33699,6 +34595,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -33794,6 +34693,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc6400_5422 */
     {
@@ -33847,7 +34757,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -34218,6 +35128,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -34313,6 +35226,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc3000_5435 */
     {
@@ -34366,7 +35290,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -34737,6 +35661,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -34832,6 +35759,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc2000_ffff5450 */
     {
@@ -34885,7 +35823,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -35256,6 +36194,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -35351,6 +36292,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc3000_5450 */
     {
@@ -35404,7 +36356,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -35775,6 +36727,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -35870,6 +36825,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc3000_5451 */
     {
@@ -35923,7 +36889,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -36294,6 +37260,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -36389,6 +37358,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000L_551x */
     {
@@ -36442,7 +37422,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -36813,6 +37793,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -36908,6 +37891,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000L_5512 */
     {
@@ -36961,7 +37955,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -37332,6 +38326,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -37427,6 +38424,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000L_5514 */
     {
@@ -37480,7 +38488,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -37851,6 +38859,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -37946,6 +38957,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc4000_5222 */
     {
@@ -37999,7 +39021,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -38370,6 +39392,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -38465,6 +39490,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc4000_5245 */
     {
@@ -38518,7 +39554,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -38889,6 +39925,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -38984,6 +40023,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc5000_5434 */
     {
@@ -39037,7 +40087,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -39408,6 +40458,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -39503,6 +40556,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000_551x */
     {
@@ -39556,7 +40620,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -39927,6 +40991,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -40022,6 +41089,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000_5513 */
     {
@@ -40075,7 +41153,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -40446,6 +41524,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -40541,6 +41622,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gcXAQ2_CMODEL */
     {
@@ -40594,7 +41686,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -40965,6 +42057,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -41060,6 +42155,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XS_600x */
     {
@@ -41113,7 +42219,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -41484,6 +42590,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -41579,6 +42688,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XS_6008 */
     {
@@ -41632,7 +42752,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -42003,6 +43123,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -42098,6 +43221,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XSVX_600x */
     {
@@ -42151,7 +43285,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -42522,6 +43656,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -42617,6 +43754,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XSVX_6008 */
     {
@@ -42670,7 +43818,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -43041,6 +44189,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -43136,6 +44287,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XSVX_6009 */
     {
@@ -43189,7 +44351,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -43560,6 +44722,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -43655,6 +44820,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XSVX_6009 */
     {
@@ -43708,7 +44884,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -44079,6 +45255,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -44174,6 +45353,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000_6100 */
     {
@@ -44227,7 +45417,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -44598,6 +45788,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -44693,6 +45886,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000L_6100 */
     {
@@ -44746,7 +45950,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -45117,6 +46321,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -45212,6 +46419,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XS_6100 */
     {
@@ -45265,7 +46483,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -45636,6 +46854,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -45731,6 +46952,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000_6200 */
     {
@@ -45784,7 +47016,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -46155,6 +47387,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -46250,6 +47485,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000UL_6200 */
     {
@@ -46303,7 +47549,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -46674,6 +47920,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -46769,6 +48018,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000ULVX_6200 */
     {
@@ -46822,7 +48082,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -47193,6 +48453,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -47288,6 +48551,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7400_551x */
     {
@@ -47341,7 +48615,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -47712,6 +48986,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -47807,6 +49084,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc8000UL_6200 */
     {
@@ -47860,7 +49148,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -48231,6 +49519,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -48326,6 +49617,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* v630 */
     {
@@ -48379,7 +49681,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -48750,6 +50052,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -48845,6 +50150,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XS_6200 */
     {
@@ -48898,7 +50214,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -49269,6 +50585,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -49364,6 +50683,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000L_6200 */
     {
@@ -49417,7 +50747,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -49788,6 +51118,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -49883,6 +51216,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000LXS_6200 */
     {
@@ -49936,7 +51280,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -50307,6 +51651,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -50402,6 +51749,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000ULVX_V11_6200 */
     {
@@ -50455,7 +51813,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -50826,6 +52184,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -50921,6 +52282,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000ULVX_V12_6200 */
     {
@@ -50974,7 +52346,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -51345,6 +52717,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -51440,6 +52815,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc8000ULVX */
     {
@@ -51493,7 +52879,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -51864,6 +53250,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -51959,6 +53348,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* GCNANOULTRA31_VIP2 */
     {
@@ -52001,7 +53401,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x2, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -52012,7 +53412,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -52237,7 +53637,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
         0x1, /* gcFEATURE_BIT_REG_Evis */
-        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
         0x0, /* gcFEATURE_BIT_REG_DEC */
@@ -52330,7 +53730,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
@@ -52340,7 +53740,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
         0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
-        0x1, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
@@ -52367,7 +53767,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
         0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
-        0x1, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x1, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
@@ -52383,6 +53783,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -52452,7 +53855,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
@@ -52478,16 +53881,27 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000ULVX_6200_pid0x60 */
+    /* GCNANOULTRA31 */
     {
         0x7000, /* ChipID */
-        0x6203, /* ChipRevision */
-        0x7000f, /* ProductID */
+        0x6204, /* ChipRevision */
+        0x70007, /* ProductID */
         0x0, /* EcoID */
-        0x60, /* CustomerID */
+        0x12, /* CustomerID */
         0x0, /* PatchVersion */
-        "", /* ProductName */
+        "GCNANOULTRA31", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
         0x200, /* gcFEATURE_VALUE_ThreadCount */
@@ -52495,15 +53909,15 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_LocalStorageSize */
         0x8, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x8, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
-        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
@@ -52511,27 +53925,27 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NumResolvePipes */
         0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
-        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
-        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
-        0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x7, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -52825,9 +54239,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
         0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
-        0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
-        0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
-        0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
         0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
         0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
         0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
@@ -52841,23 +54255,23 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
         0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
-        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
-        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
-        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
         0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
         0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
-        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
         0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
-        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
-        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
@@ -52872,13 +54286,13 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
         0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
-        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x1, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
-        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
-        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x1, /* gcFEATURE_BIT_FENCE_64BIT */
         0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
@@ -52888,20 +54302,23 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
-        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
-        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
-        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
-        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
-        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
-        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
-        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
-        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
-        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x1, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x1, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x1, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x1, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x1, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
-        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x1, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -52929,8 +54346,8 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
         0x0, /* gcFEATURE_BIT_DC_QOS */
         0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
-        0x1, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
-        0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
         0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
         0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
         0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
@@ -52938,73 +54355,84 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
         0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
-        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
-        0x0, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
-        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
-        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000ULN_v122 */
+    /* gc7000ULVX_6200_pid0x60 */
     {
         0x7000, /* ChipID */
         0x6203, /* ChipRevision */
-        0x70003, /* ProductID */
+        0x7000f, /* ProductID */
         0x0, /* EcoID */
-        0x4, /* CustomerID */
+        0x60, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -53014,15 +54442,15 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x8, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
         0x8, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x8, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
-        0x10, /* gcFEATURE_VALUE_Streams */
+        0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
@@ -53050,7 +54478,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -53274,7 +54702,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_RSS8 */
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
-        0x0, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
         0x0, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
@@ -53411,9 +54839,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
         0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
-        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
-        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
-        0x1, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
         0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
         0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
         0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
@@ -53421,6 +54849,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -53447,14 +54878,14 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_DC_MMU */
         0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
         0x0, /* gcFEATURE_BIT_DC_QOS */
-        0x1, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
         0x1, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
         0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
-        0x1, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
-        0x1, /* gcFEATURE_BIT_EVIS_NO_DP32 */
-        0x1, /* gcFEATURE_BIT_EVIS_NO_FILTER */
-        0x1, /* gcFEATURE_BIT_EVIS_NO_IADD */
-        0x1, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
         0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_VX2 */
@@ -53516,14 +54947,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000ULN_v123 */
+    /* gc7000ULN_v122 */
     {
         0x7000, /* ChipID */
         0x6203, /* ChipRevision */
         0x70003, /* ProductID */
         0x0, /* EcoID */
-        0x11, /* CustomerID */
+        0x4, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -53569,7 +55011,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -53892,10 +55334,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
         0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
         0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
@@ -53940,6 +55382,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -54035,38 +55480,49 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000XS_6FFF */
+    /* gc7000ULN_v123 */
     {
         0x7000, /* ChipID */
-        0x6fff, /* ChipRevision */
-        0x70004, /* ProductID */
+        0x6203, /* ChipRevision */
+        0x70003, /* ProductID */
         0x0, /* EcoID */
-        0x0, /* CustomerID */
+        0x11, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x800, /* gcFEATURE_VALUE_ThreadCount */
-        0x8, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x8, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
-        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x8, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
         0x10, /* gcFEATURE_VALUE_Streams */
-        0x1f, /* gcFEATURE_VALUE_VaryingCount */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
         0x10, /* gcFEATURE_VALUE_VertexCacheSize */
         0x1, /* gcFEATURE_VALUE_NumResolvePipes */
-        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x10, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x0, /* gcFEATURE_VALUE_NNMadPerCore */
         0x0, /* gcFEATURE_VALUE_NNCoreCount */
@@ -54088,14 +55544,14 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
         0x0, /* gcFEATURE_BIT_REG_DebugMode */
-        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_ZCompression */
         0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
         0x1, /* gcFEATURE_BIT_REG_MSAA */
         0x0, /* gcFEATURE_BIT_REG_DC */
@@ -54222,7 +55678,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -54292,7 +55748,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -54313,7 +55769,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
         0x0, /* gcFEATURE_BIT_REG_Evis */
-        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
         0x0, /* gcFEATURE_BIT_REG_DEC */
@@ -54323,23 +55779,23 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
-        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_VMSAA */
         0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
         0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
-        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_V4Compression */
         0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
         0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
-        0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
-        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x1, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x0, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -54350,7 +55806,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -54364,7 +55820,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
         0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
-        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
         0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
         0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY */
@@ -54408,13 +55864,13 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
         0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
-        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
         0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
         0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
@@ -54449,9 +55905,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
         0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
-        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
-        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
-        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x1, /* gcFEATURE_BIT_PE_A8B8G8R8 */
         0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
         0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
         0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
@@ -54459,6 +55915,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -54485,14 +55944,14 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_DC_MMU */
         0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
         0x0, /* gcFEATURE_BIT_DC_QOS */
-        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
-        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
-        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
-        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
-        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
-        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
-        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
-        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x1, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x1, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x1, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x1, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x1, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x1, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x1, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x1, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
         0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_VX2 */
@@ -54554,14 +56013,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000_6210 */
+    /* gc7000XS_6FFF */
     {
         0x7000, /* ChipID */
-        0x6210, /* ChipRevision */
-        0x70000, /* ProductID */
+        0x6fff, /* ChipRevision */
+        0x70004, /* ProductID */
         0x0, /* EcoID */
-        0x6, /* CustomerID */
+        0x0, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -54571,16 +56041,16 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
         0x10, /* gcFEATURE_VALUE_Streams */
-        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x1f, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
         0x10, /* gcFEATURE_VALUE_VertexCacheSize */
@@ -54607,7 +56077,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -54741,7 +56211,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -54811,7 +56281,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -54853,12 +56323,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
-        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -54869,7 +56339,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -54883,7 +56353,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
         0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
-        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
         0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
         0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY */
@@ -54901,9 +56371,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
         0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
-        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
-        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
-        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
         0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
         0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
         0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
@@ -54917,12 +56387,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
         0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
-        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
-        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
-        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
-        0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
-        0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
-        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
         0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
@@ -54952,7 +56422,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
-        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
@@ -54978,6 +56448,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -55073,6 +56546,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000_6210 */
     {
@@ -55080,7 +56564,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x6210, /* ChipRevision */
         0x70000, /* ProductID */
         0x0, /* EcoID */
-        0xa, /* CustomerID */
+        0x6, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -55126,7 +56610,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -55444,14 +56928,14 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
-        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
-        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
-        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
         0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
@@ -55473,7 +56957,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
-        0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x1, /* gcFEATURE_BIT_FENCE_64BIT */
         0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
@@ -55497,6 +56981,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -55592,14 +57079,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000XS_6210 */
+    /* gc7000_6210 */
     {
         0x7000, /* ChipID */
         0x6210, /* ChipRevision */
-        0x70004, /* ProductID */
+        0x70000, /* ProductID */
         0x0, /* EcoID */
-        0x8, /* CustomerID */
+        0xa, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -55609,11 +57107,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
         0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
@@ -55645,7 +57143,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -55779,7 +57277,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -55849,7 +57347,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -55892,11 +57390,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
         0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x0, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -55907,7 +57405,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -55970,8 +57468,8 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
         0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
@@ -56016,6 +57514,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -56111,14 +57612,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc8000XS_6210 */
+    /* gc7000XS_6210 */
     {
-        0x8000, /* ChipID */
+        0x7000, /* ChipID */
         0x6210, /* ChipRevision */
-        0x80004, /* ProductID */
+        0x70004, /* ProductID */
         0x0, /* EcoID */
-        0xd, /* CustomerID */
+        0x8, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -56164,7 +57676,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -56487,7 +57999,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
         0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
         0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
         0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
@@ -56535,6 +58047,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -56630,14 +58145,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc8200LXS */
+    /* gc8000XS_6210 */
     {
-        0x8200, /* ChipID */
-        0x6212, /* ChipRevision */
-        0x8200a, /* ProductID */
+        0x8000, /* ChipID */
+        0x6210, /* ChipRevision */
+        0x80004, /* ProductID */
         0x0, /* EcoID */
-        0xe, /* CustomerID */
+        0xd, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -56646,7 +58172,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x2, /* gcFEATURE_VALUE_CoreCount */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
         0x30, /* gcFEATURE_VALUE_LocalStorageSize */
         0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
@@ -56683,7 +58209,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -56919,7 +58445,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x1, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -57054,6 +58580,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -57149,14 +58678,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000XS_6210 */
+    /* gc8200LXS */
     {
-        0x7000, /* ChipID */
-        0x6210, /* ChipRevision */
-        0x70004, /* ProductID */
+        0x8200, /* ChipID */
+        0x6212, /* ChipRevision */
+        0x8200a, /* ProductID */
         0x0, /* EcoID */
-        0xc, /* CustomerID */
+        0xe, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -57165,7 +58705,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x2, /* gcFEATURE_VALUE_CoreCount */
         0x30, /* gcFEATURE_VALUE_LocalStorageSize */
         0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
@@ -57202,7 +58742,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -57438,7 +58978,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -57525,9 +59065,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
         0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
         0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
@@ -57573,6 +59113,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -57668,28 +59211,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000L_6210 */
+    /* gc7000XS_6210 */
     {
         0x7000, /* ChipID */
         0x6210, /* ChipRevision */
-        0x70002, /* ProductID */
+        0x70004, /* ProductID */
         0x0, /* EcoID */
-        0x5, /* CustomerID */
+        0xc, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x400, /* gcFEATURE_VALUE_ThreadCount */
-        0x4, /* gcFEATURE_VALUE_NumShaderCores */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
@@ -57721,7 +59275,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -57855,7 +59409,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -57925,7 +59479,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -57968,11 +59522,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
         0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -57983,7 +59537,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -58037,17 +59591,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
         0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
         0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
-        0x1, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
-        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
-        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
-        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
@@ -58068,7 +59622,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
-        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x1, /* gcFEATURE_BIT_FENCE_64BIT */
         0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
@@ -58092,6 +59646,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -58187,6 +59744,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000L_6210 */
     {
@@ -58194,7 +59762,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x6210, /* ChipRevision */
         0x70002, /* ProductID */
         0x0, /* EcoID */
-        0x9, /* CustomerID */
+        0x5, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -58240,7 +59808,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -58556,16 +60124,16 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
         0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
         0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
-        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
-        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
-        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
-        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
         0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
@@ -58587,7 +60155,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
-        0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x1, /* gcFEATURE_BIT_FENCE_64BIT */
         0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
@@ -58611,6 +60179,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -58706,14 +60277,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000LXS_6210 */
+    /* gc7000L_6210 */
     {
         0x7000, /* ChipID */
         0x6210, /* ChipRevision */
-        0x7000a, /* ProductID */
+        0x70002, /* ProductID */
         0x0, /* EcoID */
-        0x0, /* CustomerID */
+        0x9, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -58723,11 +60305,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
         0x8, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
@@ -58759,7 +60341,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -58893,7 +60475,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -58963,7 +60545,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -59006,11 +60588,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
         0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x0, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -59021,7 +60603,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -59084,7 +60666,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
         0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
         0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
@@ -59130,6 +60712,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -59225,28 +60810,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000XSVX_6210 */
+    /* gc7000LXS_6210 */
     {
         0x7000, /* ChipID */
         0x6210, /* ChipRevision */
-        0x70008, /* ProductID */
+        0x7000a, /* ProductID */
         0x0, /* EcoID */
-        0x7, /* CustomerID */
+        0x0, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x800, /* gcFEATURE_VALUE_ThreadCount */
-        0x8, /* gcFEATURE_VALUE_NumShaderCores */
+        0x400, /* gcFEATURE_VALUE_ThreadCount */
+        0x4, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
@@ -59278,7 +60874,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -59502,7 +61098,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_RSS8 */
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
-        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_Evis */
         0x1, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
@@ -59604,7 +61200,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
         0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
@@ -59649,6 +61245,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -59744,6 +61343,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* gc7000XSVX_6210 */
     {
@@ -59751,7 +61361,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x6210, /* ChipRevision */
         0x70008, /* ProductID */
         0x0, /* EcoID */
-        0xb, /* CustomerID */
+        0x7, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -59797,7 +61407,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -60122,7 +61732,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
         0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
         0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
@@ -60168,6 +61778,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -60263,28 +61876,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000L_DEC400 */
+    /* gc7000XSVX_6210 */
     {
         0x7000, /* ChipID */
-        0x6214, /* ChipRevision */
-        0x70002, /* ProductID */
+        0x6210, /* ChipRevision */
+        0x70008, /* ProductID */
         0x0, /* EcoID */
-        0x30, /* CustomerID */
-        0x8, /* PatchVersion */
+        0xb, /* CustomerID */
+        0x0, /* PatchVersion */
         "", /* ProductName */
-        0x1, /* FormalRelease */
+        0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x400, /* gcFEATURE_VALUE_ThreadCount */
-        0x4, /* gcFEATURE_VALUE_NumShaderCores */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
@@ -60316,7 +61940,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -60450,7 +62074,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -60520,7 +62144,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -60540,7 +62164,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_RSS8 */
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
-        0x0, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
         0x1, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
@@ -60563,11 +62187,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
         0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -60578,7 +62202,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -60642,9 +62266,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
         0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
-        0x1, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
@@ -60652,7 +62276,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
-        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
@@ -60687,6 +62311,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -60782,28 +62409,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7000L_DEC400 */
+    /* gc7000XSVX */
     {
         0x7000, /* ChipID */
-        0x6214, /* ChipRevision */
-        0x70002, /* ProductID */
-        0x1, /* EcoID */
-        0x30, /* CustomerID */
-        0x8, /* PatchVersion */
+        0x6212, /* ChipRevision */
+        0x70008, /* ProductID */
+        0x0, /* EcoID */
+        0x14, /* CustomerID */
+        0x0, /* PatchVersion */
         "", /* ProductName */
-        0x1, /* FormalRelease */
+        0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x400, /* gcFEATURE_VALUE_ThreadCount */
-        0x4, /* gcFEATURE_VALUE_NumShaderCores */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
@@ -60835,7 +62473,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -60969,7 +62607,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -61039,7 +62677,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -61059,7 +62697,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_RSS8 */
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
-        0x0, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
         0x1, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
@@ -61082,11 +62720,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
         0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -61097,7 +62735,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -61161,9 +62799,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
         0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
-        0x1, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
@@ -61171,15 +62809,15 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
-        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
-        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x1, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
         0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
-        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x1, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
-        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
@@ -61192,20 +62830,23 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
-        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
-        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
-        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x1, /* gcFEATURE_BIT_PE_A8B8G8R8 */
         0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
-        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
-        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
-        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
-        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
-        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x1, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x1, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x1, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x1, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -61301,32 +62942,43 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7400_0002 */
+    /* gc7000L_DEC400 */
     {
-        0x8400, /* ChipID */
-        0x6310, /* ChipRevision */
-        0x8400a, /* ProductID */
+        0x7000, /* ChipID */
+        0x6214, /* ChipRevision */
+        0x70002, /* ProductID */
         0x0, /* EcoID */
-        0x44, /* CustomerID */
-        0x0, /* PatchVersion */
+        0x30, /* CustomerID */
+        0x8, /* PatchVersion */
         "", /* ProductName */
-        0x0, /* FormalRelease */
+        0x1, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x800, /* gcFEATURE_VALUE_ThreadCount */
-        0x8, /* gcFEATURE_VALUE_NumShaderCores */
+        0x400, /* gcFEATURE_VALUE_ThreadCount */
+        0x4, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
-        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
@@ -61354,7 +63006,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -61488,7 +63140,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -61558,7 +63210,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -61590,7 +63242,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x1, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -61601,11 +63253,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
         0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x0, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -61616,7 +63268,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -61633,7 +63285,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
         0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
         0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
-        0x0, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_SECURITY */
         0x1, /* gcFEATURE_BIT_ROBUSTNESS */
         0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
         0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
@@ -61646,7 +63298,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_DRAWID */
         0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
         0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
-        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
         0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
         0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
         0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
@@ -61672,7 +63324,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
@@ -61680,17 +63332,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
         0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
-        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x1, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
-        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
-        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
@@ -61701,7 +63353,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
-        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x1, /* gcFEATURE_BIT_FENCE_64BIT */
         0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
@@ -61725,6 +63377,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -61820,32 +63475,43 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc7400_0003 */
+    /* gc7000L_DEC400 */
     {
-        0x8400, /* ChipID */
-        0x6310, /* ChipRevision */
-        0x8400a, /* ProductID */
-        0x0, /* EcoID */
-        0x45, /* CustomerID */
-        0x0, /* PatchVersion */
+        0x7000, /* ChipID */
+        0x6214, /* ChipRevision */
+        0x70002, /* ProductID */
+        0x1, /* EcoID */
+        0x30, /* CustomerID */
+        0x8, /* PatchVersion */
         "", /* ProductName */
-        0x0, /* FormalRelease */
+        0x1, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
         0x400, /* gcFEATURE_VALUE_ThreadCount */
         0x4, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
         0x8, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
-        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
@@ -61873,7 +63539,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -62007,7 +63673,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_OclOnly */
         0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
-        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
         0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
@@ -62077,7 +63743,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
         0x1, /* gcFEATURE_BIT_REG_Halti3 */
-        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
         0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
         0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
         0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
@@ -62109,7 +63775,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x1, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -62120,11 +63786,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
         0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x0, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -62135,7 +63801,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -62152,7 +63818,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
         0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
         0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
-        0x0, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_SECURITY */
         0x1, /* gcFEATURE_BIT_ROBUSTNESS */
         0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
         0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
@@ -62165,7 +63831,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_DRAWID */
         0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
         0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
-        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
         0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
         0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
         0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
@@ -62191,7 +63857,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
@@ -62199,17 +63865,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
         0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
-        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x1, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
-        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
-        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
@@ -62220,7 +63886,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
-        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x1, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x1, /* gcFEATURE_BIT_FENCE_64BIT */
         0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
@@ -62235,7 +63901,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
-        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
         0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
         0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
         0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
@@ -62244,6 +63910,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -62339,39 +64008,50 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc8400_6300 */
+    /* gc7400_0002 */
     {
         0x8400, /* ChipID */
-        0x6300, /* ChipRevision */
-        0x84004, /* ProductID */
+        0x6310, /* ChipRevision */
+        0x8400a, /* ProductID */
         0x0, /* EcoID */
-        0x41, /* CustomerID */
+        0x44, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
         0x800, /* gcFEATURE_VALUE_ThreadCount */
-        0x10, /* gcFEATURE_VALUE_NumShaderCores */
+        0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x40, /* gcFEATURE_VALUE_L1CacheSize */
+        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
-        0x10, /* gcFEATURE_VALUE_Streams */
+        0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
         0x10, /* gcFEATURE_VALUE_VertexCacheSize */
         0x1, /* gcFEATURE_VALUE_NumResolvePipes */
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
-        0xf, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x0, /* gcFEATURE_VALUE_NNMadPerCore */
         0x0, /* gcFEATURE_VALUE_NNCoreCount */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
@@ -62392,7 +64072,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -62528,7 +64208,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
         0x1, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
-        0x0, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
         0x0, /* gcFEATURE_BIT_REG_FastMSAA */
         0x0, /* gcFEATURE_BIT_REG_WClip */
@@ -62616,7 +64296,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_RSS8 */
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
-        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_Evis */
         0x1, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
@@ -62628,7 +64308,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -62671,7 +64351,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
         0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
         0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
-        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x0, /* gcFEATURE_BIT_SECURITY */
         0x1, /* gcFEATURE_BIT_ROBUSTNESS */
         0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
         0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
@@ -62684,7 +64364,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_DRAWID */
         0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
         0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
-        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
         0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
         0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
         0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
@@ -62701,7 +64381,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
-        0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
         0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
         0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
@@ -62710,7 +64390,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
@@ -62722,11 +64402,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
-        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
-        0x1, /* gcFEATURE_BIT_SMALLBATCH */
+        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
@@ -62753,16 +64433,19 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
         0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
-        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
-        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
         0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
         0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
         0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
         0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
-        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -62858,39 +64541,50 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc8100_6300_pid0x43 */
+    /* gc7400_0003 */
     {
-        0x8100, /* ChipID */
-        0x6300, /* ChipRevision */
-        0x81004, /* ProductID */
+        0x8400, /* ChipID */
+        0x6310, /* ChipRevision */
+        0x8400a, /* ProductID */
         0x0, /* EcoID */
-        0x43, /* CustomerID */
+        0x45, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x800, /* gcFEATURE_VALUE_ThreadCount */
-        0x10, /* gcFEATURE_VALUE_NumShaderCores */
+        0x400, /* gcFEATURE_VALUE_ThreadCount */
+        0x4, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x40, /* gcFEATURE_VALUE_L1CacheSize */
+        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
-        0x10, /* gcFEATURE_VALUE_Streams */
+        0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
         0x10, /* gcFEATURE_VALUE_VertexCacheSize */
         0x1, /* gcFEATURE_VALUE_NumResolvePipes */
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
-        0x1, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x0, /* gcFEATURE_VALUE_NNMadPerCore */
         0x0, /* gcFEATURE_VALUE_NNCoreCount */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
@@ -62911,7 +64605,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -63047,7 +64741,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
         0x1, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
-        0x0, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
         0x0, /* gcFEATURE_BIT_REG_FastMSAA */
         0x0, /* gcFEATURE_BIT_REG_WClip */
@@ -63135,7 +64829,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_RSS8 */
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
-        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_Evis */
         0x1, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
@@ -63147,7 +64841,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -63190,7 +64884,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
         0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
         0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
-        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x0, /* gcFEATURE_BIT_SECURITY */
         0x1, /* gcFEATURE_BIT_ROBUSTNESS */
         0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
         0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
@@ -63203,7 +64897,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_DRAWID */
         0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
         0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
-        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
         0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
         0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
         0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
@@ -63220,7 +64914,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
-        0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
         0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
         0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
         0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
@@ -63229,7 +64923,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
         0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
@@ -63241,11 +64935,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
-        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
-        0x1, /* gcFEATURE_BIT_SMALLBATCH */
+        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
@@ -63272,16 +64966,19 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
         0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
-        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
-        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
         0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
         0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
         0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
         0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
-        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -63377,39 +65074,50 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gc8200_6300_pid0x46 */
+    /* gc7403_0002 */
     {
-        0x8200, /* ChipID */
-        0x6300, /* ChipRevision */
-        0x82004, /* ProductID */
+        0x8400, /* ChipID */
+        0x6310, /* ChipRevision */
+        0x8400b, /* ProductID */
         0x0, /* EcoID */
-        0x46, /* CustomerID */
+        0x48, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
         0x800, /* gcFEATURE_VALUE_ThreadCount */
-        0x10, /* gcFEATURE_VALUE_NumShaderCores */
+        0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x40, /* gcFEATURE_VALUE_L1CacheSize */
+        0x30, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x30, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x0, /* gcFEATURE_VALUE_USC_BANKS */
-        0x10, /* gcFEATURE_VALUE_Streams */
+        0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
         0x10, /* gcFEATURE_VALUE_VertexCacheSize */
         0x1, /* gcFEATURE_VALUE_NumResolvePipes */
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
-        0x3, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x0, /* gcFEATURE_VALUE_NNMadPerCore */
         0x0, /* gcFEATURE_VALUE_NNCoreCount */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
@@ -63430,7 +65138,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
         0x1, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
@@ -63566,7 +65274,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_InstructionCache */
         0x1, /* gcFEATURE_BIT_REG_GeometryShader */
         0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
-        0x0, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
         0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
         0x0, /* gcFEATURE_BIT_REG_FastMSAA */
         0x0, /* gcFEATURE_BIT_REG_WClip */
@@ -63666,6 +65374,8001 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x0, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x1, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* gc8400_6300 */
+    {
+        0x8400, /* ChipID */
+        0x6300, /* ChipRevision */
+        0x84004, /* ProductID */
+        0x0, /* EcoID */
+        0x41, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x10, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x40, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x0, /* gcFEATURE_VALUE_USC_BANKS */
+        0x10, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0xf, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x0, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x0, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x1, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* cc8400_6302 */
+    {
+        0x8400, /* ChipID */
+        0x6302, /* ChipRevision */
+        0x6084000, /* ProductID */
+        0x0, /* EcoID */
+        0x52, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x10, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x40, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x0, /* gcFEATURE_VALUE_USC_BANKS */
+        0x10, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0xf, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x0, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x1, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x0, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x1, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* gc8100_6300_pid0x43 */
+    {
+        0x8100, /* ChipID */
+        0x6300, /* ChipRevision */
+        0x81004, /* ProductID */
+        0x0, /* EcoID */
+        0x43, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x10, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x40, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x0, /* gcFEATURE_VALUE_USC_BANKS */
+        0x10, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x1, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x0, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x0, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x1, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* gc8100_6300_pid0x47 */
+    {
+        0x8100, /* ChipID */
+        0x6302, /* ChipRevision */
+        0x81004, /* ProductID */
+        0x0, /* EcoID */
+        0x47, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x10, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x40, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x0, /* gcFEATURE_VALUE_USC_BANKS */
+        0x10, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x1, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x0, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x0, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x1, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* gc8200_6300_pid0x46 */
+    {
+        0x8200, /* ChipID */
+        0x6300, /* ChipRevision */
+        0x82004, /* ProductID */
+        0x0, /* EcoID */
+        0x46, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x10, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x40, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x0, /* gcFEATURE_VALUE_USC_BANKS */
+        0x10, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x3, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x0, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x0, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x1, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x0, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x1, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x1, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* cc8000_6330 */
+    {
+        0x8000, /* ChipID */
+        0x6330, /* ChipRevision */
+        0x6080000, /* ProductID */
+        0x0, /* EcoID */
+        0x51, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x8, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x0, /* gcFEATURE_VALUE_USC_BANKS */
+        0x10, /* gcFEATURE_VALUE_Streams */
+        0x1f, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x0, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x0, /* gcFEATURE_BIT_REG_Evis */
+        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x1, /* gcFEATURE_BIT_SH_CMPLX */
+        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x1, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x1, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x1, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* vip7000UL_6100 */
+    {
+        0x7000, /* ChipID */
+        0x6100, /* ChipRevision */
+        0x5070003, /* ProductID */
+        0x0, /* EcoID */
+        0x0, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x1, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x0, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x0, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x0, /* gcFEATURE_BIT_SECURITY */
+        0x0, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* vip7000L_6200 */
+    {
+        0x7000, /* ChipID */
+        0x6200, /* ChipRevision */
+        0x5070002, /* ProductID */
+        0x0, /* EcoID */
+        0x0, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x400, /* gcFEATURE_VALUE_ThreadCount */
+        0x4, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* vip7000UL_6200 */
+    {
+        0x7000, /* ChipID */
+        0x6201, /* ChipRevision */
+        0x5070003, /* ProductID */
+        0x0, /* EcoID */
+        0x0, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x1, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x0, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* vip8000UL_6211 */
+    {
+        0x8000, /* ChipID */
+        0x6212, /* ChipRevision */
+        0x5080003, /* ProductID */
+        0x0, /* EcoID */
+        0x21, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* vip8000ULFN_6211 */
+    {
+        0x8000, /* ChipID */
+        0x6211, /* ChipRevision */
+        0x5080003, /* ProductID */
+        0x0, /* EcoID */
+        0x22, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* vip8000UL_6211 */
+    {
+        0x8000, /* ChipID */
+        0x6211, /* ChipRevision */
+        0x5080003, /* ProductID */
+        0x0, /* EcoID */
+        0x0, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* vipnano */
+    {
+        0x8000, /* ChipID */
+        0x7000, /* ChipRevision */
+        0x5080001, /* ProductID */
+        0x0, /* EcoID */
+        0x29, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* gcnanovip */
+    {
+        0x8000, /* ChipID */
+        0x7000, /* ChipRevision */
+        0x424f5343, /* ProductID */
+        0x0, /* EcoID */
+        0x0, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
+        0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
+        0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_NEW_GPIPE */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
+        0x0, /* gcFEATURE_BIT_NO_DXT */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
+        0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
+        0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
+        0x1, /* gcFEATURE_BIT_DRAWID */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
+        0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
+        0x0, /* gcFEATURE_BIT_PE2D_SEPARATE_CACHE */
+        0x1, /* gcFEATURE_BIT_PE_MSAA_OQ_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_MSAA_CL_FIX */
+        0x1, /* gcFEATURE_BIT_USC_DEFER_FILL_FIX */
+        0x1, /* gcFEATURE_BIT_SH_CLOCK_GATE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
+        0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
+        0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x1, /* gcFEATURE_BIT_RA_CG_FIX */
+        0x0, /* gcFEATURE_BIT_DEC400 */
+        0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
+        0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
+        0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
+        0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
+        0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
+        0x0, /* gcFEATURE_BIT_FENCE_32BIT */
+        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
+        0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
+        0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
+        0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
+        0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
+        0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
+        0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
+        0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
+        0x0, /* gcFEATURE_BIT_VG_FP25 */
+        0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
+        0x0, /* gcFEATURE_BIT_VG_DOUBLE_IMAGE */
+        0x0, /* gcFEATURE_BIT_VG_RECTANGLE_STRIPE_MODE */
+        0x0, /* gcFEATURE_BIT_VG_MMU */
+        0x0, /* gcFEATURE_BIT_VG_IM_FILTER */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_IM_YUV_PLANAR */
+        0x0, /* gcFEATURE_BIT_VG_PE_YUV_PACKET */
+        0x0, /* gcFEATURE_BIT_VG_COLOR_PRECISION_8_BIT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLVE_ENGINE */
+        0x0, /* gcFEATURE_BIT_VG_PE_COLOR_KEY */
+        0x0, /* gcFEATURE_BIT_VG_IM_INDEX_FORMAT */
+        0x0, /* gcFEATURE_BIT_VG_RESOLUTION_8K */
+        0x0, /* gcFEATURE_BIT_VG_IMAGE_16K */
+        0x0, /* gcFEATURE_BIT_VG_FORMAT_ARGB2222 */
+        0x0, /* gcFEATURE_BIT_G2D_DEC400 */
+        0x0, /* gcFEATURE_BIT_DC_OVERLAY_SCALING */
+        0x0, /* gcFEATURE_BIT_DC_SOURCE_ROTATION */
+        0x0, /* gcFEATURE_BIT_DC_TILED */
+        0x0, /* gcFEATURE_BIT_DC_YUV_L1 */
+        0x0, /* gcFEATURE_BIT_DC_D30_OUTPUT */
+        0x0, /* gcFEATURE_BIT_DC_MMU */
+        0x0, /* gcFEATURE_BIT_DC_COMPRESSION */
+        0x0, /* gcFEATURE_BIT_DC_QOS */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_ABSDIFF */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BITREPLACE */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_BOXFILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_CORDIAC */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_DP32 */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_FILTER */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_IADD */
+        0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
+        0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
+        0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
+        0x0, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x0, /* gcFEATURE_BIT_TP_LRN */
+        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x0, /* gcFEATURE_BIT_NN_ZDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP9 */
+        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
+        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_INPUT_4BIT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
+        0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
+        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
+        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
+    },
+    /* vipnano-q */
+    {
+        0x8000, /* ChipID */
+        0x7100, /* ChipRevision */
+        0x45080001, /* ProductID */
+        0x0, /* EcoID */
+        0x24, /* CustomerID */
+        0x0, /* PatchVersion */
+        "", /* ProductName */
+        0x0, /* FormalRelease */
+        0x40, /* gcFEATURE_VALUE_TempRegisters */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_InstructionCount */
+        0x140, /* gcFEATURE_VALUE_NumberOfConstants */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
+        0x14, /* gcFEATURE_VALUE_ShaderPCLength */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
+        0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
+        0x0, /* gcFEATURE_VALUE_BufferSize */
+        0x10, /* gcFEATURE_VALUE_VertexCacheSize */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
+        0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x10, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
+        0x1, /* gcFEATURE_BIT_REG_Pipe3D */
+        0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
+        0x0, /* gcFEATURE_BIT_REG_DebugMode */
+        0x1, /* gcFEATURE_BIT_REG_ZCompression */
+        0x0, /* gcFEATURE_BIT_REG_YUV420Filter */
+        0x1, /* gcFEATURE_BIT_REG_MSAA */
+        0x0, /* gcFEATURE_BIT_REG_DC */
+        0x0, /* gcFEATURE_BIT_REG_Pipe2D */
+        0x1, /* gcFEATURE_BIT_REG_ETC1TextureCompression */
+        0x1, /* gcFEATURE_BIT_REG_FastScaler */
+        0x1, /* gcFEATURE_BIT_REG_HighDynamicRange */
+        0x1, /* gcFEATURE_BIT_REG_YUV420Tiler */
+        0x1, /* gcFEATURE_BIT_REG_ModuleCG */
+        0x0, /* gcFEATURE_BIT_REG_MinArea */
+        0x0, /* gcFEATURE_BIT_REG_NoEZ */
+        0x0, /* gcFEATURE_BIT_REG_No422Texture */
+        0x0, /* gcFEATURE_BIT_REG_BufferInterleaving */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite2D */
+        0x0, /* gcFEATURE_BIT_REG_NoScaler */
+        0x1, /* gcFEATURE_BIT_REG_YUY2Averaging */
+        0x0, /* gcFEATURE_BIT_REG_HalfPECache */
+        0x0, /* gcFEATURE_BIT_REG_HalfTXCache */
+        0x0, /* gcFEATURE_BIT_REG_YUY2RenderTarget */
+        0x0, /* gcFEATURE_BIT_REG_Mem32BitSupport */
+        0x0, /* gcFEATURE_BIT_REG_PipeVG */
+        0x0, /* gcFEATURE_BIT_REG_VGTS */
+        0x0, /* gcFEATURE_BIT_REG_FE20 */
+        0x1, /* gcFEATURE_BIT_REG_ByteWrite3D */
+        0x1, /* gcFEATURE_BIT_REG_RsYuvTarget */
+        0x1, /* gcFEATURE_BIT_REG_FE20BitIndex */
+        0x1, /* gcFEATURE_BIT_REG_FlipY */
+        0x1, /* gcFEATURE_BIT_REG_DualReturnBus */
+        0x1, /* gcFEATURE_BIT_REG_EndiannessConfig */
+        0x1, /* gcFEATURE_BIT_REG_Texture8K */
+        0x1, /* gcFEATURE_BIT_REG_CorrectTextureConverter */
+        0x1, /* gcFEATURE_BIT_REG_SpecialMsaaLod */
+        0x1, /* gcFEATURE_BIT_REG_FastClearFlush */
+        0x1, /* gcFEATURE_BIT_REG_2DPE20 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectAutoDisable */
+        0x1, /* gcFEATURE_BIT_REG_Render8K */
+        0x1, /* gcFEATURE_BIT_REG_TileStatus2Bits */
+        0x1, /* gcFEATURE_BIT_REG_SeparateTileStatusWhenInterleaved */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiled32x32 */
+        0x0, /* gcFEATURE_BIT_REG_VG20 */
+        0x0, /* gcFEATURE_BIT_REG_TSExtendedCommands */
+        0x1, /* gcFEATURE_BIT_REG_CompressionFifoFixed */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions0 */
+        0x0, /* gcFEATURE_BIT_REG_VGFilter */
+        0x0, /* gcFEATURE_BIT_REG_VG21 */
+        0x1, /* gcFEATURE_BIT_REG_ShaderGetsW */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions1 */
+        0x1, /* gcFEATURE_BIT_REG_DefaultReg0 */
+        0x1, /* gcFEATURE_BIT_REG_MC20 */
+        0x0, /* gcFEATURE_BIT_REG_ShaderMSAASideband */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes0 */
+        0x0, /* gcFEATURE_BIT_REG_VAA */
+        0x0, /* gcFEATURE_BIT_REG_BypassInMSAA */
+        0x0, /* gcFEATURE_BIT_REG_HierarchicalZ */
+        0x0, /* gcFEATURE_BIT_REG_NewTexture */
+        0x0, /* gcFEATURE_BIT_REG_A8TargetSupport */
+        0x1, /* gcFEATURE_BIT_REG_CorrectStencil */
+        0x1, /* gcFEATURE_BIT_REG_EnhanceVR */
+        0x1, /* gcFEATURE_BIT_REG_RSUVSwizzle */
+        0x1, /* gcFEATURE_BIT_REG_V2Compression */
+        0x0, /* gcFEATURE_BIT_REG_VGDoubleBuffer */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes1 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes2 */
+        0x0, /* gcFEATURE_BIT_REG_TextureStride */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes3 */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisable1 */
+        0x0, /* gcFEATURE_BIT_REG_AutoRestartTS */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes4 */
+        0x0, /* gcFEATURE_BIT_REG_L2Windowing */
+        0x1, /* gcFEATURE_BIT_REG_HalfFloatPipe */
+        0x1, /* gcFEATURE_BIT_REG_PixelDither */
+        0x1, /* gcFEATURE_BIT_REG_TwoStencilReference */
+        0x1, /* gcFEATURE_BIT_REG_ExtendedPixelFormat */
+        0x1, /* gcFEATURE_BIT_REG_CorrectMinMaxDepth */
+        0x1, /* gcFEATURE_BIT_REG_DitherAndFilterPlusAlpha2D */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes5 */
+        0x0, /* gcFEATURE_BIT_REG_New2D */
+        0x1, /* gcFEATURE_BIT_REG_NewFloatingPointArithmetic */
+        0x1, /* gcFEATURE_BIT_REG_TextureHorizontalAlignmentSelect */
+        0x1, /* gcFEATURE_BIT_REG_NonPowerOfTwo */
+        0x1, /* gcFEATURE_BIT_REG_LinearTextureSupport */
+        0x1, /* gcFEATURE_BIT_REG_Halti0 */
+        0x0, /* gcFEATURE_BIT_REG_CorrectOverflowVG */
+        0x1, /* gcFEATURE_BIT_REG_NegativeLogFix */
+        0x1, /* gcFEATURE_BIT_REG_ResolveOffset */
+        0x1, /* gcFEATURE_BIT_REG_OkToGateAxiClock */
+        0x1, /* gcFEATURE_BIT_REG_MMU */
+        0x1, /* gcFEATURE_BIT_REG_WideLine */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes6 */
+        0x1, /* gcFEATURE_BIT_REG_FcFlushStall */
+        0x1, /* gcFEATURE_BIT_REG_LineLoop */
+        0x1, /* gcFEATURE_BIT_REG_LogicOp */
+        0x1, /* gcFEATURE_BIT_REG_SeamlessCubeMap */
+        0x1, /* gcFEATURE_BIT_REG_SuperTiledTexture */
+        0x1, /* gcFEATURE_BIT_REG_LinearPE */
+        0x1, /* gcFEATURE_BIT_REG_RectPrimitive */
+        0x0, /* gcFEATURE_BIT_REG_Composition */
+        0x1, /* gcFEATURE_BIT_REG_CorrectAutoDisableCountWidth */
+        0x1, /* gcFEATURE_BIT_REG_PESwizzle */
+        0x1, /* gcFEATURE_BIT_REG_EndEvent */
+        0x1, /* gcFEATURE_BIT_REG_S1S8 */
+        0x1, /* gcFEATURE_BIT_REG_Halti1 */
+        0x0, /* gcFEATURE_BIT_REG_RGB888 */
+        0x1, /* gcFEATURE_BIT_REG_TX_YUVAssembler */
+        0x1, /* gcFEATURE_BIT_REG_DynamicFrequencyScaling */
+        0x0, /* gcFEATURE_BIT_REG_TXFilter */
+        0x1, /* gcFEATURE_BIT_REG_FullDirectFB */
+        0x0, /* gcFEATURE_BIT_REG_OnePass2DFilter */
+        0x1, /* gcFEATURE_BIT_REG_ThreadWalkerInPS */
+        0x1, /* gcFEATURE_BIT_REG_TileFiller */
+        0x1, /* gcFEATURE_BIT_REG_YUVStandard */
+        0x0, /* gcFEATURE_BIT_REG_MultiSourceBlt */
+        0x0, /* gcFEATURE_BIT_REG_YUVConversion */
+        0x1, /* gcFEATURE_BIT_REG_FlushFixed2D */
+        0x1, /* gcFEATURE_BIT_REG_Interleaver */
+        0x1, /* gcFEATURE_BIT_REG_MixedStreams */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheFor2D420 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes7 */
+        0x0, /* gcFEATURE_BIT_REG_NoIndexPattern */
+        0x1, /* gcFEATURE_BIT_REG_TextureTileStatus */
+        0x1, /* gcFEATURE_BIT_REG_DecompressZ16 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes8 */
+        0x1, /* gcFEATURE_BIT_REG_DERotationStallFix */
+        0x0, /* gcFEATURE_BIT_REG_OclOnly */
+        0x1, /* gcFEATURE_BIT_REG_NewFeatures0 */
+        0x1, /* gcFEATURE_BIT_REG_InstructionCache */
+        0x0, /* gcFEATURE_BIT_REG_GeometryShader */
+        0x1, /* gcFEATURE_BIT_REG_TexCompressionSupertiled */
+        0x1, /* gcFEATURE_BIT_REG_Generics */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes9 */
+        0x0, /* gcFEATURE_BIT_REG_FastMSAA */
+        0x0, /* gcFEATURE_BIT_REG_WClip */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes10 */
+        0x1, /* gcFEATURE_BIT_REG_UnifiedSamplers */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes11 */
+        0x1, /* gcFEATURE_BIT_REG_PerformanceCounters */
+        0x1, /* gcFEATURE_BIT_REG_ExtraShaderInstructions2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes12 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes13 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_ACE */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_DEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes14 */
+        0x0, /* gcFEATURE_BIT_REG_PowerOptimizations0 */
+        0x1, /* gcFEATURE_BIT_REG_NewHZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes15 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements1 */
+        0x0, /* gcFEATURE_BIT_REG_DENoGamma */
+        0x0, /* gcFEATURE_BIT_REG_PAEnhancements2 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_PEEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_HIEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_FEEnhancements2 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes16 */
+        0x0, /* gcFEATURE_BIT_REG_DEEnhancements5 */
+        0x1, /* gcFEATURE_BIT_REG_TXEnhancements4 */
+        0x0, /* gcFEATURE_BIT_REG_PEEnhancements4 */
+        0x1, /* gcFEATURE_BIT_REG_MCEnhancements1 */
+        0x1, /* gcFEATURE_BIT_REG_Halti2 */
+        0x0, /* gcFEATURE_BIT_REG_DEMirrorRotate */
+        0x1, /* gcFEATURE_BIT_REG_SmallMSAA */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes17 */
+        0x0, /* gcFEATURE_BIT_REG_Rasterizer2 */
+        0x0, /* gcFEATURE_BIT_REG_DualPipeOPF */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2 */
+        0x0, /* gcFEATURE_BIT_REG_CSCV2 */
+        0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
+        0x0, /* gcFEATURE_BIT_REG_Compression2D */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
+        0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
+        0x0, /* gcFEATURE_BIT_REG_DESupertile */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements6 */
+        0x1, /* gcFEATURE_BIT_REG_SHEnhancements7 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes20 */
+        0x0, /* gcFEATURE_BIT_REG_DEAddress40 */
+        0x0, /* gcFEATURE_BIT_REG_MiniMMUFix */
+        0x1, /* gcFEATURE_BIT_REG_EEZ */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes21 */
+        0x0, /* gcFEATURE_BIT_REG_ExtraVgCaps */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV15 */
+        0x1, /* gcFEATURE_BIT_REG_BugFixes22 */
+        0x1, /* gcFEATURE_BIT_REG_Halti3 */
+        0x0, /* gcFEATURE_BIT_REG_TessellationShaders */
+        0x0, /* gcFEATURE_BIT_REG_OPF9Tap */
+        0x0, /* gcFEATURE_BIT_REG_MultiSrcV2StrQuad */
+        0x0, /* gcFEATURE_BIT_REG_SeperateSRCAndDstCache */
+        0x1, /* gcFEATURE_BIT_REG_Halti4 */
+        0x1, /* gcFEATURE_BIT_REG_RAWriteDepth */
+        0x0, /* gcFEATURE_BIT_REG_AndroidOnly */
+        0x1, /* gcFEATURE_BIT_REG_HasChipProductReg */
+        0x0, /* gcFEATURE_BIT_REG_TXSupportDEC */
+        0x1, /* gcFEATURE_BIT_REG_S8MSAACompression */
+        0x1, /* gcFEATURE_BIT_REG_BugFixesIn544 */
+        0x0, /* gcFEATURE_BIT_REG_L2CacheRemove */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowRndVtxCnt */
+        0x0, /* gcFEATURE_BIT_REG_CubeMapFL28 */
+        0x1, /* gcFEATURE_BIT_REG_TX6bitFrac */
+        0x1, /* gcFEATURE_BIT_REG_FEAllowStallPrefetchEng */
+        0x0, /* gcFEATURE_BIT_REG_ThirdPartyCompression */
+        0x1, /* gcFEATURE_BIT_REG_RSS8 */
+        0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
+        0x1, /* gcFEATURE_BIT_REG_Halti5 */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
+        0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
+        0x0, /* gcFEATURE_BIT_REG_DEC */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12 */
+        0x0, /* gcFEATURE_BIT_REG_VSTileNV12_10BIT */
+        0x0, /* gcFEATURE_BIT_RenderTarget8 */
+        0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
+        0x0, /* gcFEATURE_BIT_FaceLod */
+        0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
+        0x1, /* gcFEATURE_BIT_VMSAA */
         0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
@@ -63677,11 +73380,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
         0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x1, /* gcFEATURE_BIT_HWTFB */
+        0x0, /* gcFEATURE_BIT_HWTFB */
         0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
         0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
@@ -63692,7 +73395,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
         0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
         0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
         0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
@@ -63706,7 +73409,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
         0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
-        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
         0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
         0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY */
@@ -63723,11 +73426,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
         0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
-        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
         0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
         0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
         0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
-        0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
         0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
         0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
         0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
@@ -63739,24 +73442,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FE_NEED_DUMMYDRAW */
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_OUTPUT */
         0x0, /* gcFEATURE_BIT_PE2D_LINEAR_YUV420_10BIT */
-        0x1, /* gcFEATURE_BIT_MULTI_CLUSTER */
-        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
-        0x1, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
-        0x1, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
-        0x1, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
-        0x1, /* gcFEATURE_BIT_FE_ROBUST_FIX */
-        0x1, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
+        0x0, /* gcFEATURE_BIT_MULTI_CLUSTER */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK */
+        0x0, /* gcFEATURE_BIT_SH_DUAL16_SAMPLEMASK_ZW */
+        0x0, /* gcFEATURE_BIT_TPG_TRIVIAL_MODE_FIX */
+        0x0, /* gcFEATURE_BIT_TX_ASTC_MULTISLICE_FIX */
+        0x0, /* gcFEATURE_BIT_FE_ROBUST_FIX */
+        0x0, /* gcFEATURE_BIT_SH_GPIPE_ACCESS_FULLTEMPS */
         0x0, /* gcFEATURE_BIT_PSIO_INTERLOCK */
         0x1, /* gcFEATURE_BIT_PA_WIDELINE_FIX */
-        0x1, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
+        0x0, /* gcFEATURE_BIT_WIDELINE_HELPER_FIX */
         0x0, /* gcFEATURE_BIT_G2D_3rd_PARTY_COMPRESSION_1_1 */
-        0x1, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
+        0x0, /* gcFEATURE_BIT_TX_FLUSH_L1CACHE */
         0x1, /* gcFEATURE_BIT_PE_DITHER_FIX2 */
-        0x1, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
-        0x1, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
-        0x1, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
-        0x1, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
-        0x1, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
+        0x0, /* gcFEATURE_BIT_SH_TEXLD_U_FIX */
+        0x0, /* gcFEATURE_BIT_MC_FCCACHE_BYTEMASK */
+        0x0, /* gcFEATURE_BIT_SH_MULTI_WG_PACK_FIX */
+        0x0, /* gcFEATURE_BIT_PE_ADVANCE_BLEND_PART0 */
+        0x0, /* gcFEATURE_BIT_FE_PATCHLIST_FETCH_FIX */
         0x1, /* gcFEATURE_BIT_RA_CG_FIX */
         0x0, /* gcFEATURE_BIT_DEC400 */
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
@@ -63764,7 +73467,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
-        0x1, /* gcFEATURE_BIT_SMALLBATCH */
+        0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
@@ -63779,28 +73482,31 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
-        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
-        0x1, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
-        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
-        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
         0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
-        0x1, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
-        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
+        0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
+        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
         0x0, /* gcFEATURE_BIT_PE_A8B8G8R8 */
         0x0, /* gcFEATURE_BIT_MULTIVIEW_RENDER */
         0x0, /* gcFEATURE_BIT_FE_DRAW_DIRECT */
         0x0, /* gcFEATURE_BIT_TX_VKBORDER_MODE */
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
-        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
+        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -63837,34 +73543,34 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
         0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
-        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
-        0x0, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
-        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
         0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -63876,10 +73582,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
@@ -63893,65 +73599,76 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
-        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* cc8000_6330 */
+    /* vipnano-q */
     {
         0x8000, /* ChipID */
-        0x6330, /* ChipRevision */
-        0x6080000, /* ProductID */
+        0x7100, /* ChipRevision */
+        0x45080001, /* ProductID */
         0x0, /* EcoID */
-        0x51, /* CustomerID */
+        0x82, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x800, /* gcFEATURE_VALUE_ThreadCount */
-        0x8, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x0, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
-        0x0, /* gcFEATURE_VALUE_USC_BANKS */
-        0x10, /* gcFEATURE_VALUE_Streams */
-        0x1f, /* gcFEATURE_VALUE_VaryingCount */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x8, /* gcFEATURE_VALUE_Streams */
+        0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
         0x10, /* gcFEATURE_VALUE_VertexCacheSize */
         0x0, /* gcFEATURE_VALUE_NumResolvePipes */
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
-        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0xa, /* gcFEATURE_VALUE_NNCoreCount */
+        0xa, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
-        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x0, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
-        0x0, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
-        0x0, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
+        0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -64173,8 +73890,8 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_RSS8 */
         0x1, /* gcFEATURE_BIT_REG_MSAACoherencyCheck */
         0x1, /* gcFEATURE_BIT_REG_Halti5 */
-        0x0, /* gcFEATURE_BIT_REG_Evis */
-        0x1, /* gcFEATURE_BIT_REG_BltEngine */
+        0x1, /* gcFEATURE_BIT_REG_Evis */
+        0x0, /* gcFEATURE_BIT_REG_BltEngine */
         0x0, /* gcFEATURE_BIT_REG_BugFixes23 */
         0x0, /* gcFEATURE_BIT_REG_BugFixes24 */
         0x0, /* gcFEATURE_BIT_REG_DEC */
@@ -64284,31 +74001,31 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
-        0x1, /* gcFEATURE_BIT_SH_CMPLX */
-        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
-        0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
         0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
-        0x1, /* gcFEATURE_BIT_ASYNC_BLT */
-        0x1, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
+        0x0, /* gcFEATURE_BIT_ASYNC_BLT */
+        0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
-        0x1, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
-        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
         0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
-        0x1, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
-        0x1, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
+        0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
+        0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
         0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -64320,6 +74037,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -64356,36 +74076,36 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
         0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
-        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
-        0x0, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
-        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
@@ -64395,40 +74115,51 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
-        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip7000UL_6100 */
+    /* vipnano-d */
     {
-        0x7000, /* ChipID */
-        0x6100, /* ChipRevision */
-        0x5070003, /* ProductID */
+        0x8000, /* ChipID */
+        0x7110, /* ChipRevision */
+        0x25080001, /* ProductID */
         0x0, /* EcoID */
-        0x0, /* CustomerID */
+        0x89, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x200, /* gcFEATURE_VALUE_ThreadCount */
-        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
@@ -64448,29 +74179,29 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NumResolvePipes */
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
-        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x40000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
-        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x3, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x3, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -64657,7 +74388,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_REG_PAEnhancements3 */
         0x1, /* gcFEATURE_BIT_REG_BugFixes18 */
         0x0, /* gcFEATURE_BIT_REG_Compression2D */
-        0x1, /* gcFEATURE_BIT_REG_Probe */
+        0x0, /* gcFEATURE_BIT_REG_Probe */
         0x1, /* gcFEATURE_BIT_REG_MediumPrecision */
         0x0, /* gcFEATURE_BIT_REG_DESupertile */
         0x1, /* gcFEATURE_BIT_REG_BugFixes19 */
@@ -64703,68 +74434,68 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TxLodFlowCorrection */
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
-        0x0, /* gcFEATURE_BIT_VMSAA */
+        0x1, /* gcFEATURE_BIT_VMSAA */
         0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
-        0x0, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
-        0x0, /* gcFEATURE_BIT_V4Compression */
+        0x1, /* gcFEATURE_BIT_CACHE128B256BPERLINE */
+        0x1, /* gcFEATURE_BIT_V4Compression */
         0x0, /* gcFEATURE_BIT_PE2D_MAJOR_SUPER_TILE */
-        0x0, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
-        0x0, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
+        0x1, /* gcFEATURE_BIT_PE_32BPC_COLORMASK_FIX */
+        0x1, /* gcFEATURE_BIT_ALPHA_BLENDING_OPT */
         0x1, /* gcFEATURE_BIT_NEW_GPIPE */
-        0x1, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
-        0x1, /* gcFEATURE_BIT_MSAA_SHADING */
+        0x0, /* gcFEATURE_BIT_PIPELINE_32_ATTRIBUTES */
+        0x0, /* gcFEATURE_BIT_MSAA_SHADING */
         0x0, /* gcFEATURE_BIT_NO_ANISTRO_FILTER */
-        0x0, /* gcFEATURE_BIT_NO_ASTC */
+        0x1, /* gcFEATURE_BIT_NO_ASTC */
         0x0, /* gcFEATURE_BIT_NO_DXT */
-        0x1, /* gcFEATURE_BIT_HWTFB */
-        0x0, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
-        0x0, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
-        0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
+        0x0, /* gcFEATURE_BIT_HWTFB */
+        0x1, /* gcFEATURE_BIT_RA_DEPTH_WRITE_MSAA1X_FIX */
+        0x1, /* gcFEATURE_BIT_EZHZ_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_FIX */
         0x1, /* gcFEATURE_BIT_SH_HALFDEPENDENCY_FIX */
-        0x0, /* gcFEATURE_BIT_USC_MCFILL_FIX */
-        0x0, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
-        0x0, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
-        0x0, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
-        0x0, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
+        0x1, /* gcFEATURE_BIT_USC_MCFILL_FIX */
+        0x1, /* gcFEATURE_BIT_TPG_TCPERF_FIX */
+        0x1, /* gcFEATURE_BIT_USC_MDFIFO_OVERFLOW_FIX */
+        0x1, /* gcFEATURE_BIT_SH_TEXLD_BARRIER_IN_CS_FIX */
+        0x1, /* gcFEATURE_BIT_RS_NEW_BASEADDR */
         0x1, /* gcFEATURE_BIT_PE_8bpp_DUALPIPE_FIX */
-        0x1, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
-        0x0, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
-        0x0, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
+        0x0, /* gcFEATURE_BIT_SH_ADVANCED_INSTR */
+        0x1, /* gcFEATURE_BIT_SH_FLAT_INTERPOLATION_DUAL16_FIX */
+        0x1, /* gcFEATURE_BIT_USC_CONTINUOUS_FLUS_FIX */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_V4 */
         0x0, /* gcFEATURE_BIT_SH_SUPPORT_ALPHA_KILL */
-        0x0, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
+        0x1, /* gcFEATURE_BIT_PE_NO_ALPHA_TEST */
         0x0, /* gcFEATURE_BIT_TX_LOD_NEAREST_SELECT */
-        0x0, /* gcFEATURE_BIT_SH_FIX_LDEXP */
+        0x1, /* gcFEATURE_BIT_SH_FIX_LDEXP */
         0x1, /* gcFEATURE_BIT_SUPPORT_MOVAI */
-        0x0, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
-        0x0, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
-        0x0, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
-        0x0, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
-        0x0, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
-        0x0, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
-        0x0, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
-        0x0, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
-        0x0, /* gcFEATURE_BIT_SECURITY */
-        0x0, /* gcFEATURE_BIT_ROBUSTNESS */
-        0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
-        0x0, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
+        0x1, /* gcFEATURE_BIT_SH_SNAP2PAGE_MAXPAGES_FIX */
+        0x1, /* gcFEATURE_BIT_PE_RGBA16I_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_8bpp_256TILE_FC_FIX */
+        0x1, /* gcFEATURE_BIT_PE_64bit_FENCE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_FULL_CACHE_FIX */
+        0x1, /* gcFEATURE_BIT_TX_YUV_ASSEMBLER_10BIT */
+        0x1, /* gcFEATURE_BIT_FE_32bit_INDEX_FIX */
+        0x1, /* gcFEATURE_BIT_BLT_64bpp_MASKED_CLEAR_FIX */
+        0x1, /* gcFEATURE_BIT_SECURITY */
+        0x1, /* gcFEATURE_BIT_ROBUSTNESS */
+        0x1, /* gcFEATURE_BIT_USC_ATOMIC_FIX */
+        0x1, /* gcFEATURE_BIT_SH_PSO_MSAA1x_FIX */
         0x1, /* gcFEATURE_BIT_USC_VX_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
-        0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac */
-        0x0, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
+        0x1, /* gcFEATURE_BIT_USC_GOS_ADDR_FIX */
+        0x1, /* gcFEATURE_BIT_TX_8bit_UVFrac */
+        0x1, /* gcFEATURE_BIT_TX_DESC_CACHE_CLOCKGATE_FIX */
         0x1, /* gcFEATURE_BIT_RSBLT_MSAA_DECOMPRESSION */
         0x0, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE */
         0x1, /* gcFEATURE_BIT_DRAWID */
-        0x0, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
+        0x1, /* gcFEATURE_BIT_PSIO_SAMPLEMASK_IN_R0ZW_FIX */
         0x1, /* gcFEATURE_BIT_TX_INTEGER_COORDINATE_V2 */
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG */
-        0x1, /* gcFEATURE_BIT_SNAPPAGE_CMD */
-        0x0, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
-        0x0, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
-        0x0, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
+        0x0, /* gcFEATURE_BIT_SNAPPAGE_CMD */
+        0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
+        0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
+        0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
         0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
         0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
         0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
@@ -64800,7 +74531,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_LS_SUPPORT_PERCOMP_DEPENDENCY */
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
-        0x0, /* gcFEATURE_BIT_SECURITY_AHB */
+        0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
@@ -64813,7 +74544,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
-        0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
@@ -64825,9 +74556,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
-        0x1, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
+        0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -64839,6 +74570,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -64875,35 +74609,35 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
         0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
-        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
-        0x0, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
-        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
@@ -64912,9 +74646,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
@@ -64924,7 +74658,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
@@ -64934,28 +74668,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip7000L_6200 */
+    /* vip8000UL-s */
     {
-        0x7000, /* ChipID */
-        0x6200, /* ChipRevision */
-        0x5070002, /* ProductID */
+        0x8000, /* ChipID */
+        0x7000, /* ChipRevision */
+        0x15080003, /* ProductID */
         0x0, /* EcoID */
-        0x0, /* CustomerID */
+        0x25, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x400, /* gcFEATURE_VALUE_ThreadCount */
-        0x4, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -64967,29 +74712,29 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NumResolvePipes */
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
-        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
-        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -65332,7 +75077,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
-        0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
@@ -65358,6 +75103,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -65394,18 +75142,18 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
         0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
-        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
-        0x0, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
-        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x0, /* gcFEATURE_BIT_TP_REORDER */
         0x0, /* gcFEATURE_BIT_TP_LRN */
         0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
@@ -65420,8 +75168,8 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -65436,7 +75184,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
@@ -65453,28 +75201,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip7000UL_6200 */
+    /* vip8000UL-s */
     {
-        0x7000, /* ChipID */
-        0x6201, /* ChipRevision */
-        0x5070003, /* ProductID */
+        0x8000, /* ChipID */
+        0x7005, /* ChipRevision */
+        0x15080003, /* ProductID */
         0x0, /* EcoID */
-        0x0, /* CustomerID */
+        0x83, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
-        0x1, /* FormalRelease */
+        0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
         0x200, /* gcFEATURE_VALUE_ThreadCount */
         0x2, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x2, /* gcFEATURE_VALUE_CoreCount */
+        0x18, /* gcFEATURE_VALUE_LocalStorageSize */
         0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -65486,29 +75245,29 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_NumResolvePipes */
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
-        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
-        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
-        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -65742,7 +75501,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -65851,7 +75610,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
-        0x0, /* gcFEATURE_BIT_PSCS_THROTTLE */
+        0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
@@ -65865,7 +75624,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -65877,6 +75636,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -65913,18 +75675,18 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_NO_SELECTADD */
         0x0, /* gcFEATURE_BIT_EVIS_LERP_7OUTPUT */
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
-        0x0, /* gcFEATURE_BIT_EVIS_VX2 */
-        0x0, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
-        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x1, /* gcFEATURE_BIT_EVIS_VX2 */
+        0x1, /* gcFEATURE_BIT_NN_FLOAT */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x0, /* gcFEATURE_BIT_TP_REORDER */
         0x0, /* gcFEATURE_BIT_TP_LRN */
         0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
@@ -65936,11 +75698,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
         0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -65955,7 +75717,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
@@ -65972,14 +75734,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL_6211 */
+    /* vip8000UL-q */
     {
         0x8000, /* ChipID */
-        0x6212, /* ChipRevision */
-        0x5080003, /* ProductID */
+        0x7000, /* ChipRevision */
+        0x45080003, /* ProductID */
         0x0, /* EcoID */
-        0x21, /* CustomerID */
+        0x26, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -65989,11 +75762,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -66006,16 +75779,16 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
@@ -66025,9 +75798,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -66396,6 +76169,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -66434,8 +76210,8 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
         0x1, /* gcFEATURE_BIT_EVIS_VX2 */
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
-        0x0, /* gcFEATURE_BIT_VIP_V7 */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x0, /* gcFEATURE_BIT_TP_REORDER */
@@ -66491,14 +76267,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000ULFN_6211 */
+    /* vip8000UL */
     {
         0x8000, /* ChipID */
-        0x6211, /* ChipRevision */
+        0x7000, /* ChipRevision */
         0x5080003, /* ProductID */
         0x0, /* EcoID */
-        0x22, /* CustomerID */
+        0x0, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -66508,11 +76295,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -66526,15 +76313,15 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
         0x1, /* gcFEATURE_VALUE_NNCoreCount */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
@@ -66544,9 +76331,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -66903,7 +76690,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -66915,6 +76702,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -66953,9 +76743,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
         0x1, /* gcFEATURE_BIT_EVIS_VX2 */
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
-        0x0, /* gcFEATURE_BIT_VIP_V7 */
-        0x0, /* gcFEATURE_BIT_MCFE */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_VIP_V7 */
+        0x1, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x0, /* gcFEATURE_BIT_TP_REORDER */
         0x0, /* gcFEATURE_BIT_TP_LRN */
@@ -66979,7 +76769,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
@@ -66993,7 +76783,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
@@ -67010,28 +76800,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL_6211 */
+    /* vip8000-q */
     {
         0x8000, /* ChipID */
-        0x6211, /* ChipRevision */
-        0x5080003, /* ProductID */
+        0x7000, /* ChipRevision */
+        0x45080000, /* ProductID */
         0x0, /* EcoID */
-        0x0, /* CustomerID */
+        0x72, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x200, /* gcFEATURE_VALUE_ThreadCount */
-        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x800, /* gcFEATURE_VALUE_ThreadCount */
+        0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -67044,16 +76845,16 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
@@ -67063,9 +76864,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -67422,7 +77223,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -67434,6 +77235,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -67472,11 +77276,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
         0x1, /* gcFEATURE_BIT_EVIS_VX2 */
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x0, /* gcFEATURE_BIT_TP_LRN */
         0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
@@ -67512,14 +77316,14 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
@@ -67529,14 +77333,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano */
+    /* vipnano-d */
     {
         0x8000, /* ChipID */
-        0x7000, /* ChipRevision */
-        0x5080001, /* ProductID */
+        0x7003, /* ChipRevision */
+        0x25080001, /* ProductID */
         0x0, /* EcoID */
-        0x29, /* CustomerID */
+        0x2a, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -67547,7 +77362,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
         0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
@@ -67563,16 +77378,16 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
@@ -67582,9 +77397,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -67953,6 +77768,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -67996,11 +77814,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
@@ -68018,7 +77836,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
@@ -68038,7 +77856,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
@@ -68048,14 +77866,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* gcnanovip */
+    /* vipnano-d */
     {
         0x8000, /* ChipID */
         0x7000, /* ChipRevision */
-        0x424f5343, /* ProductID */
+        0x25080001, /* ProductID */
         0x0, /* EcoID */
-        0x0, /* CustomerID */
+        0x76, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -68066,7 +77895,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
         0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x8, /* gcFEATURE_VALUE_L1CacheSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
@@ -68078,20 +77907,20 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
         0x0, /* gcFEATURE_VALUE_BufferSize */
         0x10, /* gcFEATURE_VALUE_VertexCacheSize */
-        0x1, /* gcFEATURE_VALUE_NumResolvePipes */
+        0x0, /* gcFEATURE_VALUE_NumResolvePipes */
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
-        0x0, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x0, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
-        0x0, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x0, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x40, /* gcFEATURE_VALUE_NNMadPerCore */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
+        0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
@@ -68101,9 +77930,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -68398,7 +78227,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SH_NO_INDEX_CONST_ON_A0 */
         0x1, /* gcFEATURE_BIT_SH_NO_ONECONST_LIMIT */
         0x1, /* gcFEATURE_BIT_SH_IMG_LDST_ON_TEMP */
-        0x0, /* gcFEATURE_BIT_COMPUTE_ONLY */
+        0x1, /* gcFEATURE_BIT_COMPUTE_ONLY */
         0x1, /* gcFEATURE_BIT_SH_IMG_LDST_CLAMP */
         0x1, /* gcFEATURE_BIT_SH_ICACHE_ALLOC_COUNT_FIX */
         0x1, /* gcFEATURE_BIT_SH_ICACHE_PREFETCH */
@@ -68450,7 +78279,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
-        0x1, /* gcFEATURE_BIT_FENCE_64BIT */
+        0x0, /* gcFEATURE_BIT_FENCE_64BIT */
         0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
         0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
         0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
@@ -68472,6 +78301,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -68510,16 +78342,16 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
         0x1, /* gcFEATURE_BIT_EVIS_VX2 */
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x0, /* gcFEATURE_BIT_MCFE */
+        0x1, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
@@ -68550,14 +78382,14 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
@@ -68567,31 +78399,42 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-q */
+    /* vip8000L-O */
     {
         0x8000, /* ChipID */
-        0x7100, /* ChipRevision */
-        0x45080001, /* ProductID */
+        0x7000, /* ChipRevision */
+        0x85080002, /* ProductID */
         0x0, /* EcoID */
-        0x24, /* CustomerID */
+        0x2f, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x100, /* gcFEATURE_VALUE_ThreadCount */
-        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x400, /* gcFEATURE_VALUE_ThreadCount */
+        0x4, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
-        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
-        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x4, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
@@ -68601,28 +78444,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x10, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x10, /* gcFEATURE_VALUE_NNCoreCount */
+        0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -68955,26 +78798,26 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_SH_CMPLX */
-        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x1, /* gcFEATURE_BIT_SH_CMPLX */
+        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
-        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
         0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
-        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x1, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x0, /* gcFEATURE_BIT_FENCE_64BIT */
         0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
         0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
         0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
-        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
-        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x1, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
@@ -68991,6 +78834,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -69031,7 +78877,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
         0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x0, /* gcFEATURE_BIT_MCFE */
+        0x1, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
@@ -69039,7 +78885,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
         0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
@@ -69049,13 +78895,13 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
         0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
         0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
@@ -69063,20 +78909,20 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
@@ -69086,31 +78932,42 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-q */
+    /* vip8000L-qi */
     {
         0x8000, /* ChipID */
-        0x7100, /* ChipRevision */
-        0x45080001, /* ProductID */
+        0x7200, /* ChipRevision */
+        0x4508000a, /* ProductID */
         0x0, /* EcoID */
-        0x82, /* CustomerID */
+        0x85, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x100, /* gcFEATURE_VALUE_ThreadCount */
-        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x400, /* gcFEATURE_VALUE_ThreadCount */
+        0x4, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
-        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
-        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x4, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
@@ -69120,28 +78977,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0xa, /* gcFEATURE_VALUE_NNCoreCount */
-        0xa, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0xc, /* gcFEATURE_VALUE_NNCoreCount */
+        0xc, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0xc, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -69474,25 +79331,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_SH_CMPLX */
-        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x1, /* gcFEATURE_BIT_SH_CMPLX */
+        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
-        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
         0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
-        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x1, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x0, /* gcFEATURE_BIT_FENCE_64BIT */
         0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
         0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
         0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
-        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
@@ -69510,6 +79367,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -69550,12 +79410,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
         0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x0, /* gcFEATURE_BIT_MCFE */
+        0x1, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x1, /* gcFEATURE_BIT_NN_ZDP3 */
@@ -69570,27 +79430,27 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
@@ -69598,38 +79458,49 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-d */
+    /* vip8000L-di */
     {
         0x8000, /* ChipID */
-        0x7110, /* ChipRevision */
-        0x25080001, /* ProductID */
+        0x7200, /* ChipRevision */
+        0x2508000a, /* ProductID */
         0x0, /* EcoID */
-        0x89, /* CustomerID */
+        0x91, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x100, /* gcFEATURE_VALUE_ThreadCount */
-        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x400, /* gcFEATURE_VALUE_ThreadCount */
+        0x4, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x20, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
-        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
-        0x2, /* gcFEATURE_VALUE_USC_BANKS */
+        0x4, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
@@ -69639,28 +79510,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x100, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
-        0x3, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
-        0x3, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -69993,25 +79864,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_SH_CMPLX */
-        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x1, /* gcFEATURE_BIT_SH_CMPLX */
+        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
-        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
         0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
-        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x1, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x0, /* gcFEATURE_BIT_FENCE_64BIT */
         0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
         0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
         0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
-        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
@@ -70029,6 +79900,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -70069,12 +79943,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
         0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x0, /* gcFEATURE_BIT_MCFE */
+        0x1, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x1, /* gcFEATURE_BIT_NN_ZDP3 */
@@ -70089,27 +79963,27 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
@@ -70117,35 +79991,46 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL-s */
+    /* vipnano-s */
     {
         0x8000, /* ChipID */
-        0x7000, /* ChipRevision */
-        0x15080003, /* ProductID */
+        0x7003, /* ChipRevision */
+        0x15080001, /* ProductID */
         0x0, /* EcoID */
-        0x25, /* CustomerID */
+        0x23, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x200, /* gcFEATURE_VALUE_ThreadCount */
-        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
         0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -70166,7 +80051,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -70177,9 +80062,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -70548,6 +80433,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -70610,7 +80498,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
@@ -70633,7 +80521,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
@@ -70643,28 +80531,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL-s */
+    /* vipnano-si */
     {
         0x8000, /* ChipID */
         0x7005, /* ChipRevision */
-        0x15080003, /* ProductID */
-        0x0, /* EcoID */
-        0x83, /* CustomerID */
+        0x5000009, /* ProductID */
+        0x2000000, /* EcoID */
+        0x96, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x200, /* gcFEATURE_VALUE_ThreadCount */
-        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x2, /* gcFEATURE_VALUE_CoreCount */
-        0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
         0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -70680,12 +80579,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x2, /* gcFEATURE_VALUE_NNCoreCount */
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -70696,9 +80595,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -70932,7 +80831,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x1, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -71055,7 +80954,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -71067,6 +80966,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -71112,7 +81014,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TP_REORDER */
         0x0, /* gcFEATURE_BIT_TP_LRN */
         0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
@@ -71126,10 +81028,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
         0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
@@ -71152,7 +81054,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
@@ -71162,28 +81064,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL-q */
+    /* vipnano-qi */
     {
         0x8000, /* ChipID */
-        0x7000, /* ChipRevision */
-        0x45080003, /* ProductID */
+        0x7004, /* ChipRevision */
+        0x45080009, /* ProductID */
         0x0, /* EcoID */
-        0x26, /* CustomerID */
+        0x7d, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x200, /* gcFEATURE_VALUE_ThreadCount */
-        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
         0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -71198,26 +81111,26 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
         0x8, /* gcFEATURE_VALUE_NNCoreCount */
         0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -71574,7 +81487,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -71586,6 +81499,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -71629,27 +81545,27 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
-        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
         0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
         0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -71661,17 +81577,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
@@ -71681,28 +81597,39 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL */
+    /* vipnano-qi */
     {
         0x8000, /* ChipID */
-        0x7000, /* ChipRevision */
-        0x5080003, /* ProductID */
-        0x0, /* EcoID */
-        0x0, /* CustomerID */
+        0x7004, /* ChipRevision */
+        0x45080009, /* ProductID */
+        0x1, /* EcoID */
+        0x7d, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x200, /* gcFEATURE_VALUE_ThreadCount */
-        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x18, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
         0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x18, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -71715,28 +81642,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -72105,6 +82032,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -72145,30 +82075,30 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
         0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x1, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
-        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
         0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
         0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -72180,7 +82110,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
@@ -72190,38 +82120,49 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
+        0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
-        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000-q */
+    /* vipnano-di */
     {
         0x8000, /* ChipID */
         0x7000, /* ChipRevision */
-        0x45080000, /* ProductID */
+        0x25080009, /* ProductID */
         0x0, /* EcoID */
-        0x72, /* CustomerID */
+        0x7e, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x800, /* gcFEATURE_VALUE_ThreadCount */
-        0x8, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x40, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x40, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -72234,28 +82175,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -72624,6 +82565,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -72667,23 +82611,23 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x1, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
-        0x0, /* gcFEATURE_BIT_TP_ROI_POOLING */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x0, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
-        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
         0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
         0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
@@ -72699,7 +82643,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
@@ -72719,14 +82663,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-d */
+    /* vipnano-si */
     {
         0x8000, /* ChipID */
-        0x7003, /* ChipRevision */
-        0x25080001, /* ProductID */
+        0x7120, /* ChipRevision */
+        0x15080009, /* ProductID */
         0x0, /* EcoID */
-        0x2a, /* CustomerID */
+        0x80, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -72753,28 +82708,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -73143,6 +83098,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -73185,43 +83143,43 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
@@ -73238,14 +83196,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-d */
+    /* vipnano-qi+ */
     {
         0x8000, /* ChipID */
-        0x7000, /* ChipRevision */
-        0x25080001, /* ProductID */
-        0x0, /* EcoID */
-        0x76, /* CustomerID */
+        0x8000, /* ChipRevision */
+        0x5080009, /* ProductID */
+        0x16000000, /* EcoID */
+        0xa3, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -73261,7 +83230,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
@@ -73272,28 +83241,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x16, /* gcFEATURE_VALUE_NNCoreCount */
+        0x16, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x16, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x9, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x5, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
-        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x40, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -73662,6 +83631,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -73702,86 +83674,97 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
         0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x1, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
-        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
-        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
-        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x1, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x1, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x1, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000L-O */
+    /* vipnano-qi+ */
     {
         0x8000, /* ChipID */
-        0x7000, /* ChipRevision */
-        0x85080002, /* ProductID */
-        0x0, /* EcoID */
-        0x2f, /* CustomerID */
+        0x8001, /* ChipRevision */
+        0x5080009, /* ProductID */
+        0x18000000, /* EcoID */
+        0xa9, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x400, /* gcFEATURE_VALUE_ThreadCount */
-        0x4, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
-        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
-        0x4, /* gcFEATURE_VALUE_USC_BANKS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
@@ -73791,28 +83774,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x10, /* gcFEATURE_VALUE_NNCoreCount */
-        0x10, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x10, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x10, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x18, /* gcFEATURE_VALUE_NNCoreCount */
+        0x18, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x18, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0x9, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x5, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
-        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x40, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -74145,26 +84128,26 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
-        0x1, /* gcFEATURE_BIT_SH_CMPLX */
-        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
-        0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
         0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
         0x0, /* gcFEATURE_BIT_ASYNC_FE_FENCE_FIX */
         0x1, /* gcFEATURE_BIT_PSCS_THROTTLE */
-        0x1, /* gcFEATURE_BIT_SEPARATE_LS */
+        0x0, /* gcFEATURE_BIT_SEPARATE_LS */
         0x0, /* gcFEATURE_BIT_WIDELINE_TRIANGLE_EMU */
         0x0, /* gcFEATURE_BIT_FENCE_32BIT */
         0x0, /* gcFEATURE_BIT_FENCE_64BIT */
         0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
         0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
         0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
-        0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
-        0x1, /* gcFEATURE_BIT_HWMANAGED_LS */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
@@ -74181,6 +84164,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -74221,12 +84207,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
         0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x1, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x1, /* gcFEATURE_BIT_NN_ZDP3 */
@@ -74238,69 +84224,80 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
         0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
-        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
-        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
-        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x1, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x1, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x1, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000L-qi */
+    /* vip8000-oi */
     {
         0x8000, /* ChipID */
-        0x7200, /* ChipRevision */
-        0x4508000a, /* ProductID */
-        0x0, /* EcoID */
-        0x85, /* CustomerID */
+        0x8000, /* ChipRevision */
+        0x5080008, /* ProductID */
+        0x20000000, /* EcoID */
+        0xa4, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x400, /* gcFEATURE_VALUE_ThreadCount */
-        0x4, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x8, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
-        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
-        0x4, /* gcFEATURE_VALUE_USC_BANKS */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
@@ -74310,28 +84307,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0xc, /* gcFEATURE_VALUE_NNCoreCount */
-        0xc, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0xc, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x20, /* gcFEATURE_VALUE_NNCoreCount */
+        0x20, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x20, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x12, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x10, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x5, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
-        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
-        0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
-        0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
-        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
+        0x0, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
+        0x0, /* gcFEATURE_VALUE_NNFP16_ZDP */
+        0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x40, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -74664,12 +84661,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
-        0x1, /* gcFEATURE_BIT_SH_CMPLX */
-        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
-        0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
         0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
@@ -74682,7 +84679,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
         0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
         0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
-        0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
@@ -74700,6 +84697,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -74740,7 +84740,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
         0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x1, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
@@ -74760,7 +84760,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
@@ -74768,7 +84768,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
         0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
@@ -74776,50 +84776,61 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
-        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
-        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
         0x1, /* gcFEATURE_BIT_ZRL_8BIT */
-        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x1, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x1, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x1, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000L-di */
+    /* vipnano-ni */
     {
         0x8000, /* ChipID */
-        0x7200, /* ChipRevision */
-        0x508000a, /* ProductID */
-        0x4000000, /* EcoID */
-        0x91, /* CustomerID */
+        0x7121, /* ChipRevision */
+        0x5000009, /* ProductID */
+        0x1000000, /* EcoID */
+        0xa2, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x400, /* gcFEATURE_VALUE_ThreadCount */
-        0x4, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x20, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x20, /* gcFEATURE_VALUE_L1CacheSize */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x20, /* gcFEATURE_VALUE_USC_MAX_PAGES */
-        0x2, /* gcFEATURE_VALUE_NumPixelPipes */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
-        0x4, /* gcFEATURE_VALUE_USC_BANKS */
+        0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
         0x400, /* gcFEATURE_VALUE_VertexOutputBufferSize */
@@ -74829,28 +84840,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -75183,12 +85194,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
         0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
-        0x1, /* gcFEATURE_BIT_SH_CMPLX */
-        0x1, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
+        0x0, /* gcFEATURE_BIT_SH_CMPLX */
+        0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
         0x0, /* gcFEATURE_BIT_TX_LERP_LESS_BIT */
         0x0, /* gcFEATURE_BIT_SH_GM_ENDIAN */
         0x0, /* gcFEATURE_BIT_SH_GM_USC_UNALLOC */
-        0x1, /* gcFEATURE_BIT_SH_END_OF_BB */
+        0x0, /* gcFEATURE_BIT_SH_END_OF_BB */
         0x0, /* gcFEATURE_BIT_TX_BORDER_CLAMP_FIX */
         0x0, /* gcFEATURE_BIT_SH_IMG_LD_LASTPIXEL_FIX */
         0x0, /* gcFEATURE_BIT_ASYNC_BLT */
@@ -75201,7 +85212,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PE_DEPTH_ONLY_OQFIX */
         0x0, /* gcFEATURE_BIT_TX_SEAMLESS_CUBE */
         0x0, /* gcFEATURE_BIT_TX_SNORM_SUPPORT */
-        0x1, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
+        0x0, /* gcFEATURE_BIT_SH_SCATTER_GATHER */
         0x0, /* gcFEATURE_BIT_HWMANAGED_LS */
         0x0, /* gcFEATURE_BIT_SH_IMAGE_ENABLE_FIX */
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
@@ -75219,6 +85230,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -75259,7 +85273,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
         0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
-        0x1, /* gcFEATURE_BIT_MCFE */
+        0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
         0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
@@ -75282,24 +85296,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
@@ -75307,27 +85321,38 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-s */
+    /* vip8000UL-si */
     {
         0x8000, /* ChipID */
-        0x7003, /* ChipRevision */
-        0x15080001, /* ProductID */
-        0x0, /* EcoID */
-        0x23, /* CustomerID */
+        0x7121, /* ChipRevision */
+        0x508000b, /* ProductID */
+        0x2000000, /* EcoID */
+        0x98, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x100, /* gcFEATURE_VALUE_ThreadCount */
-        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
@@ -75350,26 +85375,26 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
         0x2, /* gcFEATURE_VALUE_NNCoreCount */
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x40000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -75726,7 +85751,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -75738,6 +85763,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -75780,28 +85808,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
-        0x1, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -75810,13 +85838,13 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
@@ -75833,14 +85861,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-si */
     {
         0x8000, /* ChipID */
-        0x7005, /* ChipRevision */
-        0x5080009, /* ProductID */
+        0x7121, /* ChipRevision */
+        0x5000009, /* ProductID */
         0x2000000, /* EcoID */
-        0x96, /* CustomerID */
+        0x97, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -75869,26 +85908,26 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
         0x2, /* gcFEATURE_VALUE_NNCoreCount */
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x0, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -76245,7 +86284,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_MSAA_FRAGMENT_OPERATION */
         0x0, /* gcFEATURE_BIT_PE_TILE_CACHE_FLUSH_FIX */
         0x0, /* gcFEATURE_BIT_BLT_YUV_OUTPUT */
-        0x0, /* gcFEATURE_BIT_SH_IO_CG_FIX */
+        0x1, /* gcFEATURE_BIT_SH_IO_CG_FIX */
         0x0, /* gcFEATURE_BIT_PE_SWIZZLE */
         0x0, /* gcFEATURE_BIT_SH_ROBUSTNESS_FIX */
         0x0, /* gcFEATURE_BIT_USC_ATOMIC_FIX2 */
@@ -76257,6 +86296,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -76299,28 +86341,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
-        0x0, /* gcFEATURE_BIT_TP_LRN */
-        0x0, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_LRN */
+        0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
-        0x0, /* gcFEATURE_BIT_NN_INT8_SCALE */
-        0x0, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TF_QUANTIZATION */
+        0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
+        0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
-        0x0, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -76329,13 +86371,13 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_OCB_COUNTER */
+        0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
@@ -76352,14 +86394,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-qi */
+    /* vipnano-si */
     {
         0x8000, /* ChipID */
-        0x7004, /* ChipRevision */
-        0x45080009, /* ProductID */
-        0x0, /* EcoID */
-        0x7d, /* CustomerID */
+        0x8000, /* ChipRevision */
+        0x5000009, /* ProductID */
+        0x4000000, /* EcoID */
+        0xa5, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -76375,7 +86428,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
@@ -76386,28 +86439,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x9, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x5, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
-        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x40, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -76776,6 +86829,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -76818,67 +86874,78 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER */
+        0x1, /* gcFEATURE_BIT_TP_REORDER */
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
         0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
         0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
         0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
         0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
-        0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
-        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
-        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
-        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x1, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x1, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x1, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-qi */
+    /* vippico_v1 */
     {
         0x8000, /* ChipID */
-        0x7004, /* ChipRevision */
-        0x45080009, /* ProductID */
-        0x1, /* EcoID */
-        0x7d, /* CustomerID */
+        0x7120, /* ChipRevision */
+        0x8000001, /* ProductID */
+        0x1000000, /* EcoID */
+        0x87, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -76905,18 +86972,18 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
@@ -76924,9 +86991,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -77295,6 +87362,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -77333,7 +87403,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
         0x1, /* gcFEATURE_BIT_EVIS_VX2 */
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
-        0x1, /* gcFEATURE_BIT_TP_ENGINE */
+        0x0, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
@@ -77341,23 +87411,23 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
         0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
         0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
         0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
-        0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
@@ -77368,12 +87438,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
@@ -77387,17 +87457,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
-        0x0, /* gcFEATURE_BIT_HI_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-di */
+    /* vippico_v2 */
     {
         0x8000, /* ChipID */
-        0x7000, /* ChipRevision */
-        0x25080009, /* ProductID */
-        0x0, /* EcoID */
-        0x7e, /* CustomerID */
+        0x7130, /* ChipRevision */
+        0x8000001, /* ProductID */
+        0x1000000, /* EcoID */
+        0x93, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -77424,28 +87505,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x7, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -77814,6 +87895,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -77860,41 +87944,41 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3 */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
         0x0, /* gcFEATURE_BIT_NN_XYDP9 */
         0x1, /* gcFEATURE_BIT_NN_INT8_SCALE */
         0x1, /* gcFEATURE_BIT_NN_POWER_ISOLATION */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE1 */
         0x1, /* gcFEATURE_BIT_TF_QUANTIZATION */
-        0x1, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
-        0x0, /* gcFEATURE_BIT_TP_REAL_INT16 */
-        0x0, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
+        0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
+        0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
-        0x0, /* gcFEATURE_BIT_TP_REORDER_FIX */
+        0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
@@ -77902,21 +87986,32 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-si */
+    /* vippico_v3 */
     {
         0x8000, /* ChipID */
-        0x7120, /* ChipRevision */
-        0x15080009, /* ProductID */
-        0x0, /* EcoID */
-        0x80, /* CustomerID */
+        0x7131, /* ChipRevision */
+        0x8000001, /* ProductID */
+        0x2000000, /* EcoID */
+        0x99, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -77945,26 +88040,26 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
         0x2, /* gcFEATURE_VALUE_NNCoreCount */
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x7, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -78333,6 +88428,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -78379,7 +88477,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
@@ -78398,22 +88496,22 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
@@ -78421,27 +88519,38 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL-si */
+    /* vipnano-si */
     {
         0x8000, /* ChipID */
-        0x7121, /* ChipRevision */
-        0x508000b, /* ProductID */
+        0x7131, /* ChipRevision */
+        0x5000009, /* ProductID */
         0x2000000, /* EcoID */
-        0x98, /* CustomerID */
+        0x9e, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x200, /* gcFEATURE_VALUE_ThreadCount */
-        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
@@ -78451,7 +88560,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
@@ -78466,13 +88575,13 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x100, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x60000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -78481,9 +88590,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -78852,6 +88961,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -78915,24 +89027,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
@@ -78940,21 +89052,32 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-si */
+    /* vip8000-oi MP */
     {
         0x8000, /* ChipID */
-        0x7120, /* ChipRevision */
-        0x5080009, /* ProductID */
-        0x2000000, /* EcoID */
-        0x97, /* CustomerID */
+        0x7300, /* ChipRevision */
+        0x5080008, /* ProductID */
+        0x10000000, /* EcoID */
+        0x86, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -78963,12 +89086,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x8, /* gcFEATURE_VALUE_CoreCount */
+        0x9, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x9, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -78989,9 +89112,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -79000,9 +89123,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -79236,7 +89359,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -79333,7 +89456,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
@@ -79370,7 +89493,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -79431,12 +89557,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
@@ -79445,14 +89571,14 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_SCALER */
+        0x1, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
@@ -79466,14 +89592,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vippico_v1 */
+    /* VIP8000OI_SP */
     {
         0x8000, /* ChipID */
-        0x7120, /* ChipRevision */
-        0x8000001, /* ProductID */
-        0x1000000, /* EcoID */
-        0x87, /* CustomerID */
+        0x7300, /* ChipRevision */
+        0x5080008, /* ProductID */
+        0x2000000, /* EcoID */
+        0xa7, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -79483,11 +89620,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x9, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x9, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -79500,17 +89637,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x2, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x0, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -79519,9 +89656,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -79755,7 +89892,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -79852,7 +89989,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
@@ -79889,7 +90026,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -79928,7 +90068,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_EVIS_ACCSQ_8OUTPUT */
         0x1, /* gcFEATURE_BIT_EVIS_VX2 */
         0x1, /* gcFEATURE_BIT_NN_FLOAT */
-        0x0, /* gcFEATURE_BIT_TP_ENGINE */
+        0x1, /* gcFEATURE_BIT_TP_ENGINE */
         0x1, /* gcFEATURE_BIT_VIP_V7 */
         0x0, /* gcFEATURE_BIT_MCFE */
         0x0, /* gcFEATURE_BIT_NN_INTERLEVE8 */
@@ -79936,7 +90076,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
@@ -79955,14 +90095,14 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
@@ -79971,7 +90111,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_SCALER */
+        0x1, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
@@ -79985,14 +90125,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vippico_v2 */
+    /* vip8000L-qi MP */
     {
         0x8000, /* ChipID */
-        0x7130, /* ChipRevision */
-        0x8000001, /* ProductID */
-        0x1000000, /* EcoID */
-        0x93, /* CustomerID */
+        0x7300, /* ChipRevision */
+        0x508000a, /* ProductID */
+        0x8000000, /* EcoID */
+        0x9b, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -80001,12 +90152,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x4, /* gcFEATURE_VALUE_CoreCount */
+        0x9, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x9, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -80019,28 +90170,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount */
-        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
-        0x7, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -80274,7 +90425,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -80371,7 +90522,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
@@ -80408,7 +90559,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -80455,7 +90609,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
@@ -80475,43 +90629,54 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vippico_v3 */
+    /* vip8000UL-di MP */
     {
         0x8000, /* ChipID */
-        0x7130, /* ChipRevision */
-        0x8000001, /* ProductID */
-        0x2000000, /* EcoID */
-        0x99, /* CustomerID */
+        0x7300, /* ChipRevision */
+        0x508000b, /* ProductID */
+        0x4000000, /* EcoID */
+        0x9c, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -80520,12 +90685,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x1, /* gcFEATURE_VALUE_CoreCount */
-        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x10, /* gcFEATURE_VALUE_L1CacheSize */
+        0x2, /* gcFEATURE_VALUE_CoreCount */
+        0x9, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x9, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -80540,26 +90705,26 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
         0x2, /* gcFEATURE_VALUE_NNCoreCount */
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x0, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
-        0x7, /* gcFEATURE_VALUE_TPLite_CoreCount */
+        0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -80793,7 +90958,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x0, /* gcFEATURE_BIT_ChipEnableLink */
+        0x1, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -80890,7 +91055,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
@@ -80927,7 +91092,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -80974,7 +91142,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TP_LRN */
         0x1, /* gcFEATURE_BIT_TP_MAX_POOLING_STRIDE1 */
         0x0, /* gcFEATURE_BIT_NN_FP16_ALU */
-        0x0, /* gcFEATURE_BIT_NN_INT16_ALU */
+        0x1, /* gcFEATURE_BIT_NN_INT16_ALU */
         0x1, /* gcFEATURE_BIT_TP_ROI_POOLING */
         0x1, /* gcFEATURE_BIT_NN_ZDP3 */
         0x0, /* gcFEATURE_BIT_NN_ZDP6 */
@@ -80988,49 +91156,60 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-si */
+    /* VIP8000OI_SP */
     {
         0x8000, /* ChipID */
-        0x7130, /* ChipRevision */
-        0x5000009, /* ProductID */
+        0x7300, /* ChipRevision */
+        0x5080008, /* ProductID */
         0x2000000, /* EcoID */
-        0x9e, /* CustomerID */
+        0x90, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -81046,7 +91225,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
@@ -81061,13 +91240,13 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0x6, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x180, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -81076,9 +91255,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -81446,7 +91625,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -81507,49 +91689,60 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000-oi MP */
+    /* vipnano-qi */
     {
         0x8000, /* ChipID */
-        0x7300, /* ChipRevision */
-        0x5080008, /* ProductID */
-        0x10000000, /* EcoID */
-        0x86, /* CustomerID */
+        0x7120, /* ChipRevision */
+        0x45080009, /* ProductID */
+        0x0, /* EcoID */
+        0x88, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -81558,12 +91751,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x8, /* gcFEATURE_VALUE_CoreCount */
-        0x9, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x9, /* gcFEATURE_VALUE_L1CacheSize */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -81576,17 +91769,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -81595,9 +91788,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -81831,7 +92024,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x1, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -81928,7 +92121,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
@@ -81965,7 +92158,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -82026,11 +92222,11 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
@@ -82038,8 +92234,8 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
@@ -82047,7 +92243,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
@@ -82061,14 +92257,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000L-qi MP */
+    /* vipnano-qi */
     {
         0x8000, /* ChipID */
-        0x7300, /* ChipRevision */
-        0x508000a, /* ProductID */
+        0x7130, /* ChipRevision */
+        0x5000009, /* ProductID */
         0x8000000, /* EcoID */
-        0x9b, /* CustomerID */
+        0xa1, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -82077,12 +92284,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x4, /* gcFEATURE_VALUE_CoreCount */
-        0x9, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x9, /* gcFEATURE_VALUE_L1CacheSize */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -82095,17 +92302,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -82114,9 +92321,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -82350,7 +92557,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x1, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -82447,7 +92654,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
@@ -82484,7 +92691,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -82545,49 +92755,60 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_SCALER */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
         0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
         0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL-di MP */
+    /* vipnano-di */
     {
         0x8000, /* ChipID */
-        0x7300, /* ChipRevision */
-        0x508000b, /* ProductID */
-        0x4000000, /* EcoID */
-        0x9c, /* CustomerID */
+        0x7110, /* ChipRevision */
+        0x25080009, /* ProductID */
+        0x0, /* EcoID */
+        0x7f, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -82596,12 +92817,12 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
-        0x2, /* gcFEATURE_VALUE_CoreCount */
-        0x9, /* gcFEATURE_VALUE_LocalStorageSize */
-        0x9, /* gcFEATURE_VALUE_L1CacheSize */
+        0x1, /* gcFEATURE_VALUE_CoreCount */
+        0x10, /* gcFEATURE_VALUE_LocalStorageSize */
+        0x10, /* gcFEATURE_VALUE_L1CacheSize */
         0x200, /* gcFEATURE_VALUE_InstructionMemorySize */
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
-        0x9, /* gcFEATURE_VALUE_USC_MAX_PAGES */
+        0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
         0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
@@ -82614,28 +92835,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x80000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -82869,7 +93090,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_FaceLod */
         0x0, /* gcFEATURE_BIT_MultiCoreSemaphoreStallV2 */
         0x1, /* gcFEATURE_BIT_VMSAA */
-        0x1, /* gcFEATURE_BIT_ChipEnableLink */
+        0x0, /* gcFEATURE_BIT_ChipEnableLink */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_1_5_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_MULTI_SRC_BLT_BILINEAR_FILTER */
         0x1, /* gcFEATURE_BIT_RA_HZEZ_CLOCK_CONTROL */
@@ -82966,7 +93187,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_MULTI_CORE_BLOCK_SET_CONFIG2 */
         0x0, /* gcFEATURE_BIT_PE_VMSAA_COVERAGE_CACHE_FIX */
         0x1, /* gcFEATURE_BIT_SECURITY_AHB */
-        0x1, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
+        0x0, /* gcFEATURE_BIT_MULTICORE_SEMAPHORESTALL_V3 */
         0x0, /* gcFEATURE_BIT_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_SH_CMPLX */
         0x0, /* gcFEATURE_BIT_SH_IDIV0_SWZL_EHS */
@@ -83003,7 +93224,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -83067,7 +93291,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -83077,15 +93301,15 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_SCALER */
+        0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
@@ -83099,20 +93323,31 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-si */
+    /* vip8000UL-di */
     {
         0x8000, /* ChipID */
-        0x7300, /* ChipRevision */
-        0x5080008, /* ProductID */
-        0x2000000, /* EcoID */
-        0x90, /* CustomerID */
+        0x7120, /* ChipRevision */
+        0x508000b, /* ProductID */
+        0x6000000, /* EcoID */
+        0x92, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x100, /* gcFEATURE_VALUE_ThreadCount */
-        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x200, /* gcFEATURE_VALUE_ThreadCount */
+        0x2, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
@@ -83133,28 +93368,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x80000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -83522,7 +93757,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TX_UNNORMALIZED_COORD */
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
-        0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -83583,10 +93821,10 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
@@ -83596,15 +93834,15 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_SCALER */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
         0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
@@ -83618,20 +93856,31 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x0, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-qi */
+    /* vip9000pico4c */
     {
         0x8000, /* ChipID */
-        0x7120, /* ChipRevision */
-        0x45080009, /* ProductID */
-        0x0, /* EcoID */
-        0x88, /* CustomerID */
+        0x8000, /* ChipRevision */
+        0x8000001, /* ProductID */
+        0x1000000, /* EcoID */
+        0xaa, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
         0x100, /* gcFEATURE_VALUE_ThreadCount */
-        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x0, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
@@ -83641,7 +93890,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
@@ -83652,28 +93901,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x8, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x1, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x9, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
-        0x180, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x5, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -84042,6 +94291,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -84100,57 +94352,68 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_TP_SIMPLE_INT16 */
         0x1, /* gcFEATURE_BIT_TP_REAL_INT16 */
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
-        0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
+        0x0, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
-        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
-        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
-        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x1, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x1, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x1, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-di */
+    /* VIP9000PicoSi+ */
     {
         0x8000, /* ChipID */
-        0x7110, /* ChipRevision */
-        0x25080009, /* ProductID */
-        0x0, /* EcoID */
-        0x7f, /* CustomerID */
+        0x8001, /* ChipRevision */
+        0x8090001, /* ProductID */
+        0x6000000, /* EcoID */
+        0xab, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
         0x100, /* gcFEATURE_VALUE_ThreadCount */
-        0x1, /* gcFEATURE_VALUE_NumShaderCores */
+        0x0, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
@@ -84160,7 +94423,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
@@ -84175,24 +94438,24 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
         0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x9, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x200, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x5, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -84561,6 +94824,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -84625,51 +94891,62 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
         0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
-        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x1, /* gcFEATURE_BIT_NN_XYDP0 */
         0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
-        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
-        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x1, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x1, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x1, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vip8000UL-di */
+    /* vipnano-di */
     {
         0x8000, /* ChipID */
-        0x7120, /* ChipRevision */
-        0x508000b, /* ProductID */
-        0x6000000, /* EcoID */
-        0x92, /* CustomerID */
+        0x7131, /* ChipRevision */
+        0x25080009, /* ProductID */
+        0x0, /* EcoID */
+        0x84, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
         0x40, /* gcFEATURE_VALUE_TempRegisters */
-        0x200, /* gcFEATURE_VALUE_ThreadCount */
-        0x2, /* gcFEATURE_VALUE_NumShaderCores */
+        0x100, /* gcFEATURE_VALUE_ThreadCount */
+        0x1, /* gcFEATURE_VALUE_NumShaderCores */
         0x200, /* gcFEATURE_VALUE_InstructionCount */
         0x140, /* gcFEATURE_VALUE_NumberOfConstants */
         0x1, /* gcFEATURE_VALUE_CoreCount */
@@ -84690,17 +94967,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x200, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -84709,9 +94986,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -85080,6 +95357,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -85143,21 +95423,21 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
         0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
-        0x0, /* gcFEATURE_BIT_SWTILING_PHASE3 */
+        0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
         0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
         0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
-        0x0, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
         0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
         0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
@@ -85175,14 +95455,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x0, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-di */
+    /* vipnano-si */
     {
         0x8000, /* ChipID */
-        0x7131, /* ChipRevision */
-        0x25080009, /* ProductID */
-        0x0, /* EcoID */
-        0x84, /* CustomerID */
+        0x7130, /* ChipRevision */
+        0x5080009, /* ProductID */
+        0x2000000, /* EcoID */
+        0x9a, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -85209,16 +95500,16 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x4, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
@@ -85228,9 +95519,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -85599,6 +95890,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -85678,8 +95972,8 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_XYDP0 */
         0x1, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
@@ -85694,14 +95988,25 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x1, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
-    /* vipnano-si */
+    /* vipnano-si+ */
     {
         0x8000, /* ChipID */
-        0x7130, /* ChipRevision */
+        0x8001, /* ChipRevision */
         0x5080009, /* ProductID */
-        0x2000000, /* EcoID */
-        0x9a, /* CustomerID */
+        0x6000000, /* EcoID */
+        0x9f, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -85717,7 +96022,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x14, /* gcFEATURE_VALUE_ShaderPCLength */
         0x10, /* gcFEATURE_VALUE_USC_MAX_PAGES */
         0x1, /* gcFEATURE_VALUE_NumPixelPipes */
-        0x2, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
+        0x1, /* gcFEATURE_VALUE_USC_CACHE_CONTROLLERS */
         0x2, /* gcFEATURE_VALUE_USC_BANKS */
         0x8, /* gcFEATURE_VALUE_Streams */
         0x10, /* gcFEATURE_VALUE_VaryingCount */
@@ -85728,28 +96033,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x2, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
-        0xc, /* gcFEATURE_VALUE_NNInputBufferDepth */
-        0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
+        0x9, /* gcFEATURE_VALUE_NNInputBufferDepth */
+        0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x5, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
-        0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x40, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -86118,6 +96423,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -86178,49 +96486,60 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_NN_FIRST_PIXEL_POOLING */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE2 */
         0x1, /* gcFEATURE_BIT_NN_STRIDE_SUPPORT */
-        0x1, /* gcFEATURE_BIT_NN_XYDP6 */
+        0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
-        0x0, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
-        0x0, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
-        0x0, /* gcFEATURE_BIT_NN_XYDP0 */
-        0x1, /* gcFEATURE_BIT_ZRL_7BIT */
+        0x1, /* gcFEATURE_BIT_NN_XYDP0 */
+        0x0, /* gcFEATURE_BIT_ZRL_7BIT */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_MERGE_FIX */
-        0x0, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
-        0x0, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_NN_SMALLBATCH_PHASE1 */
+        0x1, /* gcFEATURE_BIT_TP_SMALLBATCH_PHASE1 */
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
-        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
-        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
-        0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
+        0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x1, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x1, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x1, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-si+ */
     {
         0x8000, /* ChipID */
-        0x8000, /* ChipRevision */
-        0x5000009, /* ProductID */
-        0x3000000, /* EcoID */
-        0x9f, /* CustomerID */
+        0x8001, /* ChipRevision */
+        0x5080009, /* ProductID */
+        0x7000000, /* EcoID */
+        0xa6, /* CustomerID */
         0x0, /* PatchVersion */
         "", /* ProductName */
         0x0, /* FormalRelease */
@@ -86247,28 +96566,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x100, /* gcFEATURE_VALUE_RESULT_WINDOW_MAX_SIZE */
         0x0, /* gcFEATURE_VALUE_ClusterAliveMask */
         0x40, /* gcFEATURE_VALUE_NNMadPerCore */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
-        0x6, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
+        0x7, /* gcFEATURE_VALUE_NNCoreCount */
+        0x7, /* gcFEATURE_VALUE_NNCoreCount_INT8 */
+        0x7, /* gcFEATURE_VALUE_NNCoreCount_INT16 */
         0x0, /* gcFEATURE_VALUE_NNCoreCount_FLOAT16 */
         0x9, /* gcFEATURE_VALUE_NNInputBufferDepth */
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
-        0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
+        0x5, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_X */
         0x1, /* gcFEATURE_VALUE_NNFP16_XYDP_Y */
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
-        0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
+        0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x40, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -86637,6 +96956,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -86700,16 +97022,16 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_NN_XYDP6 */
         0x1, /* gcFEATURE_BIT_TP_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONV1x1_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
-        0x0, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_CACHELINE_MODE_PERF_FIX */
+        0x1, /* gcFEATURE_BIT_NN_PER3DTILE_BUBBLE_FIX */
         0x1, /* gcFEATURE_BIT_NN_CONVOUT_FIFO_DEPTH_FIX */
         0x1, /* gcFEATURE_BIT_SWTILING_PHASE3 */
         0x0, /* gcFEATURE_BIT_USC_STAY_LRU */
-        0x0, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
+        0x1, /* gcFEATURE_BIT_NN_NONZERO_MIRROR_BORDER */
         0x1, /* gcFEATURE_BIT_NN_COEF_DECOMPRESS_PERF2X */
         0x0, /* gcFEATURE_BIT_INPUT_4BIT */
         0x1, /* gcFEATURE_BIT_COEF_COMPRESSION_ENHANCEMENT */
-        0x0, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX */
         0x1, /* gcFEATURE_BIT_NN_ZDP3_NO_COMPRESS_FIX */
         0x1, /* gcFEATURE_BIT_NN_ASYNC_COPY_PERF_FIX */
         0x1, /* gcFEATURE_BIT_OCB_COUNTER */
@@ -86721,17 +97043,28 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_SCALER */
         0x0, /* gcFEATURE_BIT_NN_REQ_SLOWARBITRATION_FIX */
         0x0, /* gcFEATURE_BIT_IMAGE_PARTIAL_CACHE */
-        0x0, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
+        0x1, /* gcFEATURE_BIT_FULLCACHE_KERNELHEAD_FIX */
         0x1, /* gcFEATURE_BIT_NN_SINGLEPORT_ACCUMBUFFER */
         0x0, /* gcFEATURE_BIT_NN_SMALLBATCH */
         0x0, /* gcFEATURE_BIT_TP_SMALLBATCH */
-        0x0, /* gcFEATURE_BIT_ZRL_8BIT */
-        0x0, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
+        0x1, /* gcFEATURE_BIT_ZRL_8BIT */
+        0x1, /* gcFEATURE_BIT_NN_DEPTHWISE_SUPPORT */
         0x0, /* gcFEATURE_BIT_NN_WRITE_WITHOUT_USC */
-        0x0, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
+        0x1, /* gcFEATURE_BIT_NN_ZDP_INIMAGE_SIZE_FIX */
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x1, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x1, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x1, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x1, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x1, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s */
     {
@@ -86774,9 +97107,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0xe0, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -86785,9 +97118,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -87156,6 +97489,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -87251,6 +97587,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d */
     {
@@ -87293,9 +97640,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -87304,9 +97651,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -87675,6 +98022,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -87770,6 +98120,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q */
     {
@@ -87812,9 +98173,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -87823,9 +98184,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -88194,6 +98555,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -88289,6 +98653,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o */
     {
@@ -88331,9 +98706,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -88342,9 +98717,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -88713,6 +99088,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -88808,6 +99186,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s */
     {
@@ -88850,9 +99239,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x100, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -88861,9 +99250,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -89232,6 +99621,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -89327,6 +99719,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s+ */
     {
@@ -89369,9 +99772,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x100, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -89380,9 +99783,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -89751,6 +100154,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -89846,6 +100252,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d */
     {
@@ -89888,9 +100305,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x200, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -89899,9 +100316,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -90270,6 +100687,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -90365,6 +100785,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d+ */
     {
@@ -90407,9 +100838,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x200, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -90418,9 +100849,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -90789,6 +101220,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -90884,6 +101318,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q */
     {
@@ -90926,9 +101371,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -90937,9 +101382,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -91308,6 +101753,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -91403,6 +101851,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q+ */
     {
@@ -91445,9 +101904,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x400, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -91456,9 +101915,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -91827,6 +102286,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -91922,6 +102384,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o */
     {
@@ -91964,9 +102437,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -91975,9 +102448,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -92346,6 +102819,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -92441,6 +102917,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o+ */
     {
@@ -92483,9 +102970,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0xc, /* gcFEATURE_VALUE_TPEngine_CoreCount */
-        0x800, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
         0x200, /* gcFEATURE_VALUE_TP_REORDER_INIMAGE_SIZE */
         0x0, /* gcFEATURE_VALUE_TPLite_CoreCount */
@@ -92494,9 +102981,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -92865,6 +103352,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -92960,6 +103450,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s */
     {
@@ -93002,7 +103503,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -93013,9 +103514,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -93384,6 +103885,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -93479,6 +103983,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s+ */
     {
@@ -93521,7 +104036,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -93532,9 +104047,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -93903,6 +104418,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -93998,6 +104516,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d */
     {
@@ -94040,7 +104569,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -94051,9 +104580,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -94422,6 +104951,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -94517,6 +105049,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d+ */
     {
@@ -94559,7 +105102,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -94570,9 +105113,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -94941,6 +105484,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -95036,6 +105582,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q */
     {
@@ -95078,7 +105635,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -95089,9 +105646,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -95460,6 +106017,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -95555,6 +106115,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q+ */
     {
@@ -95597,7 +106168,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -95608,9 +106179,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -95979,6 +106550,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -96074,6 +106648,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o */
     {
@@ -96116,7 +106701,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -96127,9 +106712,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -96498,6 +107083,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -96593,6 +107181,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o+ */
     {
@@ -96635,7 +107234,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0xc, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -96646,9 +107245,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -97017,6 +107616,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -97112,6 +107714,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s */
     {
@@ -97154,7 +107767,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -97165,9 +107778,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -97536,6 +108149,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -97631,6 +108247,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s+ */
     {
@@ -97673,7 +108300,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -97684,9 +108311,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -98055,6 +108682,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -98150,6 +108780,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d */
     {
@@ -98192,7 +108833,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -98203,9 +108844,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -98574,6 +109215,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -98669,6 +109313,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d+ */
     {
@@ -98711,7 +109366,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -98722,9 +109377,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -99093,6 +109748,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -99188,6 +109846,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q */
     {
@@ -99230,7 +109899,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -99241,9 +109910,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -99612,6 +110281,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -99707,6 +110379,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q+ */
     {
@@ -99749,7 +110432,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -99760,9 +110443,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -100131,6 +110814,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -100226,6 +110912,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o */
     {
@@ -100268,7 +110965,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x7e2, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -100279,9 +110976,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -100650,6 +111347,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -100745,6 +111445,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o+ */
     {
@@ -100787,7 +111498,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x40, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0xc, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -100798,9 +111509,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x10, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x10, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -101169,6 +111880,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -101264,6 +111978,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x0, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s */
     {
@@ -101306,7 +112031,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x2, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -101317,9 +112042,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -101688,6 +112413,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -101783,6 +112511,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-s+ */
     {
@@ -101825,7 +112564,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x100, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x40000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x3, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -101836,9 +112575,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x10, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -102207,6 +112946,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -102302,6 +113044,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d */
     {
@@ -102344,7 +113097,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -102355,9 +113108,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x20, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -102726,6 +113479,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -102821,6 +113577,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-d+ */
     {
@@ -102863,7 +113630,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x200, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x80000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x6, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -102874,9 +113641,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x20, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -103245,6 +114012,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -103340,6 +114110,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q */
     {
@@ -103382,7 +114163,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x8, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -103393,9 +114174,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x40, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -103764,6 +114545,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -103859,6 +114643,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-q+ */
     {
@@ -103901,7 +114696,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0xc, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -103912,9 +114707,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x40, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -104283,6 +115078,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -104378,6 +115176,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o */
     {
@@ -104420,7 +115229,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x10, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -104431,9 +115240,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x40, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -104802,6 +115611,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -104897,6 +115709,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vipnano-o+ */
     {
@@ -104939,7 +115762,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x800, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x200000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x18, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -104950,9 +115773,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x40, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x40, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x40, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -105321,6 +116144,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -105416,6 +116242,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vip8000ulo_mp */
     {
@@ -105458,7 +116295,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x10, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -105469,9 +116306,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -105840,6 +116677,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -105935,6 +116775,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vip8000ulo+_mp */
     {
@@ -105977,7 +116828,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x18, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -105988,9 +116839,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -106359,6 +117210,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -106454,6 +117308,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vip8000lh_mp */
     {
@@ -106496,7 +117361,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x10, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -106507,9 +117372,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -106878,6 +117743,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -106973,6 +117841,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vip8000lh+_mp */
     {
@@ -107015,7 +117894,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x400, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x100000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x18, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -107026,9 +117905,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -107397,6 +118276,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x1, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -107492,6 +118374,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
     /* vippico */
     {
@@ -107534,7 +118427,7 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x20, /* gcFEATURE_VALUE_NNAccumBufferDepth */
         0x400, /* gcFEATURE_VALUE_TPEngine_PwlLUTCount */
         0x10, /* gcFEATURE_VALUE_TPEngine_PwlLUTSize */
-        0x80, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
+        0x20000, /* gcFEATURE_VALUE_VIP_SRAM_SIZE */
         0x1, /* gcFEATURE_VALUE_TPEngine_CoreCount */
         0x0, /* gcFEATURE_VALUE_AXI_SRAM_SIZE */
         0x4, /* gcFEATURE_VALUE_NN_INIMAGE_OFFSET_BITS */
@@ -107545,9 +118438,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_VALUE_NNFP16_ZDP */
         0x8, /* gcFEATURE_VALUE_NN_LANES_PER_OUT_CYCLE */
         0x20, /* gcFEATURE_VALUE_MAX_OT_NUMBER */
-        0x20, /* gcFEATURE_VALUE_VIP_SRAM_WIDTH_INBYTE */
+        0x20, /* gcFEATURE_VALUE_EQUIVALENT_VIP_SRAM_WIDTH_INBYTE */
         0x8, /* gcFEATURE_VALUE_TP_ZRL_BITS */
-        0x1, /* gcFEATURE_BIT_REG_FastClear */
+        0x0, /* gcFEATURE_BIT_REG_FastClear */
         0x0, /* gcFEATURE_BIT_REG_SpecialAntiAliasing */
         0x1, /* gcFEATURE_BIT_REG_Pipe3D */
         0x1, /* gcFEATURE_BIT_REG_DXTTextureCompression */
@@ -107916,6 +118809,9 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x0, /* gcFEATURE_BIT_PA_LINECLIP_FIX */
         0x0, /* gcFEATURE_BIT_TX_8bit_UVFrac_ROUNDING_FIX */
         0x0, /* gcFEATURE_BIT_MP_ARCH */
+        0x0, /* gcFEATURE_BIT_TX_NO_FIXED_FILTER */
+        0x0, /* gcFEATURE_BIT_SHARE_Z */
+        0x0, /* gcFEATURE_BIT_DE_2D_FAST_CLEAR */
         0x0, /* gcFEATURE_BIT_VG_TS_CULLING */
         0x0, /* gcFEATURE_BIT_VG_FP25 */
         0x0, /* gcFEATURE_BIT_VG_AYUV_INPUT_OUTPUT */
@@ -108011,6 +118907,17 @@ static gcsFEATURE_DATABASE gChipInfo[] = {
         0x1, /* gcFEATURE_BIT_HI_REORDER_FIX */
         0x0, /* gcFEATURE_BIT_TP_COEF_COMPRESSION_ENHANCEMENT */
         0x1, /* gcFEATURE_BIT_VIP_DEC400 */
+        0x0, /* gcFEATURE_BIT_IMAGE_NOT_PACKED_IN_SRAM_FIX */
+        0x1, /* gcFEATURE_BIT_IDLE_BEFORE_FLUSH_COMPLETE_FIX */
+        0x1, /* gcFEATURE_BIT_NO_FLUSH_USC_FIX */
+        0x1, /* gcFEATURE_BIT_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX */
+        0x0, /* gcFEATURE_BIT_XY_OFFSET_LIMITATION_FIX */
+        0x0, /* gcFEATURE_BIT_USC_INVALIDATE_CACHE_LINE_FIX */
+        0x0, /* gcFEATURE_BIT_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX */
+        0x0, /* gcFEATURE_BIT_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX */
+        0x0, /* gcFEATURE_BIT_NN_PER_CHANNEL_POST_MULTIPLY */
+        0x0, /* gcFEATURE_BIT_NN_NO_Z_LOCATION_OFFSET */
+        0x0, /* gcFEATURE_BIT_NN_PRELU */
     },
 };
 
index b2b83c3..83239b2 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -56,7 +56,6 @@
 #ifndef __gc_hal_h_
 #define __gc_hal_h_
 
-#include "gc_hal_rename.h"
 #include "gc_hal_types.h"
 #include "gc_hal_enum.h"
 #include "gc_hal_base.h"
@@ -144,7 +143,7 @@ extern "C" {
 #define gcvINVALID_ADDRESS              ~0U
 #define gcvINVALID_VALUE                0xCCCCCCCC
 
-#define gcvINVALID_PHYSICAL_ADDRESS     ~0U
+#define gcvINVALID_PHYSICAL_ADDRESS     ~0ULL
 
 #define gcmGET_PRE_ROTATION(rotate) \
     ((rotate) & (~(gcvSURF_POST_FLIP_X | gcvSURF_POST_FLIP_Y)))
@@ -198,6 +197,7 @@ typedef enum _gceOBJECT_TYPE
     gcvOBJ_VARIABLE             = gcmCC('V','A','R','I'),
     gcvOBJ_VERTEX               = gcmCC('V','R','T','X'),
     gcvOBJ_VIDMEM               = gcmCC('V','M','E','M'),
+    gcvOBJ_VIDMEM_BLOCK         = gcmCC('V','M','B','K'),
     gcvOBJ_VG                   = gcmCC('V','G',' ',' '),
     gcvOBJ_BUFOBJ               = gcmCC('B','U','F','O'),
     gcvOBJ_UNIFORM_BLOCK        = gcmCC('U','B','L','K'),
@@ -222,8 +222,9 @@ typedef struct _gckHARDWARE *       gckHARDWARE;
 
 #define gcdMAX_SURF_LAYERS             4
 
-#define gcdMAX_DRAW_BUFFERS            8
+#define gcdMAX_DRAW_BUFFERS            16
 
+#define gcdMAX_3DGPU_COUNT             8
 /*******************************************************************************
 **
 **  gcmVERIFY_OBJECT
@@ -310,14 +311,6 @@ typedef struct _gckHARDWARE *       gckHARDWARE;
 #   define gcmVERIFY_OBJECT_RETURN(obj, t)    do {} while (gcvFALSE)
 #endif
 
-typedef struct _gcsContiguousBlock
-{
-    gctUINT32   ptr;
-    gctSIZE_T   size;
-}
-gcsContiguousBlock;
-
-
 /******************************************************************************\
 ********************************** gckOS Object *********************************
 \******************************************************************************/
@@ -380,17 +373,9 @@ gckOS_FreeMemory(
 /* Allocate paged memory. */
 gceSTATUS
 gckOS_AllocatePagedMemory(
-    IN gckOS Os,
-    IN gctSIZE_T Bytes,
-    OUT gctPHYS_ADDR * Physical
-    );
-
-/* Allocate paged memory. */
-gceSTATUS
-gckOS_AllocatePagedMemoryEx(
     IN gckOS Os,
     IN gctUINT32 Flag,
-    IN gctSIZE_T Bytes,
+    IN OUT gctSIZE_T * Bytes,
     OUT gctUINT32 * Gid,
     OUT gctPHYS_ADDR * Physical
     );
@@ -402,22 +387,25 @@ gckOS_LockPages(
     IN gctPHYS_ADDR Physical,
     IN gctSIZE_T Bytes,
     IN gctBOOL Cacheable,
-    OUT gctPOINTER * Logical,
-    OUT gctSIZE_T * PageCount
+    OUT gctPOINTER * Logical
     );
 
 /* Map pages. */
 gceSTATUS
-gckOS_MapPages(
+gckOS_MapPagesEx(
     IN gckOS Os,
+    IN gceCORE Core,
     IN gctPHYS_ADDR Physical,
     IN gctSIZE_T PageCount,
-    IN gctPOINTER PageTable
+    IN gctUINT32 Address,
+    IN gctPOINTER PageTable,
+    IN gctBOOL Writable,
+    IN gceVIDMEM_TYPE Type
     );
 
-/* Map pages. */
+/* Map 1M pages. */
 gceSTATUS
-gckOS_MapPagesEx(
+gckOS_Map1MPages(
     IN gckOS Os,
     IN gceCORE Core,
     IN gctPHYS_ADDR Physical,
@@ -425,7 +413,7 @@ gckOS_MapPagesEx(
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctBOOL Writable,
-    IN gceSURF_TYPE Type
+    IN gceVIDMEM_TYPE Type
     );
 
 gceSTATUS
@@ -467,28 +455,26 @@ gckOS_AllocateNonPagedMemory(
 gceSTATUS
 gckOS_FreeNonPagedMemory(
     IN gckOS Os,
-    IN gctSIZE_T Bytes,
     IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical
+    IN gctPOINTER Logical,
+    IN gctSIZE_T Bytes
     );
 
-/* Allocate contiguous memory. */
+/* Reserved memory. */
 gceSTATUS
-gckOS_AllocateContiguous(
-    IN gckOS Os,
-    IN gctBOOL InUserSpace,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctPHYS_ADDR * Physical,
-    OUT gctPOINTER * Logical
+gckOS_RequestReservedMemory(
+    gckOS Os,
+    gctPHYS_ADDR_T Start,
+    gctSIZE_T Size,
+    const char * Name,
+    gctBOOL Requested,
+    gctPOINTER * MemoryHandle
     );
 
-/* Free contiguous memory. */
-gceSTATUS
-gckOS_FreeContiguous(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
+void
+gckOS_ReleaseReservedMemory(
+    gckOS Os,
+    gctPOINTER MemoryHandle
     );
 
 /* Get the number fo bytes per page. */
@@ -506,28 +492,28 @@ gckOS_GetPhysicalAddress(
     OUT gctPHYS_ADDR_T * Address
     );
 
-/* Get the physical address of a corresponding user logical address. */
+/* Get real physical address from handle. */
 gceSTATUS
-gckOS_UserLogicalToPhysical(
+gckOS_GetPhysicalFromHandle(
     IN gckOS Os,
-    IN gctPOINTER Logical,
-    OUT gctPHYS_ADDR_T * Address
+    IN gctPHYS_ADDR Physical,
+    IN gctUINT32 Offset,
+    OUT gctPHYS_ADDR_T * PhysicalAddress
     );
 
-
-/*  Map a physical address into kernel space.*/
+/* Get the physical address of a corresponding user logical address. */
 gceSTATUS
-gckOS_MapPhysicalToKernelSpace(
+gckOS_UserLogicalToPhysical(
     IN gckOS Os,
-    IN gckVIDMEM_NODE NodeObject,
-    OUT gctPOINTER * Logical
+    IN gctPOINTER Logical,
+    OUT gctPHYS_ADDR_T * Address
     );
 
 /* Map physical memory. */
 gceSTATUS
 gckOS_MapPhysical(
     IN gckOS Os,
-    IN gctUINT32 Physical,
+    IN gctPHYS_ADDR_T Physical,
     IN gctSIZE_T Bytes,
     OUT gctPOINTER * Logical
     );
@@ -540,15 +526,6 @@ gckOS_UnmapPhysical(
     IN gctSIZE_T Bytes
     );
 
-/* Get real physical address from descriptor. */
-gceSTATUS
-gckOS_PhysicalToPhysicalAddress(
-    IN gckOS Os,
-    IN gctPOINTER Physical,
-    IN gctUINT32 Offset,
-    OUT gctPHYS_ADDR_T * PhysicalAddress
-    );
-
 /* Read data from a hardware register. */
 gceSTATUS
 gckOS_ReadRegister(
@@ -583,6 +560,15 @@ gckOS_WriteRegisterEx(
     IN gctUINT32 Data
     );
 
+/* Write data to a hardware register without dump. */
+gceSTATUS
+gckOS_WriteRegisterEx_NoDump(
+    IN gckOS Os,
+    IN gceCORE Core,
+    IN gctUINT32 Address,
+    IN gctUINT32 Data
+    );
+
 #ifdef __QNXNTO__
 static gcmINLINE gceSTATUS
 gckOS_WriteMemory(
@@ -634,17 +620,6 @@ gckOS_UnmapMemory(
     IN gctPOINTER Logical
     );
 
-/* Unmap user logical memory out of physical memory.
- * This function is only supported in Linux currently.
- */
-gceSTATUS
-gckOS_UnmapUserLogical(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    IN gctPOINTER Logical
-    );
-
 /* Delete a mutex. */
 gceSTATUS
 gckOS_DeleteMutex(
@@ -1049,18 +1024,6 @@ gckOS_ZeroMemory(
     IN gctSIZE_T Bytes
     );
 
-/* Device I/O control to the kernel HAL layer. */
-gceSTATUS
-gckOS_DeviceControl(
-    IN gckOS Os,
-    IN gctBOOL FromUser,
-    IN gctUINT32 IoControlCode,
-    IN gctPOINTER InputBuffer,
-    IN gctSIZE_T InputBufferSize,
-    OUT gctPOINTER OutputBuffer,
-    IN gctSIZE_T OutputBufferSize
-    );
-
 /*******************************************************************************
 **
 **  gckOS_GetProcessID
@@ -1172,29 +1135,6 @@ gckOS_UnmapSignal(
     IN gctSIGNAL Signal
     );
 
-/* Map user memory. */
-gceSTATUS
-gckOS_MapUserMemory(
-    IN gckOS Os,
-    IN gceCORE Core,
-    IN gctPOINTER Memory,
-    IN gctUINT32 Physical,
-    IN gctSIZE_T Size,
-    OUT gctPOINTER * Info,
-    OUT gctUINT32_PTR Address
-    );
-
-/* Unmap user memory. */
-gceSTATUS
-gckOS_UnmapUserMemory(
-    IN gckOS Os,
-    IN gceCORE Core,
-    IN gctPOINTER Memory,
-    IN gctSIZE_T Size,
-    IN gctPOINTER Info,
-    IN gctUINT32 Address
-    );
-
 /* Get scatter-gather table from memory. */
 gceSTATUS
 gckOS_MemoryGetSGT(
@@ -1222,13 +1162,14 @@ gckOS_WrapMemory(
     IN gcsUSER_MEMORY_DESC_PTR Desc,
     OUT gctSIZE_T *Bytes,
     OUT gctPHYS_ADDR * Physical,
-    OUT gctBOOL *Contiguous
+    OUT gctBOOL *Contiguous,
+    OUT gctSIZE_T * PageCountCpu
     );
 
 gceSTATUS
 gckOS_GetPolicyID(
     IN gckOS Os,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     OUT gctUINT32_PTR PolicyID,
     OUT gctUINT32_PTR AXIConfig
     );
@@ -1368,7 +1309,7 @@ gceSTATUS
 gckOS_QueryOption(
     IN gckOS Os,
     IN gctCONST_STRING Option,
-    OUT gctUINT32 * Value
+    OUT gctUINT64 * Value
     );
 
 /******************************************************************************\
@@ -1649,106 +1590,13 @@ gckHEAP_ProfileEnd(
     IN gctCONST_STRING Title
     );
 
-
-/******************************************************************************\
-******************************** gckVIDMEM Object ******************************
-\******************************************************************************/
-
 typedef struct _gckVIDMEM *         gckVIDMEM;
 typedef struct _gckKERNEL *         gckKERNEL;
 typedef struct _gckDB *             gckDB;
 typedef struct _gckDVFS *           gckDVFS;
-typedef struct _gcsASYNC_COMMAND *  gckASYNC_COMMAND;
 typedef struct _gckMMU *            gckMMU;
 typedef struct _gcsDEVICE *         gckDEVICE;
 
-/* Construct a new gckVIDMEM object. */
-gceSTATUS
-gckVIDMEM_Construct(
-    IN gckOS Os,
-    IN gctUINT32 BaseAddress,
-    IN gctSIZE_T Bytes,
-    IN gctSIZE_T Threshold,
-    IN gctSIZE_T Banking,
-    OUT gckVIDMEM * Memory
-    );
-
-/* Destroy an gckVDIMEM object. */
-gceSTATUS
-gckVIDMEM_Destroy(
-    IN gckVIDMEM Memory
-    );
-
-/* Allocate linear memory. */
-gceSTATUS
-gckVIDMEM_AllocateLinear(
-    IN gckKERNEL Kernel,
-    IN gckVIDMEM Memory,
-    IN gctSIZE_T Bytes,
-    IN gctUINT32 Alignment,
-    IN gceSURF_TYPE Type,
-    IN gctBOOL Specified,
-    OUT gcuVIDMEM_NODE_PTR * Node
-    );
-
-/* Free memory. */
-gceSTATUS
-gckVIDMEM_Free(
-    IN gckKERNEL Kernel,
-    IN gcuVIDMEM_NODE_PTR Node
-    );
-
-/* Lock memory. */
-gceSTATUS
-gckVIDMEM_Lock(
-    IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    IN gctBOOL Cacheable,
-    OUT gctUINT32 * Address,
-    OUT gctUINT32 * Gid,
-    OUT gctUINT64 * PhysicalAddress
-    );
-
-/* Unlock memory. */
-gceSTATUS
-gckVIDMEM_Unlock(
-    IN gckKERNEL Kernel,
-    IN gckVIDMEM_NODE Node,
-    IN gceSURF_TYPE Type,
-    IN OUT gctBOOL * Asynchroneous
-    );
-
-/* Construct a gcuVIDMEM_NODE union for virtual memory. */
-gceSTATUS
-gckVIDMEM_ConstructVirtual(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 Flag,
-    IN gctSIZE_T Bytes,
-    OUT gcuVIDMEM_NODE_PTR * Node
-    );
-
-/* Destroy a gcuVIDMEM_NODE union for virtual memory. */
-gceSTATUS
-gckVIDMEM_DestroyVirtual(
-    IN gcuVIDMEM_NODE_PTR Node
-    );
-
-gceSTATUS
-gckVIDMEM_SetCommitStamp(
-    IN gckKERNEL Kernel,
-    IN gceENGINE Engine,
-    IN gctUINT32 Handle,
-    IN gctUINT64 CommitStamp
-    );
-
-gceSTATUS
-gckVIDMEM_GetCommitStamp(
-    IN gckKERNEL Kernel,
-    IN gceENGINE Engine,
-    IN gctUINT32 Handle,
-    OUT gctUINT64_PTR CommitStamp
-    );
-
 /******************************************************************************\
 ******************************** gckKERNEL Object ******************************
 \******************************************************************************/
@@ -1814,7 +1662,6 @@ gceSTATUS
 gckKERNEL_Dispatch(
     IN gckKERNEL Kernel,
     IN gckDEVICE Device,
-    IN gctBOOL FromUser,
     IN OUT struct _gcsHAL_INTERFACE * Interface
     );
 
@@ -1833,17 +1680,6 @@ gckKERNEL_QueryVideoMemory(
     OUT struct _gcsHAL_INTERFACE * Interface
     );
 
-/* Query used memory nodes of a specific pool. */
-gceSTATUS
-gckKERNEL_QueryVidMemPoolNodes(
-    gckKERNEL            Kernel,
-    gcePOOL              Pool,
-    gctUINT32          * TotalSize, /* sum of the sizes of the contiguous blocks (i.e. total memory used at current time) : to be filled by the called function */
-    gcsContiguousBlock * MemoryBlocks, /* previously allocated by the calling function : to be filled by the called function */
-    gctUINT32            NumMaxBlocks, /* provided by the calling function */
-    gctUINT32          * NumBlocks      /* actual number of contiguous blocks : to be filled by the called function */
-    );
-
 /* Lookup the gckVIDMEM object for a pool. */
 gceSTATUS
 gckKERNEL_GetVideoMemoryPool(
@@ -1852,79 +1688,19 @@ gckKERNEL_GetVideoMemoryPool(
     OUT gckVIDMEM * VideoMemory
     );
 
-gceSTATUS
-gckKERNEL_AllocateLinearMemory(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    IN OUT gcePOOL * Pool,
-    IN gctSIZE_T Bytes,
-    IN gctUINT32 Alignment,
-    IN gceSURF_TYPE Type,
-    IN gctUINT32 Flag,
-    OUT gctUINT32 * Node
-    );
-
-gceSTATUS
-gckKERNEL_ReleaseVideoMemory(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    IN gctUINT32 Handle
-    );
-
-gceSTATUS
-gckKERNEL_LockVideoMemory(
-    IN gckKERNEL Kernel,
-    IN gceCORE Core,
-    IN gctUINT32 ProcessID,
-    IN gctBOOL FromUser,
-    IN OUT gcsHAL_INTERFACE * Interface
-    );
-
-gceSTATUS
-gckKERNEL_UnlockVideoMemory(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    IN OUT gcsHAL_INTERFACE * Interface
-    );
-
-/* Unlock video memory from gpu immediately w/o considering gpu cache flush. */
-gceSTATUS
-gckKERNEL_BottomHalfUnlockVideoMemory(
-    IN gckKERNEL Kernel,
-    IN gctUINT32 ProcessID,
-    IN gctUINT32 Node
-    );
-
-/* Map video memory. */
+/* Map dedicated video memory node. */
 gceSTATUS
 gckKERNEL_MapVideoMemory(
     IN gckKERNEL Kernel,
     IN gctBOOL InUserSpace,
-    IN gctUINT32 Address,
-#ifdef __QNXNTO__
-    IN gctUINT32 Pid,
-    IN gctUINT32 Bytes,
-#endif
-    OUT gctPOINTER * Logical
-    );
-
-/* Map video memory. */
-gceSTATUS
-gckKERNEL_MapVideoMemoryEx(
-    IN gckKERNEL Kernel,
-    IN gceCORE Core,
-    IN gctBOOL InUserSpace,
-    IN gctUINT32 Address,
-#ifdef __QNXNTO__
-    IN gctUINT32 Pid,
-    IN gctUINT32 Bytes,
-#endif
     IN gcePOOL Pool,
+    IN gctUINT32 Offset,
+    IN gctUINT32 Bytes,
     OUT gctPOINTER * Logical
     );
 
 #ifdef __QNXNTO__
-/* Unmap video memory. */
+/* Unmap dedicated video memory. */
 gceSTATUS
 gckKERNEL_UnmapVideoMemory(
     IN gckKERNEL Kernel,
@@ -1957,14 +1733,7 @@ gckKERNEL_UnmapMemory(
 gceSTATUS
 gckKERNEL_Notify(
     IN gckKERNEL Kernel,
-    IN gceNOTIFY Notifcation,
-    IN gctBOOL Data
-    );
-
-gceSTATUS
-gckKERNEL_QuerySettings(
-    IN gckKERNEL Kernel,
-    OUT gcsKERNEL_SETTINGS * Settings
+    IN gceNOTIFY Notifcation
     );
 
 /*******************************************************************************
@@ -2038,10 +1807,23 @@ gckDVFS_Stop(
 gceSTATUS
 gckHARDWARE_Construct(
     IN gckOS Os,
+    IN gckDEVICE Device,
     IN gceCORE Core,
     OUT gckHARDWARE * Hardware
     );
 
+/* Post hardware resource allocation after gckHARDWARE object constructed. */
+gceSTATUS
+gckHARDWARE_PostConstruct(
+    IN gckHARDWARE Hardware
+    );
+
+/* Pre-destroy hardwre resource before destroying an gckHARDWARE object. */
+gceSTATUS
+gckHARDWARE_PreDestroy(
+    IN gckHARDWARE Hardware
+    );
+
 /* Destroy an gckHARDWARE object. */
 gceSTATUS
 gckHARDWARE_Destroy(
@@ -2082,51 +1864,6 @@ gckHARDWARE_QueryCommandBuffer(
     OUT gctUINT32 * ReservedTail
     );
 
-/* Add a WAIT/LINK pair in the command queue. */
-gceSTATUS
-gckHARDWARE_WaitLink(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctUINT32 Address,
-    IN gctUINT32 Offset,
-    IN OUT gctUINT32 * Bytes,
-    OUT gctUINT32 * WaitOffset,
-    OUT gctUINT32 * WaitBytes
-    );
-
-/* Kickstart the command processor. */
-gceSTATUS
-gckHARDWARE_Execute(
-    IN gckHARDWARE Hardware,
-    IN gctUINT32 Address,
-    IN gctSIZE_T Bytes
-    );
-
-/* Add an END command in the command queue. */
-gceSTATUS
-gckHARDWARE_End(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctUINT32 Address,
-    IN OUT gctUINT32 * Bytes
-    );
-
-gceSTATUS
-gckHARDWARE_ChipEnable(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gceCORE_3D_MASK ChipEnable,
-    IN OUT gctSIZE_T * Bytes
-    );
-
-/* Add a NOP command in the command queue. */
-gceSTATUS
-gckHARDWARE_Nop(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN OUT gctSIZE_T * Bytes
-    );
-
 /* Add a PIPESELECT command in the command queue. */
 gceSTATUS
 gckHARDWARE_PipeSelect(
@@ -2136,28 +1873,6 @@ gckHARDWARE_PipeSelect(
     IN OUT gctUINT32 * Bytes
     );
 
-/* Add a LINK command in the command queue. */
-gceSTATUS
-gckHARDWARE_Link(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctUINT32 FetchAddress,
-    IN gctUINT32 FetchSize,
-    IN OUT gctUINT32 * Bytes,
-    OUT gctUINT32 * Low,
-    OUT gctUINT32 * High
-    );
-
-/* Add an EVENT command in the command queue. */
-gceSTATUS
-gckHARDWARE_Event(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctUINT8 Event,
-    IN gceKERNEL_WHERE FromWhere,
-    IN OUT gctUINT32 * Bytes
-    );
-
 /* Query the available memory. */
 gceSTATUS
 gckHARDWARE_QueryMemory(
@@ -2185,14 +1900,6 @@ gckHARDWARE_QueryChipOptions(
     OUT gcsHAL_QUERY_CHIP_OPTIONS_PTR Options
     );
 
-/* Query the shader uniforms support. */
-gceSTATUS
-gckHARDWARE_QueryShaderCaps(
-    IN gckHARDWARE Hardware,
-    OUT gctUINT * VertexUniforms,
-    OUT gctUINT * FragmentUniforms,
-    OUT gctBOOL * UnifiedUnforms
-    );
 
 /* Split a harwdare specific address into API stuff. */
 gceSTATUS
@@ -2211,66 +1918,47 @@ gckHARDWARE_UpdateQueueTail(
     IN gctUINT32 Offset
     );
 
-/* Convert logical address to hardware specific address. */
+/* Interrupt manager. */
 gceSTATUS
-gckHARDWARE_ConvertLogical(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical,
-    IN gctBOOL InUserSpace,
-    OUT gctUINT32 * Address
+gckHARDWARE_Interrupt(
+    IN gckHARDWARE Hardware
     );
 
-/* Interrupt manager. */
 gceSTATUS
-gckHARDWARE_Interrupt(
-    IN gckHARDWARE Hardware,
-    IN gctBOOL InterruptValid
+gckHARDWARE_Notify(
+    IN gckHARDWARE Hardware
     );
 
 /* Program MMU. */
 gceSTATUS
 gckHARDWARE_SetMMU(
     IN gckHARDWARE Hardware,
-    IN gctPOINTER Logical
+    IN gckMMU Mmu
     );
 
 /* Flush the MMU. */
 gceSTATUS
 gckHARDWARE_FlushMMU(
-    IN gckHARDWARE Hardware
-    );
-
-gceSTATUS
-gckHARDWARE_FlushAsyncMMU(
     IN gckHARDWARE Hardware,
     IN gctPOINTER Logical,
+    IN gctUINT32 Address,
+    IN gctUINT32 SubsequentBytes,
     IN OUT gctUINT32 * Bytes
     );
 
-/* Set the page table base address. */
 gceSTATUS
-gckHARDWARE_SetMMUv2(
+gckHARDWARE_FlushAsyncMMU(
     IN gckHARDWARE Hardware,
-    IN gctBOOL Enable,
-    IN gctPOINTER MtlbAddress,
-    IN gceMMU_MODE Mode,
-    IN gctPOINTER SafeAddress,
-    IN gctBOOL FromPower
+    IN gctPOINTER Logical,
+    IN OUT gctUINT32 * Bytes
     );
 
-#if gcdPROCESS_ADDRESS_SPACE
-/* Configure mmu configuration. */
 gceSTATUS
-gckHARDWARE_ConfigMMU(
+gckHARDWARE_FlushMcfeMMU(
     IN gckHARDWARE Hardware,
     IN gctPOINTER Logical,
-    IN gctPOINTER MtlbLogical,
-    IN gctUINT32 Offset,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctSIZE_T * WaitLinkOffset,
-    OUT gctSIZE_T * WaitLinkBytes
+    IN OUT gctUINT32 * Bytes
     );
-#endif
 
 /* Get idle register. */
 gceSTATUS
@@ -2305,21 +1993,21 @@ gckHARDWARE_ReadInterrupt(
 
 /* Power management. */
 gceSTATUS
-gckHARDWARE_SetPowerManagementState(
+gckHARDWARE_SetPowerState(
     IN gckHARDWARE Hardware,
     IN gceCHIPPOWERSTATE State
     );
 
 gceSTATUS
-gckHARDWARE_QueryPowerManagementState(
+gckHARDWARE_QueryPowerState(
     IN gckHARDWARE Hardware,
     OUT gceCHIPPOWERSTATE* State
     );
 
 gceSTATUS
-gckHARDWARE_SetPowerManagement(
+gckHARDWARE_EnablePowerManagement(
     IN gckHARDWARE Hardware,
-    IN gctBOOL PowerManagement
+    IN gctBOOL Enable
     );
 
 gceSTATUS
@@ -2350,27 +2038,6 @@ gckHARDWARE_SetMinFscaleValue(
     );
 #endif
 
-#if gcdPOWEROFF_TIMEOUT
-gceSTATUS
-gckHARDWARE_SetPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    IN gctUINT32    Timeout
-);
-
-gceSTATUS
-gckHARDWARE_QueryPowerOffTimeout(
-    IN gckHARDWARE  Hardware,
-    OUT gctUINT32*  Timeout
-);
-#endif
-
-/* Profile 2D Engine. */
-gceSTATUS
-gckHARDWARE_ProfileEngine2D(
-    IN gckHARDWARE Hardware,
-    OUT gcs2D_PROFILE_PTR Profile
-    );
-
 gceSTATUS
 gckHARDWARE_InitializeHardware(
     IN gckHARDWARE Hardware
@@ -2415,31 +2082,9 @@ gckHARDWARE_SetDVFSPeroid(
     IN gctUINT32 Frequency
     );
 
-gceSTATUS
-gckHARDWARE_PrepareFunctions(
-    gckHARDWARE Hardware
-    );
-
-gceSTATUS
-gckHARDWARE_DestroyFunctions(
-    gckHARDWARE Hardware
-    );
-
-gceSTATUS
-gckHARDWARE_SetMMUStates(
-    IN gckHARDWARE Hardware,
-    IN gctPOINTER MtlbAddress,
-    IN gceMMU_MODE Mode,
-    IN gctPOINTER SafeAddress,
-    IN gctPOINTER Logical,
-    IN OUT gctUINT32 * Bytes
-    );
-
 gceSTATUS
 gckHARDWARE_QueryStateTimer(
     IN gckHARDWARE Hardware,
-    OUT gctUINT64_PTR Start,
-    OUT gctUINT64_PTR End,
     OUT gctUINT64_PTR On,
     OUT gctUINT64_PTR Off,
     OUT gctUINT64_PTR Idle,
@@ -2491,242 +2136,6 @@ gckINTERRUPT_Notify(
     IN gctBOOL Valid
     );
 #endif
-/******************************************************************************\
-******************************** gckEVENT Object *******************************
-\******************************************************************************/
-
-typedef struct _gckEVENT *      gckEVENT;
-
-/* Construct a new gckEVENT object. */
-gceSTATUS
-gckEVENT_Construct(
-    IN gckKERNEL Kernel,
-    OUT gckEVENT * Event
-    );
-
-/* Destroy an gckEVENT object. */
-gceSTATUS
-gckEVENT_Destroy(
-    IN gckEVENT Event
-    );
-
-/* Reserve the next available hardware event. */
-gceSTATUS
-gckEVENT_GetEvent(
-    IN gckEVENT Event,
-    IN gctBOOL Wait,
-    OUT gctUINT8 * EventID,
-    IN gceKERNEL_WHERE Source
-   );
-
-/* Add a new event to the list of events. */
-gceSTATUS
-gckEVENT_AddList(
-    IN gckEVENT Event,
-    IN gcsHAL_INTERFACE_PTR Interface,
-    IN gceKERNEL_WHERE FromWhere,
-    IN gctBOOL AllocateAllowed,
-    IN gctBOOL FromKernel
-    );
-
-/* Schedule a FreeNonPagedMemory event. */
-gceSTATUS
-gckEVENT_FreeNonPagedMemory(
-    IN gckEVENT Event,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gceKERNEL_WHERE FromWhere
-    );
-
-/* Schedule a FreeContiguousMemory event. */
-gceSTATUS
-gckEVENT_FreeContiguousMemory(
-    IN gckEVENT Event,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gceKERNEL_WHERE FromWhere
-    );
-
-/* Schedule a FreeVideoMemory event. */
-gceSTATUS
-gckEVENT_FreeVideoMemory(
-    IN gckEVENT Event,
-    IN gcuVIDMEM_NODE_PTR VideoMemory,
-    IN gceKERNEL_WHERE FromWhere
-    );
-
-/* Schedule a signal event. */
-gceSTATUS
-gckEVENT_Signal(
-    IN gckEVENT Event,
-    IN gctSIGNAL Signal,
-    IN gceKERNEL_WHERE FromWhere
-    );
-
-/* Schedule an Unlock event. */
-gceSTATUS
-gckEVENT_Unlock(
-    IN gckEVENT Event,
-    IN gceKERNEL_WHERE FromWhere,
-    IN gctPOINTER Node,
-    IN gceSURF_TYPE Type
-    );
-
-/* Schedule a FreeVirtualCommandBuffer event. */
-gceSTATUS
-gckEVENT_DestroyVirtualCommandBuffer(
-    IN gckEVENT Event,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gceKERNEL_WHERE FromWhere
-    );
-
-gceSTATUS
-gckEVENT_Submit(
-    IN gckEVENT Event,
-    IN gctBOOL Wait,
-    IN gctBOOL FromPower
-    );
-
-gceSTATUS
-gckEVENT_Commit(
-    IN gckEVENT Event,
-    IN gcsQUEUE_PTR Queue,
-    IN gctBOOL Forced
-    );
-
-/* Event callback routine. */
-gceSTATUS
-gckEVENT_Notify(
-    IN gckEVENT Event,
-    IN gctUINT32 IDs
-    );
-
-/* Event callback routine. */
-gceSTATUS
-gckEVENT_Interrupt(
-    IN gckEVENT Event,
-    IN gctUINT32 IDs
-    );
-
-gceSTATUS
-gckEVENT_Dump(
-    IN gckEVENT Event
-    );
-/******************************************************************************\
-******************************* gckCOMMAND Object ******************************
-\******************************************************************************/
-
-typedef struct _gckCOMMAND *        gckCOMMAND;
-
-/* Construct a new gckCOMMAND object. */
-gceSTATUS
-gckCOMMAND_Construct(
-    IN gckKERNEL Kernel,
-    OUT gckCOMMAND * Command
-    );
-
-/* Destroy an gckCOMMAND object. */
-gceSTATUS
-gckCOMMAND_Destroy(
-    IN gckCOMMAND Command
-    );
-
-/* Acquire command queue synchronization objects. */
-gceSTATUS
-gckCOMMAND_EnterCommit(
-    IN gckCOMMAND Command,
-    IN gctBOOL FromPower
-    );
-
-/* Release command queue synchronization objects. */
-gceSTATUS
-gckCOMMAND_ExitCommit(
-    IN gckCOMMAND Command,
-    IN gctBOOL FromPower
-    );
-
-/* Start the command queue. */
-gceSTATUS
-gckCOMMAND_Start(
-    IN gckCOMMAND Command
-    );
-
-/* Stop the command queue. */
-gceSTATUS
-gckCOMMAND_Stop(
-    IN gckCOMMAND Command
-    );
-
-gceSTATUS
-gckCOMMAND_Commit(
-    IN gckCOMMAND Command,
-    IN gckCONTEXT Context,
-    IN gcoCMDBUF CommandBuffer,
-    IN gcsSTATE_DELTA_PTR StateDelta,
-    IN gctUINT32 ProcessID,
-    IN gctBOOL Shared,
-    IN gctUINT32 Index,
-    OUT gctUINT64_PTR CommitStamp,
-    OUT gctBOOL_PTR ContextSwitched
-    );
-
-/* Reserve space in the command buffer. */
-gceSTATUS
-gckCOMMAND_Reserve(
-    IN gckCOMMAND Command,
-    IN gctUINT32 RequestedBytes,
-    OUT gctPOINTER * Buffer,
-    OUT gctUINT32 * BufferSize
-    );
-
-/* Execute reserved space in the command buffer. */
-gceSTATUS
-gckCOMMAND_Execute(
-    IN gckCOMMAND Command,
-    IN gctUINT32 RequstedBytes
-    );
-
-/* Stall the command queue. */
-gceSTATUS
-gckCOMMAND_Stall(
-    IN gckCOMMAND Command,
-    IN gctBOOL FromPower
-    );
-
-/* Attach user process. */
-gceSTATUS
-gckCOMMAND_Attach(
-    IN gckCOMMAND Command,
-    OUT gckCONTEXT * Context,
-    OUT gctSIZE_T * MaxState,
-    OUT gctUINT32 * NumStates,
-    IN gctUINT32 ProcessID
-    );
-
-/* Detach user process. */
-gceSTATUS
-gckCOMMAND_Detach(
-    IN gckCOMMAND Command,
-    IN gckCONTEXT Context
-    );
-
-/* Dump command buffer being executed by GPU. */
-gceSTATUS
-gckCOMMAND_DumpExecutingBuffer(
-    IN gckCOMMAND Command
-    );
-
-/* Whether a kernel command buffer address. */
-gceSTATUS
-gckCOMMAND_AddressInKernelCommandBuffer(
-    IN gckCOMMAND Command,
-    IN gctUINT32 Address,
-    OUT gctPOINTER * Pointer
-    );
 
 /******************************************************************************\
 ********************************* gckMMU Object ********************************
@@ -2751,6 +2160,7 @@ gceSTATUS
 gckMMU_AllocatePages(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
+    IN gcePAGE_TYPE PageType,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
     );
@@ -2759,7 +2169,8 @@ gceSTATUS
 gckMMU_AllocatePagesEx(
     IN gckMMU Mmu,
     IN gctSIZE_T PageCount,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
+    IN gcePAGE_TYPE PageType,
     IN gctBOOL Secure,
     OUT gctPOINTER * PageTable,
     OUT gctUINT32 * Address
@@ -2770,6 +2181,7 @@ gceSTATUS
 gckMMU_FreePages(
     IN gckMMU Mmu,
     IN gctBOOL Secure,
+    IN gcePAGE_TYPE PageType,
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctSIZE_T PageCount
@@ -2780,6 +2192,7 @@ gceSTATUS
 gckMMU_SetPage(
    IN gckMMU Mmu,
    IN gctPHYS_ADDR_T PageAddress,
+   IN gcePAGE_TYPE PageType,
    IN gctBOOL Writable,
    IN gctUINT32 *PageEntry
    );
@@ -2787,29 +2200,37 @@ gckMMU_SetPage(
 gceSTATUS
 gckMMU_Flush(
     IN gckMMU Mmu,
-    IN gceSURF_TYPE Type
+    IN gceVIDMEM_TYPE Type
     );
 
 gceSTATUS
 gckMMU_DumpPageTableEntry(
     IN gckMMU Mmu,
+    IN gceAREA_TYPE AreaType,
     IN gctUINT32 Address
     );
 
 gceSTATUS
 gckMMU_FillFlatMapping(
     IN gckMMU Mmu,
-    IN gctUINT32 PhysBase,
+    IN gctUINT64 PhysBase,
     IN gctSIZE_T Size
     );
 
 gceSTATUS
 gckMMU_IsFlatMapped(
     IN gckMMU Mmu,
-    OUT gctUINT32 Physical,
+    IN gctUINT64 Physical,
+    IN gctUINT32 Address,
     OUT gctBOOL *In
     );
 
+gceSTATUS
+gckMMU_GetAreaType(
+    IN gckMMU Mmu,
+    IN gctUINT32 GpuAddress,
+    OUT gceAREA_TYPE *AreaType
+    );
 
 gceSTATUS
 gckHARDWARE_QueryContextProfile(
index fd52383..2c22702 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -58,7 +58,8 @@
 
 #include "gc_hal_enum.h"
 #include "gc_hal_types.h"
-#include "gc_hal_dump.h"
+#include "gc_hal_debug_zones.h"
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -76,6 +77,7 @@ typedef struct gcsATOM *                gcsATOM_PTR;
 
 typedef struct _gco3D *                 gco3D;
 typedef struct _gcoCL *                 gcoCL;
+typedef struct _gcoVX *                 gcoVX;
 typedef struct _gcsFAST_FLUSH *         gcsFAST_FLUSH_PTR;
 
 typedef struct _gcoSURF *               gcoSURF;
@@ -85,10 +87,10 @@ typedef struct _gcsPOINT *              gcsPOINT_PTR;
 typedef struct _gcsSIZE *               gcsSIZE_PTR;
 typedef struct _gcsRECT *               gcsRECT_PTR;
 typedef struct _gcsBOUNDARY *           gcsBOUNDARY_PTR;
-typedef struct _gcoDUMP *               gcoDUMP;
 typedef struct _gcoHARDWARE *           gcoHARDWARE;
 typedef union  _gcuVIDMEM_NODE *        gcuVIDMEM_NODE_PTR;
 typedef struct _gcsVIDMEM_NODE *        gckVIDMEM_NODE;
+typedef struct _gcsVIDMEM_BLOCK *       gckVIDMEM_BLOCK;
 
 #if gcdENABLE_VG
 typedef struct _gcoVG *                 gcoVG;
@@ -111,6 +113,105 @@ gceFENCE_TYPE;
 
 typedef struct _gcsUSER_MEMORY_DESC *   gcsUSER_MEMORY_DESC_PTR;
 
+/* Immuatable features from database */
+typedef struct _gcsNN_FIXED_FEATURE
+{
+    gctUINT  vipCoreCount;
+    gctUINT  nnCoreCount;           /* total nn core count */
+    gctUINT  nnCoreCountInt8;       /* total nn core count supporting int8 */
+    gctUINT  nnCoreCountInt16;      /* total nn core count supporting int16 */
+    gctUINT  nnCoreCountFloat16;    /* total nn core count supporting float16 */
+    gctUINT  nnMadPerCore;
+    gctUINT  nnInputBufferDepth;
+    gctUINT  nnAccumBufferDepth;
+    gctUINT  nnFCNonPrunAccel;
+    gctUINT  nnInImageOffsetBits;
+    gctUINT  tpCoreCount; /* full-function core count */
+    gctUINT  tpPwlLUTCount;
+    gctUINT  tpPwlLUTSize;
+    gctUINT  vip7Version;
+    gctUINT  vipBrickMode;
+    gctUINT  tpReorderInImageSize;
+    gctUINT  tpliteCoreCount; /* fc-only core count */
+    gctUINT  nnFP16XYDPX;
+    gctUINT  nnFP16XYDPY;
+    gctUINT  nnFP16ZDP;
+    gctUINT  zrlBits;
+    gctUINT  uscCacheControllers;
+    gctUINT  uscBanks;
+    gctUINT  nnLanesPerOutCycle;
+    gctUINT  maxOTNumber;
+    gctUINT  equivalentVipsramWidthInByte;
+    gctUINT  shaderCoreCount;
+} gcsNN_FIXED_FEATURE;
+
+/* Features can be customized from outside */
+typedef struct _gcsNN_CUSTOMIZED_FEATURE
+{
+    gctUINT  vipSRAMSize;
+    gctUINT  axiSRAMSize;
+    gctFLOAT ddrReadBWLimit;
+    gctFLOAT ddrWriteBWLimit;
+    gctFLOAT ddrTotalBWLimit;
+    gctFLOAT axiSramReadBWLimit;
+    gctFLOAT axiSramWriteBWLimit;
+    gctFLOAT axiSramTotalBWLimit;
+    gctFLOAT axiBusReadBWLimit;
+    gctFLOAT axiBusWriteBWLimit;
+    gctFLOAT axiBusTotalBWLimit;
+    gctUINT  vipSWTiling;
+    gctFLOAT ddrLatency;
+    gctUINT  freqInMHZ;
+    gctUINT  axiClockFreqInMHZ;
+    gctUINT  maxSocOTNumber;/*max SOC outstanding transfer number*/
+    gctUINT  nnWriteWithoutUSC;
+    gctUINT  depthWiseSupport;
+    gctUINT  vipVectorPrune;
+} gcsNN_CUSTOMIZED_FEATURE;
+
+/* Features are unified (hardcoded) for hardwares */
+typedef struct _gcsNN_UNIFIED_FEATURE
+{
+    gctUINT  nnUSCCacheSize;
+    gctUINT  nnCmdSizeInBytes;
+    gctUINT  tpCmdSizeInBytes;
+    gctUINT  vipCoefDecodePerf;
+    gctUINT  vipCachedReadFromSram;
+    gctUINT  vipImagePartialCache;
+    gctUINT  lanesPerConv;
+    gctUINT  maxTileSize;
+    gctUINT  fullCacheKernelHeadFix : 1;
+    gctUINT  conv1x1HalfPerformance : 1;
+    gctUINT  per3DTileBubbleFix : 1;
+    gctUINT  cacheLineModeDisabled : 1;
+    gctUINT  tpReOrderFix : 1;
+    gctUINT  zdp3NoCompressFix : 1;
+    gctUINT  asyncCopyPerfFix : 1;
+    gctUINT  accurateTileBW : 1;
+    gctUINT  zxdp3KernelReadConflictFix : 1;
+    gctUINT  axiSramSlowedDownByAddr:1;
+    gctUINT  slowNNReqArbitrationFix:1;
+    gctUINT  singlePortAccBuffer : 1;
+    gctUINT  convOutFifoDepthFix : 1;
+    gctUINT  smallBatchEnable : 1;
+    gctUINT  axiSramOnlySWTiling : 1;
+    gctUINT  imageNotPackedInSram : 1;
+    gctUINT  coefDeltaCordOverFlowZRL8BitFix : 1;
+    gctUINT  xyOffsetLimitationFix : 1;
+} gcsNN_UNIFIED_FEATURE;
+
+/* Features are derived from above ones */
+typedef struct _gcsNN_DERIVIED_FEATURE
+{
+    gctUINT  nnDPAmount;
+    gctUINT  nnXYDPX;
+    gctUINT  nnXYDPY;
+    gctUINT  nnZDP;
+    gctFLOAT totalLatency;
+    gctFLOAT internalLatency;
+    gctFLOAT ddrReadBWInBytePerCycle;
+    gctFLOAT ddrWriteBWInBytePerCycle;
+} gcsNN_DERIVED_FEATURE;
 
 /******************************************************************************\
 ********************* Share obj lock/unlock macros. ****************************
@@ -141,20 +242,18 @@ typedef struct _gcsSystemInfo
 gcsSystemInfo;
 
 
-#if gcdENABLE_3D
-#if gcdSYNC
 #define gcPLS_INITIALIZER \
 { \
     gcvNULL, /* gcoOS object.      */ \
     gcvNULL, /* gcoHAL object.     */ \
     0, /* internalSize       */ \
-    gcvNULL, /* internalPhysical   */ \
+    0, /* internalPhysName   */ \
     gcvNULL, /* internalLogical    */ \
     0, /* externalSize       */ \
-    gcvNULL, /* externalPhysical   */ \
+    0, /* externalPhysName   */ \
     gcvNULL, /* externalLogical    */ \
     0, /* contiguousSize     */ \
-    gcvNULL, /* contiguousPhysical */ \
+    0, /* contiguousPhysName */ \
     gcvNULL, /* contiguousLogical  */ \
     gcvNULL, /* eglDisplayInfo     */ \
     gcvNULL, /* eglSurfaceInfo     */ \
@@ -171,64 +270,21 @@ gcsSystemInfo;
     gcvNULL, /* CL FE compiler lock*/ \
     gcvPATCH_NOTINIT,/* global patchID     */ \
     gcvNULL, /* global fenceID*/ \
+    gcvFALSE, /* memory profile flag */ \
+    gcvNULL, /* profileLock;        */ \
+    0, /* allocCount;         */ \
+    0, /* allocSize;          */ \
+    0, /* maxAllocSize;       */ \
+    0, /* freeCount;          */ \
+    0, /* freeSize;           */ \
+    0, /* currentSize;        */ \
+    0, /* video_allocCount;   */ \
+    0, /* video_allocSize;    */ \
+    0, /* video_maxAllocSize; */ \
+    0, /* video_freeCount;    */ \
+    0, /* video_freeSize;     */ \
+    0, /* video_currentSize;  */ \
 }
-#else
-#define gcPLS_INITIALIZER \
-{ \
-    gcvNULL, /* gcoOS object.      */ \
-    gcvNULL, /* gcoHAL object.     */ \
-    0, /* internalSize       */ \
-    gcvNULL, /* internalPhysical   */ \
-    gcvNULL, /* internalLogical    */ \
-    0, /* externalSize       */ \
-    gcvNULL, /* externalPhysical   */ \
-    gcvNULL, /* externalLogical    */ \
-    0, /* contiguousSize     */ \
-    gcvNULL, /* contiguousPhysical */ \
-    gcvNULL, /* contiguousLogical  */ \
-    gcvNULL, /* eglDisplayInfo     */ \
-    gcvNULL, /* eglSurfaceInfo     */ \
-    gcvSURF_A8R8G8B8,/* eglConfigFormat    */ \
-    gcvNULL, /* reference          */ \
-    0, /* processID          */ \
-    0, /* threadID           */ \
-    gcvFALSE, /* exiting            */ \
-    gcvFALSE, /* Special flag for NP2 texture. */ \
-    gcvFALSE, /* device open.       */ \
-    gcvNULL, /* destructor         */ \
-    gcvNULL, /* accessLock         */ \
-    gcvNULL, /* GL FE compiler lock*/ \
-    gcvNULL, /* CL FE compiler lock*/ \
-    gcvPATCH_NOTINIT,/* global patchID     */ \
-}
-#endif
-#else
-#define gcPLS_INITIALIZER \
-{ \
-    gcvNULL, /* gcoOS object.      */ \
-    gcvNULL, /* gcoHAL object.     */ \
-    0, /* internalSize       */ \
-    gcvNULL, /* internalPhysical   */ \
-    gcvNULL, /* internalLogical    */ \
-    0, /* externalSize       */ \
-    gcvNULL, /* externalPhysical   */ \
-    gcvNULL, /* externalLogical    */ \
-    0, /* contiguousSize     */ \
-    gcvNULL, /* contiguousPhysical */ \
-    gcvNULL, /* contiguousLogical  */ \
-    gcvNULL, /* eglDisplayInfo     */ \
-    gcvNULL, /* eglSurfaceInfo     */ \
-    gcvSURF_A8R8G8B8,/* eglConfigFormat    */ \
-    gcvNULL, /* reference          */ \
-    0, /* processID          */ \
-    0, /* threadID           */ \
-    gcvFALSE, /* exiting            */ \
-    gcvFALSE, /* Special flag for NP2 texture. */ \
-    gcvFALSE, /* device open.       */ \
-    gcvNULL, /* destructor        */ \
-    gcvNULL, /* accessLock        */ \
-}
-#endif
 
 /******************************************************************************\
 ******************************* Thread local storage *************************
@@ -286,7 +342,9 @@ typedef struct _gcsTLS
 #if gcdDUMP_2D
     gctUINT32                   newDump2DFlag;
 #endif
+
 #endif
+    gcoVX                       engineVX;
 
     gctBOOL                     copied;
 
@@ -323,9 +381,9 @@ typedef enum _gcePOOL
     gcvPOOL_LOCAL_EXTERNAL,
     gcvPOOL_UNIFIED,
     gcvPOOL_SYSTEM,
+    gcvPOOL_SRAM,
     gcvPOOL_VIRTUAL,
     gcvPOOL_USER,
-    gcvPOOL_CONTIGUOUS,
 
     gcvPOOL_NUMBER_OF_POOLS
 }
@@ -465,7 +523,7 @@ typedef struct _gcsHAL_CHIPIDENTITY
     gctUINT32                   customerID;
     gctUINT32                   ecoID;
     gceCHIP_FLAG                chipFlags;
-    gctUINT32                   platformFlagBits;
+    gctUINT64                   platformFlagBits;
 }
 gcsHAL_CHIPIDENTITY;
 
@@ -573,7 +631,8 @@ gcoHAL_Get3DEngine(
 gceSTATUS
 gcoHAL_GetProductName(
     IN gcoHAL Hal,
-    OUT gctSTRING *ProductName
+    OUT gctSTRING *ProductName,
+    OUT gctUINT *PID
     );
 
 gceSTATUS
@@ -625,12 +684,6 @@ gcoHAL_IsFeatureAvailable(
     IN gceFEATURE Feature
     );
 
-gceSTATUS
-gcoHAL_IsSwwaNeeded(
-    IN gcoHAL Hal,
-    IN gceSWWA Swwa
-    );
-
 gceSTATUS
 gcoHAL_IsFeatureAvailable1(
     IN gcoHAL Hal,
@@ -671,6 +724,14 @@ gcoHAL_QueryMultiGPUAffinityConfig(
     OUT gctUINT32_PTR CoreIndex
     );
 
+gceSTATUS
+gcoHAL_QuerySRAM(
+    IN gcoHAL Hal,
+    IN gceSRAM Type,
+    OUT gctUINT32 *Base,
+    OUT gctUINT32 *Size
+    );
+
 #ifdef LINUX
 gctINT32
 gcoOS_EndRecordAllocation(void);
@@ -684,11 +745,11 @@ gcoOS_AddRecordAllocation(gctSIZE_T Size);
 gceSTATUS
 gcoHAL_QueryVideoMemory(
     IN gcoHAL Hal,
-    OUT gctPHYS_ADDR * InternalAddress,
+    OUT gctUINT32 * InternalPhysName,
     OUT gctSIZE_T * InternalSize,
-    OUT gctPHYS_ADDR * ExternalAddress,
+    OUT gctUINT32 * ExternalPhysName,
     OUT gctSIZE_T * ExternalSize,
-    OUT gctPHYS_ADDR * ContiguousAddress,
+    OUT gctUINT32 * ContiguousPhysName,
     OUT gctSIZE_T * ContiguousSize
     );
 
@@ -696,7 +757,7 @@ gcoHAL_QueryVideoMemory(
 gceSTATUS
 gcoHAL_MapMemory(
     IN gcoHAL Hal,
-    IN gctPHYS_ADDR Physical,
+    IN gctUINT32 PhysName,
     IN gctSIZE_T NumberOfBytes,
     OUT gctPOINTER * Logical
     );
@@ -705,7 +766,7 @@ gcoHAL_MapMemory(
 gceSTATUS
 gcoHAL_UnmapMemory(
     IN gcoHAL Hal,
-    IN gctPHYS_ADDR Physical,
+    IN gctUINT32 PhysName,
     IN gctSIZE_T NumberOfBytes,
     IN gctPOINTER Logical
     );
@@ -714,7 +775,7 @@ gcoHAL_UnmapMemory(
 gceSTATUS
 gcoHAL_ScheduleUnmapMemory(
     IN gcoHAL Hal,
-    IN gctPHYS_ADDR Physical,
+    IN gctUINT32 PhysName,
     IN gctSIZE_T NumberOfBytes,
     IN gctPOINTER Logical
     );
@@ -745,39 +806,10 @@ gcoOS_LockVideoMemory(
     IN gctPOINTER Handle,
     IN gctBOOL InUserSpace,
     IN gctBOOL InCacheable,
-    OUT gctUINT32 * Physical,
+    OUT gctUINT32 * Address,
     OUT gctPOINTER * Logical
     );
 
-/* Map user memory. */
-gceSTATUS
-gcoHAL_MapUserMemory(
-    IN gctPOINTER Logical,
-    IN gctUINT32 Physical,
-    IN gctSIZE_T Size,
-    OUT gctPOINTER * Info,
-    OUT gctUINT32_PTR GPUAddress
-    );
-
-/* Unmap user memory. */
-gceSTATUS
-gcoHAL_UnmapUserMemory(
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Size,
-    IN gctPOINTER Info,
-    IN gctUINT32 GPUAddress
-    );
-
-/* Schedule an unmap of a user buffer using event mechanism. */
-gceSTATUS
-gcoHAL_ScheduleUnmapUserMemory(
-    IN gcoHAL Hal,
-    IN gctPOINTER Info,
-    IN gctSIZE_T Size,
-    IN gctUINT32 Address,
-    IN gctPOINTER Memory
-    );
-
 /* Commit the current command buffer. */
 gceSTATUS
 gcoHAL_Commit(
@@ -808,7 +840,7 @@ gcoHAL_Compact(
     IN gcoHAL Hal
     );
 
-#if VIVANTE_PROFILER
+#if VIVANTE_PROFILER_SYSTEM_MEMORY
 gceSTATUS
 gcoHAL_ProfileStart(
     IN gcoHAL Hal
@@ -841,12 +873,6 @@ gcoHAL_SetFilterType(
     IN gceFILTER_TYPE FilterType
     );
 
-gceSTATUS
-gcoHAL_GetDump(
-    IN gcoHAL Hal,
-    OUT gcoDUMP * Dump
-    );
-
 /* Call the kernel HAL layer. */
 gceSTATUS
 gcoHAL_Call(
@@ -908,6 +934,15 @@ gcoHAL_Query3DCoreCount(
     OUT gctUINT32  *Count
     );
 
+gceSTATUS
+gcoHAL_QueryCluster(
+    IN gcoHAL       Hal,
+    OUT gctINT32   *ClusterMinID,
+    OUT gctINT32   *ClusterMaxID,
+    OUT gctUINT32  *ClusterCount,
+    OUT gctUINT32  *ClusterIDWidth
+    );
+
 gceSTATUS
 gcoHAL_QueryCoreCount(
     IN gcoHAL Hal,
@@ -962,6 +997,29 @@ gcoHAL_GetCurrentCoreIndex(
     OUT gctUINT32 *Core
     );
 
+gceSTATUS
+gcoHAL_SelectChannel(
+    IN gcoHAL Hal,
+    IN gctBOOL Priority,
+    IN gctUINT32 ChannelId
+    );
+
+gceSTATUS
+gcoHAL_MCFESemaphore(
+    IN gctUINT32        SemaHandle,
+    IN gctBOOL          SendSema
+    );
+
+gceSTATUS
+gcoHAL_AllocateMCFESemaphore(
+    OUT gctUINT32 *     SemaHandle
+    );
+
+gceSTATUS
+gcoHAL_FreeMCFESemaphore(
+    IN gctUINT32        SemaHandle
+    );
+
 /*----------------------------------------------------------------------------*/
 /*----- Shared Buffer --------------------------------------------------------*/
 
@@ -1010,7 +1068,7 @@ gcoHAL_ConfigPowerManagement(
 gceSTATUS
 gcoHAL_AllocateVideoMemory(
     IN gctUINT Alignment,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     IN gctUINT32 Flag,
     IN gcePOOL Pool,
     IN OUT gctSIZE_T * Bytes,
@@ -1022,14 +1080,14 @@ gcoHAL_LockVideoMemory(
     IN gctUINT32 Node,
     IN gctBOOL Cacheable,
     IN gceENGINE engine,
-    OUT gctUINT32 * Physical,
+    OUT gctUINT32 * Address,
     OUT gctPOINTER * Logical
     );
 
 gceSTATUS
 gcoHAL_UnlockVideoMemory(
     IN gctUINT32 Node,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     IN gceENGINE engine
     );
 
@@ -1038,14 +1096,6 @@ gcoHAL_ReleaseVideoMemory(
     IN gctUINT32 Node
     );
 
-gceSTATUS
-gcoHAL_AllocateContiguous(
-    IN gcoOS Os,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctPHYS_ADDR * Physical,
-    OUT gctPOINTER * Logical
-    );
-
 #if gcdENABLE_3D || gcdENABLE_VG
 /* Query the target capabilities. */
 gceSTATUS
@@ -1061,6 +1111,7 @@ gcoHAL_QueryTargetCaps(
 gceSTATUS
 gcoHAL_WrapUserMemory(
     IN gcsUSER_MEMORY_DESC_PTR UserMemoryDesc,
+    IN gceVIDMEM_TYPE Type,
     OUT gctUINT32_PTR Node
     );
 
@@ -1221,7 +1272,11 @@ gcoOS_Destroy(
     IN gcoOS Os
     );
 
-/* Get the base address for the physical memory. */
+/* Deprecated API: please use gcoHAL_GetBaseAddr() instead.
+**                 This API was kept only for legacy BSP usage.
+**
+** Get the base address for the physical memory.
+*/
 gceSTATUS
 gcoOS_GetBaseAddress(
     IN gcoOS Os,
@@ -1281,52 +1336,6 @@ gcoOS_FreeMemory(
     IN gctPOINTER Memory
     );
 
-/* Free contiguous memory. */
-gceSTATUS
-gcoOS_FreeContiguous(
-    IN gcoOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    );
-
-/* Map user memory. */
-gceSTATUS
-gcoOS_MapUserMemory(
-    IN gcoOS Os,
-    IN gctPOINTER Memory,
-    IN gctSIZE_T Size,
-    OUT gctPOINTER * Info,
-    OUT gctUINT32_PTR Address
-    );
-
-/* Map user memory. */
-gceSTATUS
-gcoOS_MapUserMemoryEx(
-    IN gcoOS Os,
-    IN gctPOINTER Memory,
-    IN gctUINT32 Physical,
-    IN gctSIZE_T Size,
-    OUT gctPOINTER * Info,
-    OUT gctUINT32_PTR Address
-    );
-
-/* Unmap user memory. */
-gceSTATUS
-gcoOS_UnmapUserMemory(
-    IN gcoOS Os,
-    IN gctPOINTER Memory,
-    IN gctSIZE_T Size,
-    IN gctPOINTER Info,
-    IN gctUINT32 Address
-    );
-
-gceSTATUS
-gcoOS_CPUPhysicalToGPUPhysical(
-    IN gctUINT32 CPUPhysical,
-    OUT gctUINT32_PTR GPUPhysical
-    );
-
 /* Device I/O Control call to the kernel HAL layer. */
 gceSTATUS
 gcoOS_DeviceControl(
@@ -1338,25 +1347,6 @@ gcoOS_DeviceControl(
     IN gctSIZE_T OutputBufferSize
     );
 
-/* Allocate non paged memory. */
-gceSTATUS
-gcoOS_AllocateNonPagedMemory(
-    IN gcoOS Os,
-    IN gctBOOL InUserSpace,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctPHYS_ADDR * Physical,
-    OUT gctPOINTER * Logical
-    );
-
-/* Free non paged memory. */
-gceSTATUS
-gcoOS_FreeNonPagedMemory(
-    IN gcoOS Os,
-    IN gctSIZE_T Bytes,
-    IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical
-    );
-
 #define gcmOS_SAFE_FREE(os, mem) \
     gcoOS_Free(os, mem); \
     mem = gcvNULL
@@ -1398,6 +1388,13 @@ gcoOS_Close(
     IN gctFILE File
     );
 
+/* Remove a file. */
+gceSTATUS
+gcoOS_Remove(
+    IN gcoOS Os,
+    IN gctCONST_STRING FileName
+    );
+
 /* Read data from a file. */
 gceSTATUS
 gcoOS_Read(
@@ -1448,6 +1445,22 @@ gcoOS_DupFD(
     OUT gctINT * FD2
     );
 
+/* Lock a file. */
+gceSTATUS
+gcoOS_LockFile(
+    IN gcoOS Os,
+    IN gctFILE File,
+    IN gctBOOL Shared,
+    IN gctBOOL Block
+    );
+
+/* Unlock a file. */
+gceSTATUS
+gcoOS_UnlockFile(
+    IN gcoOS Os,
+    IN gctFILE File
+    );
+
 /* Create an endpoint for communication. */
 gceSTATUS
 gcoOS_Socket(
@@ -1692,7 +1705,7 @@ gcoOS_AddSignalHandler (
     IN gceSignalHandlerType SignalHandlerType
     );
 
-#if VIVANTE_PROFILER
+#if VIVANTE_PROFILER_SYSTEM_MEMORY
 gceSTATUS
 gcoOS_ProfileStart(
     IN gcoOS Os
@@ -1722,11 +1735,11 @@ gcoOS_GetPhysicalSystemMemorySize(
 gceSTATUS
 gcoOS_QueryVideoMemory(
     IN gcoOS Os,
-    OUT gctPHYS_ADDR * InternalAddress,
+    OUT gctUINT32 * InternalPhysName,
     OUT gctSIZE_T * InternalSize,
-    OUT gctPHYS_ADDR * ExternalAddress,
+    OUT gctUINT32 * ExternalPhysName,
     OUT gctSIZE_T * ExternalSize,
-    OUT gctPHYS_ADDR * ContiguousAddress,
+    OUT gctUINT32 * ContiguousPhysName,
     OUT gctSIZE_T * ContiguousSize
     );
 
@@ -2024,8 +2037,8 @@ gcoOS_MemoryBarrier(
 
 gceSTATUS
 gcoOS_CPUPhysicalToGPUPhysical(
-    IN gctUINT32 CPUPhysical,
-    OUT gctUINT32_PTR GPUPhysical
+    IN gctPHYS_ADDR_T CPUPhysical,
+    OUT gctPHYS_ADDR_T * GPUPhysical
     );
 
 gceSTATUS
@@ -2034,6 +2047,7 @@ gcoOS_QuerySystemInfo(
     OUT gcsSystemInfo *Info
     );
 
+
 /*----------------------------------------------------------------------------*/
 /*----- Profile --------------------------------------------------------------*/
 
@@ -2062,6 +2076,16 @@ gcoOS_QueryProfileTickRate(
     OUT gctUINT64_PTR TickRate
     );
 
+#if gcdSTATIC_LINK && defined(WIN32)
+void gcoOS_ModuleConstructor(
+    void
+    );
+
+void gcoOS_ModuleDestructor(
+    void
+    );
+#endif
+
 #define _gcmPROFILE_INIT(prefix, freq, start) \
     do { \
         prefix ## OS_QueryProfileTickRate(&(freq)); \
@@ -2455,7 +2479,7 @@ gcoSURF_MapUserSurface(
     IN gcoSURF Surface,
     IN gctUINT Alignment,
     IN gctPOINTER Logical,
-    IN gctUINT32 Physical
+    IN gctPHYS_ADDR_T Physical
     );
 
 /* Wrapp surface with known logical/GPU address */
@@ -2464,7 +2488,7 @@ gcoSURF_WrapSurface(
     IN gcoSURF Surface,
     IN gctUINT Alignment,
     IN gctPOINTER Logical,
-    IN gctUINT32 Physical
+    IN gctUINT32 Address
     );
 
 
@@ -2749,7 +2773,7 @@ gcoSURF_SetBuffer(
     IN gceSURF_FORMAT Format,
     IN gctUINT Stride,
     IN gctPOINTER Logical,
-    IN gctUINT32 Physical
+    IN gctUINT64 Physical
     );
 
 /* Set the size of the surface in pixels and map the underlying buffer. */
@@ -3000,83 +3024,31 @@ gcoSURF_MixSurfacesCPU(
     IN gctINT Count
     );
 
-
 /******************************************************************************\
-********************************* gcoDUMP Object ********************************
+******************************* Hash Structure ******************************
 \******************************************************************************/
 
-/* Construct a new gcoDUMP object. */
-gceSTATUS
-gcoDUMP_Construct(
-    IN gcoOS Os,
-    IN gcoHAL Hal,
-    OUT gcoDUMP * Dump
-    );
-
-/* Destroy a gcoDUMP object. */
-gceSTATUS
-gcoDUMP_Destroy(
-    IN gcoDUMP Dump
-    );
-
-/* Enable/disable dumping. */
-gceSTATUS
-gcoDUMP_Control(
-    IN gcoDUMP Dump,
-    IN gctSTRING FileName
-    );
+typedef struct _gcsHASH_MD5CTX
+{
+    gctBOOL   bigEndian;
+    gctSIZE_T bytes;     /* Number of bytes processed */
+    gctUINT32 states[4];
+    gctUINT8  buffer[64];
+} gcsHASH_MD5CTX;
 
-gceSTATUS
-gcoDUMP_IsEnabled(
-    IN gcoDUMP Dump,
-    OUT gctBOOL * Enabled
+void gcsHASH_MD5Init(
+    gcsHASH_MD5CTX *ctx
     );
-
-/* Add surface. */
-gceSTATUS
-gcoDUMP_AddSurface(
-    IN gcoDUMP Dump,
-    IN gctINT32 Width,
-    IN gctINT32 Height,
-    IN gceSURF_FORMAT PixelFormat,
-    IN gctUINT32 Address,
-    IN gctSIZE_T ByteCount
+void gcsHASH_MD5Update(
+    gcsHASH_MD5CTX *ctx,
+    const void *data,
+    gctSIZE_T bytes
     );
-
-/* Mark the beginning of a frame. */
-gceSTATUS
-gcoDUMP_FrameBegin(
-    IN gcoDUMP Dump
+void gcsHASH_MD5Final(
+    gcsHASH_MD5CTX *ctx,
+    gctUINT8 digest[16]
     );
 
-/* Mark the end of a frame. */
-gceSTATUS
-gcoDUMP_FrameEnd(
-    IN gcoDUMP Dump
-    );
-
-/* Dump data. */
-gceSTATUS
-gcoDUMP_DumpData(
-    IN gcoDUMP Dump,
-    IN gceDUMP_TAG Type,
-    IN gctUINT32 Address,
-    IN gctSIZE_T ByteCount,
-    IN gctCONST_POINTER Data
-    );
-
-/* Delete an address. */
-gceSTATUS
-gcoDUMP_Delete(
-    IN gcoDUMP Dump,
-    IN gctUINT32 Address
-    );
-
-/* Enable dump or not. */
-gceSTATUS
-gcoDUMP_SetDumpFlag(
-    IN gctBOOL DumpState
-    );
 
 /******************************************************************************\
 ******************************* gcsRECT Structure ******************************
@@ -3204,7 +3176,7 @@ gcoHEAP_Free(
     IN gctPOINTER Node
     );
 
-#if (VIVANTE_PROFILER  || gcdDEBUG)
+#if (VIVANTE_PROFILER_SYSTEM_MEMORY  || gcdDEBUG)
 /* Profile the heap. */
 gceSTATUS
 gcoHEAP_ProfileStart(
@@ -3218,7 +3190,6 @@ gcoHEAP_ProfileEnd(
     );
 #endif
 
-
 /******************************************************************************\
 ******************************* Debugging Macros *******************************
 \******************************************************************************/
@@ -3233,11 +3204,6 @@ gcoOS_GetDebugLevel(
     OUT gctUINT32_PTR DebugLevel
     );
 
-void
-gcoOS_SetDebugZone(
-    IN gctUINT32 Zone
-    );
-
 void
 gcoOS_GetDebugZone(
     IN gctUINT32 Zone,
@@ -3245,20 +3211,18 @@ gcoOS_GetDebugZone(
     );
 
 void
-gcoOS_SetDebugLevelZone(
-    IN gctUINT32 Level,
+gcoOS_SetDebugZone(
     IN gctUINT32 Zone
     );
 
 void
-gcoOS_SetDebugZones(
-    IN gctUINT32 Zones,
-    IN gctBOOL Enable
+gcoOS_SetDebugFile(
+    IN gctCONST_STRING FileName
     );
 
 void
-gcoOS_SetDebugFile(
-    IN gctCONST_STRING FileName
+gcoOS_EnableDebugDump(
+    IN gctBOOL Enable
     );
 
 gctFILE
@@ -3336,14 +3300,6 @@ gckOS_DebugTrace(
     ...
     );
 
-void
-gckOS_DebugTraceN(
-    IN gctUINT32 Level,
-    IN gctUINT ArgumentSize,
-    IN gctCONST_STRING Message,
-    ...
-    );
-
 void
 gcoOS_DebugTrace(
     IN gctUINT32 Level,
@@ -3354,7 +3310,8 @@ gcoOS_DebugTrace(
 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
 #   define gcmTRACE             gcoOS_DebugTrace
 #   define gcmkTRACE            gckOS_DebugTrace
-#   define gcmkTRACE_N          gckOS_DebugTraceN
+#   define gcmkTRACE_N(Level, ArgumentSize, ...) \
+        gckOS_DebugTrace(Level, __VA_ARGS__)
 #elif gcdHAS_ELLIPSIS
 #   define gcmTRACE(...)
 #   define gcmkTRACE(...)
@@ -3384,80 +3341,6 @@ gcoOS_DebugTrace(
 #   define gcmkTRACE_N          __dummy_trace_n
 #endif
 
-/* Zones common for kernel and user. */
-#define gcvZONE_OS              (1 << 0)
-#define gcvZONE_HARDWARE        (1 << 1)
-#define gcvZONE_HEAP            (1 << 2)
-#define gcvZONE_SIGNAL          (1 << 3)
-
-/* Kernel zones. */
-#define gcvZONE_KERNEL          (1 << 4)
-#define gcvZONE_VIDMEM          (1 << 5)
-#define gcvZONE_COMMAND         (1 << 6)
-#define gcvZONE_DRIVER          (1 << 7)
-#define gcvZONE_CMODEL          (1 << 8)
-#define gcvZONE_MMU             (1 << 9)
-#define gcvZONE_EVENT           (1 << 10)
-#define gcvZONE_DEVICE          (1 << 11)
-#define gcvZONE_DATABASE        (1 << 12)
-#define gcvZONE_INTERRUPT       (1 << 13)
-#define gcvZONE_POWER           (1 << 14)
-#define gcvZONE_ASYNC_COMMAND   (1 << 15)
-#define gcvZONE_ALLOCATOR       (1 << 16)
-
-/* User zones. */
-#define gcvZONE_HAL             (1 << 4)
-#define gcvZONE_BUFFER          (1 << 5)
-#define gcvZONE_CONTEXT         (1 << 6)
-#define gcvZONE_SURFACE         (1 << 7)
-#define gcvZONE_INDEX           (1 << 8)
-#define gcvZONE_STREAM          (1 << 9)
-#define gcvZONE_TEXTURE         (1 << 10)
-#define gcvZONE_2D              (1 << 11)
-#define gcvZONE_3D              (1 << 12)
-#define gcvZONE_COMPILER        (1 << 13)
-#define gcvZONE_MEMORY          (1 << 14)
-#define gcvZONE_STATE           (1 << 15)
-#define gcvZONE_AUX             (1 << 16)
-#define gcvZONE_VERTEX          (1 << 17)
-#define gcvZONE_CL              (1 << 18)
-#define gcvZONE_VG              (1 << 19)
-#define gcvZONE_VX              (1 << 20)
-#define gcvZONE_IMAGE           (1 << 21)
-#define gcvZONE_UTILITY         (1 << 22)
-#define gcvZONE_PARAMETERS      (1 << 23)
-#define gcvZONE_BUFOBJ          (1 << 24)
-#define gcvZONE_SHADER          (1 << 25)
-#define gcvZONE_STREAM_OUT      (1 << 26)
-
-/* API definitions. */
-#define gcvZONE_API_HAL         ((gctUINT32) 1  << 28)
-#define gcvZONE_API_EGL         ((gctUINT32) 2  << 28)
-#define gcvZONE_API_ES11        ((gctUINT32) 3  << 28)
-#define gcvZONE_API_ES20        ((gctUINT32) 4  << 28)
-#define gcvZONE_API_ES30        ((gctUINT32) 4  << 28)
-#define gcvZONE_API_VG11        ((gctUINT32) 5  << 28)
-#define gcvZONE_API_GL          ((gctUINT32) 6  << 28)
-#define gcvZONE_API_DFB         ((gctUINT32) 7  << 28)
-#define gcvZONE_API_GDI         ((gctUINT32) 8  << 28)
-#define gcvZONE_API_D3D         ((gctUINT32) 9  << 28)
-#define gcvZONE_API_CL          ((gctUINT32) 10 << 28)
-#define gcvZONE_API_VX          ((gctUINT32) 11 << 28)
-
-
-#define gcmZONE_GET_API(zone)   ((zone) >> 28)
-/*Set gcdZONE_MASE like 0x0 | gcvZONE_API_EGL
-will enable print EGL module debug info*/
-#define gcdZONE_MASK            0x0FFFFFFF
-
-/* Handy zones. */
-#define gcvZONE_NONE            0
-#define gcvZONE_ALL             0x0FFFFFFF
-
-/*Dump API depth set 1 for API, 2 for API and API behavior*/
-#define gcvDUMP_API_DEPTH       1
-
-
 /*******************************************************************************
 **
 **  gcmTRACE_ZONE
@@ -3481,15 +3364,6 @@ gckOS_DebugTraceZone(
     ...
     );
 
-void
-gckOS_DebugTraceZoneN(
-    IN gctUINT32 Level,
-    IN gctUINT32 Zone,
-    IN gctUINT ArgumentSize,
-    IN gctCONST_STRING Message,
-    ...
-    );
-
 void
 gcoOS_DebugTraceZone(
     IN gctUINT32 Level,
@@ -3501,7 +3375,8 @@ gcoOS_DebugTraceZone(
 #if gcmIS_DEBUG(gcdDEBUG_TRACE)
 #   define gcmTRACE_ZONE            gcoOS_DebugTraceZone
 #   define gcmkTRACE_ZONE           gckOS_DebugTraceZone
-#   define gcmkTRACE_ZONE_N         gckOS_DebugTraceZoneN
+#   define gcmkTRACE_ZONE_N(Level, Zone, ArgumentSize, ...) \
+        gckOS_DebugTraceZone(Level, Zone, __VA_ARGS__)
 #elif gcdHAS_ELLIPSIS
 #   define gcmTRACE_ZONE(...)
 #   define gcmkTRACE_ZONE(...)
@@ -3852,7 +3727,7 @@ gcoOS_ProfileDB(
     gcmTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
                   "--%s(%d): status=%d(%s)", \
                   __FUNCTION__, __LINE__, \
-                  status, gcmSTATUS2NAME(status)); \
+                  status, gcoOS_DebugStatus2Name(status)); \
     *__user_ptr__ -= 1
 #else
     gcmINLINE static void
@@ -3961,7 +3836,7 @@ gcoOS_ProfileDB(
     gcmkBINARY_TRACE(__FUNCTION__, __LINE__, gcvNULL, status); \
     gcmkTRACE_ZONE(gcdHEADER_LEVEL, _GC_OBJ_ZONE, \
                    "--%s(%d): status=%d(%s)", \
-                   __FUNCTION__, __LINE__, status, gcmkSTATUS2NAME(status)); \
+                   __FUNCTION__, __LINE__, status, gckOS_DebugStatus2Name(status)); \
     *__kernel_ptr__ -= 1
 #else
     gcmINLINE static void
@@ -4014,19 +3889,6 @@ gckOS_Print(
     ...
     );
 
-void
-gckOS_PrintN(
-    IN gctUINT ArgumentSize,
-    IN gctCONST_STRING Message,
-    ...
-    );
-
-void
-gckOS_CopyPrint(
-    IN gctCONST_STRING Message,
-    ...
-    );
-
 void
 gcoOS_Print(
     IN gctCONST_STRING Message,
@@ -4035,7 +3897,35 @@ gcoOS_Print(
 
 #define gcmPRINT                gcoOS_Print
 #define gcmkPRINT               gckOS_Print
-#define gcmkPRINT_N             gckOS_PrintN
+#define gcmkPRINT_N(ArgumentSize, ...) gckOS_Print(__VA_ARGS__)
+
+#if gcdHAS_ELLIPSIS
+#   define gcmPRINT_ONCE(Text, ...)         \
+    {                                       \
+        static gctBOOL _once = gcvFALSE;    \
+        if (!_once)                         \
+        {                                   \
+            gcmPRINT(Text, __VA_ARGS__);    \
+            _once = gcvTRUE;                \
+        }                                   \
+    }                                       \
+
+#else
+    gcmINLINE static void
+    __dummy_printonce_arg(
+        IN gctCONST_STRING Text,
+        ...
+        )
+    {
+    }
+#   define gcmPRINT_ONCE               __dummy_printonce_arg
+#endif
+
+#if gcdFEATURE_SANITYCHECK
+#define gcmFEATURE_CHECKED                gcmPRINT_ONCE
+#else
+#define gcmFEATURE_CHECKED(Text, ...)
+#endif
 
 #if gcdPRINT_VERSION
 #   define gcmPRINT_VERSION()       do { \
@@ -4053,48 +3943,56 @@ gcoOS_Print(
 #   define gcmkPRINT_VERSION()      do { } while (gcvFALSE)
 #endif
 
-typedef enum _gceDUMP_BUFFER
+typedef enum _gceDUMP_BUFFER_TYPE
 {
+    gcvDUMP_BUFFER_USER_STRING,
+    gcvDUMP_BUFFER_VERIFY,
+
+    gcvDUMP_BUFFER_MEMORY,
+    gcvDUMP_BUFFER_TEXTURE,
+    gcvDUMP_BUFFER_STREAM,
+    gcvDUMP_BUFFER_INDEX,
+    gcvDUMP_BUFFER_BUFOBJ,
+    gcvDUMP_BUFFER_IMAGE,
+    /* A type of command, but should not execute directly. */
+    gcvDUMP_BUFFER_INSTRUCTION,
     gcvDUMP_BUFFER_CONTEXT,
-    gcvDUMP_BUFFER_USER,
-    gcvDUMP_BUFFER_KERNEL,
-    gcvDUMP_BUFFER_LINK,
-    gcvDUMP_BUFFER_WAITLINK,
-    gcvDUMP_BUFFER_FROM_USER,
+    gcvDUMP_BUFFER_COMMAND,
+    gcvDUMP_BUFFER_ASYNC_COMMAND,
+    gcvDUMP_BUFFER_USER_TYPE_LAST = gcvDUMP_BUFFER_ASYNC_COMMAND,
+
+    gcvDUMP_BUFFER_KERNEL_CONTEXT,
+    gcvDUMP_BUFFER_KERNEL_COMMAND,
+
+    gcvDUMP_BUFFER_PHYSICAL_MEMORY,
+
+    gcvDUMP_BUFFER_TYPE_COUNT,
 }
-gceDUMP_BUFFER;
+gceDUMP_BUFFER_TYPE;
 
 void
-gckOS_DumpBuffer(
+gckOS_Dump(
     IN gckOS Os,
-    IN gctPOINTER Buffer,
-    IN gctSIZE_T Size,
-    IN gceDUMP_BUFFER Type,
-    IN gctBOOL CopyMessage
+    IN gctCONST_STRING Format,
+    ...
     );
 
-#define gcmkDUMPBUFFER          gckOS_DumpBuffer
-
-#if gcdDUMP_COMMAND
-#   define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage) \
-        gcmkDUMPBUFFER(Os, Buffer, Size, Type, CopyMessage)
-#else
-#   define gcmkDUMPCOMMAND(Os, Buffer, Size, Type, CopyMessage)
-#endif
-
-#if gcmIS_DEBUG(gcdDEBUG_CODE)
-
 void
-gckOS_DebugFlush(
-    gctCONST_STRING CallerName,
-    gctUINT LineNumber,
-    gctUINT32 DmaAddress
+gckOS_DumpBuffer(
+    IN gckOS Os,
+    IN gceDUMP_BUFFER_TYPE Type,
+    IN gctPOINTER Buffer,
+    IN gctUINT64 Address,
+    IN gctSIZE_T Size
     );
 
-#   define gcmkDEBUGFLUSH(DmaAddress) \
-        gckOS_DebugFlush(__FUNCTION__, __LINE__, DmaAddress)
+#if gcdDUMP_IN_KERNEL
+#   define gcmkDUMP             gckOS_Dump
+
+#   define gcmkDUMP_BUFFER      gckOS_DumpBuffer
 #else
-#   define gcmkDEBUGFLUSH(DmaAddress)
+#   define gcmkDUMP(...)        do {} while (0)
+#   define gcmkDUMP_BUFFER(...) do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4104,100 +4002,52 @@ gckOS_DebugFlush(
 **      Print average frame rate
 **
 */
-#if gcdDUMP_FRAMERATE
-    gceSTATUS
-    gcfDumpFrameRate(
-        void
-        );
-#   define gcmDUMP_FRAMERATE        gcfDumpFrameRate
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_FRAMERATE(...)
-#else
-    gcmINLINE static void
-    __dummy_dump_frame_rate(
-        void
-        )
-    {
-    }
-#   define gcmDUMP_FRAMERATE        __dummy_dump_frame_rate
-#endif
-
+gceSTATUS
+gcoOS_DumpFrameRate(
+    void
+    );
+#   define gcmDUMP_FRAMERATE        gcoOS_DumpFrameRate
 
 /*******************************************************************************
 **
-**  gcmDUMP
+**  gcoOS_SetDumpFlag
 **
-**      Print a dump message.
+**      Dump print switch.
 **
 **  ARGUMENTS:
 **
-**      gctSTRING   Message.
-**
-**      ...         Optional arguments.
+**      DumpState
+**          True to enable dump prints.
 */
 
-#if gcdDUMP || gcdDUMP_2DVG
-    gceSTATUS
-    gcfDump(
-        IN gcoOS Os,
-        IN gctCONST_STRING String,
-        ...
-        );
-#  define gcmDUMP               gcfDump
-#elif gcdHAS_ELLIPSIS
-#  define gcmDUMP(...)
-#else
-    gcmINLINE static void
-    __dummy_dump(
-        IN gcoOS Os,
-        IN gctCONST_STRING Message,
-        ...
-        )
-    {
-    }
-#  define gcmDUMP               __dummy_dump
-#endif
+gceSTATUS
+gcoOS_SetDumpFlag(
+    IN gctBOOL DumpState
+    );
 
 /*******************************************************************************
 **
-**  gcmDUMP_DATA
+**  gcmDUMP
 **
-**      Add data to the dump.
+**      Print a dump message.
 **
 **  ARGUMENTS:
 **
-**      gctSTRING Tag
-**          Tag for dump.
-**
-**      gctPOINTER Logical
-**          Logical address of buffer.
+**      gctSTRING   Message.
 **
-**      gctSIZE_T Bytes
-**          Number of bytes.
+**      ...         Optional arguments.
 */
 
-#if gcdDUMP || gcdDUMP_COMMAND
-    gceSTATUS
-    gcfDumpData(
-        IN gcoOS Os,
-        IN gctSTRING Tag,
-        IN gctPOINTER Logical,
-        IN gctSIZE_T Bytes
-        );
-#  define gcmDUMP_DATA          gcfDumpData
-#elif gcdHAS_ELLIPSIS
-#  define gcmDUMP_DATA(...)
+#if gcdDUMP
+gceSTATUS
+gcoOS_Dump(
+    IN gcoOS Os,
+    IN gctCONST_STRING String,
+    ...
+    );
+#  define gcmDUMP               gcoOS_Dump
 #else
-    gcmINLINE static void
-    __dummy_dump_data(
-        IN gcoOS Os,
-        IN gctSTRING Tag,
-        IN gctPOINTER Logical,
-        IN gctSIZE_T Bytes
-        )
-    {
-    }
-#  define gcmDUMP_DATA          __dummy_dump_data
+#  define gcmDUMP(...)          do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4211,8 +4061,8 @@ gckOS_DebugFlush(
 **      gctSTRING Tag
 **          Tag for dump.
 **
-**      gctUINT32 Physical
-**          Physical address of buffer.
+**      gctUINT32 Address
+**          GPU address of buffer.
 **
 **      gctPOINTER Logical
 **          Logical address of buffer.
@@ -4224,68 +4074,39 @@ gckOS_DebugFlush(
 **          Number of bytes.
 */
 
-#if gcdDUMP || gcdDUMP_COMMAND || gcdDUMP_2DVG
+#if gcdDUMP
 gceSTATUS
-gcfDumpBuffer(
+gcoOS_DumpBuffer(
     IN gcoOS Os,
-    IN gctSTRING Tag,
-    IN gctUINT32 Physical,
+    IN gceDUMP_BUFFER_TYPE Type,
+    IN gctUINT32 Address,
     IN gctPOINTER Logical,
     IN gctSIZE_T Offset,
     IN gctSIZE_T Bytes
     );
-#   define gcmDUMP_BUFFER       gcfDumpBuffer
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_BUFFER(...)
+#   define gcmDUMP_BUFFER       gcoOS_DumpBuffer
 #else
-    gcmINLINE static void
-    __dummy_dump_buffer(
-        IN gcoOS Os,
-        IN gctSTRING Tag,
-        IN gctUINT32 Physical,
-        IN gctPOINTER Logical,
-        IN gctUINT32 Offset,
-        IN gctSIZE_T Bytes
-        )
-    {
-    }
-#   define gcmDUMP_BUFFER       __dummy_dump_buffer
+#   define gcmDUMP_BUFFER(...)  do {} while (0)
 #endif
 
 #if gcdDUMP
 void
-gcfDumpLock(
+gcoOS_DumpLock(
     void
     );
-#   define gcmDUMP_LOCK       gcfDumpLock
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_LOCK(...)
+#   define gcmDUMP_LOCK         gcoOS_DumpLock
 #else
-    gcmINLINE static void
-    __dummy_dump_lock(
-        void
-        )
-    {
-    }
-#   define gcmDUMP_LOCK       __dummy_dump_lock
+#   define gcmDUMP_LOCK(...)    do {} while (0)
 #endif
 
 #if gcdDUMP
 void
-gcfDumpUnlock(
+gcoOS_DumpUnlock(
     void
     );
-#   define gcmDUMP_UNLOCK       gcfDumpUnlock
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_UNLOCK(...)
+#   define gcmDUMP_UNLOCK       gcoOS_DumpUnlock
 #else
-    gcmINLINE static void
-    __dummy_dump_unlock(
-        void
-        )
-    {
-    }
-#   define gcmDUMP_UNLOCK       __dummy_dump_unlock
+#   define gcmDUMP_UNLOCK(...)  do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4300,20 +4121,11 @@ gcfDumpUnlock(
 **
 **      ...         Optional arguments.
 */
-gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...);
+gceSTATUS gcoOS_DumpApi(IN gctCONST_STRING String, ...);
 #if gcdDUMP_API
-#   define gcmDUMP_API           gcfDumpApi
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_API(...)
+#   define gcmDUMP_API          gcoOS_DumpApi
 #else
-    gcmINLINE static void
-    __dummy_dump_api(
-        IN gctCONST_STRING Message,
-        ...
-        )
-    {
-    }
-#  define gcmDUMP_API           __dummy_dump_api
+#   define gcmDUMP_API(...)     do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4327,20 +4139,11 @@ gceSTATUS gcfDumpApi(IN gctCONST_STRING String, ...);
 **      gctUINT32_PTR   Pointer to array.
 **      gctUINT32       Size.
 */
-gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size);
+gceSTATUS gcoOS_DumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size);
 #if gcdDUMP_API
-#   define gcmDUMP_API_ARRAY        gcfDumpArray
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_API_ARRAY(...)
+#   define gcmDUMP_API_ARRAY        gcoOS_DumpArray
 #else
-    gcmINLINE static void
-    __dummy_dump_api_array(
-        IN gctCONST_POINTER Data,
-        IN gctUINT32 Size
-        )
-    {
-    }
-#   define gcmDUMP_API_ARRAY        __dummy_dump_api_array
+#   define gcmDUMP_API_ARRAY(...)   do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4354,20 +4157,11 @@ gceSTATUS gcfDumpArray(IN gctCONST_POINTER Data, IN gctUINT32 Size);
 **      gctUINT32_PTR   Pointer to array.
 **      gctUINT32       Termination.
 */
-gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination);
+gceSTATUS gcoOS_DumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination);
 #if gcdDUMP_API
-#   define gcmDUMP_API_ARRAY_TOKEN  gcfDumpArrayToken
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_API_ARRAY_TOKEN(...)
+#   define gcmDUMP_API_ARRAY_TOKEN      gcoOS_DumpArrayToken
 #else
-    gcmINLINE static void
-    __dummy_dump_api_array_token(
-        IN gctCONST_POINTER Data,
-        IN gctUINT32 Termination
-        )
-    {
-    }
-#   define gcmDUMP_API_ARRAY_TOKEN  __dummy_dump_api_array_token
+#   define gcmDUMP_API_ARRAY_TOKEN(...) do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4381,20 +4175,11 @@ gceSTATUS gcfDumpArrayToken(IN gctCONST_POINTER Data, IN gctUINT32 Termination);
 **      gctCONST_POINTER    Pointer to array.
 **      gctSIZE_T           Size.
 */
-gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size);
+gceSTATUS gcoOS_DumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size);
 #if gcdDUMP_API
-#   define gcmDUMP_API_DATA         gcfDumpApiData
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_API_DATA(...)
+#   define gcmDUMP_API_DATA         gcoOS_DumpApiData
 #else
-    gcmINLINE static void
-    __dummy_dump_api_data(
-        IN gctCONST_POINTER Data,
-        IN gctSIZE_T Size
-        )
-    {
-    }
-#   define gcmDUMP_API_DATA         __dummy_dump_api_data
+#   define gcmDUMP_API_DATA(...)    do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4407,22 +4192,13 @@ gceSTATUS gcfDumpApiData(IN gctCONST_POINTER Data, IN gctSIZE_T Size);
 **      gctUINT32_PTR       Pointer to the command buffer.
 **      gctUINT32           Command buffer size.
 */
-gceSTATUS gcfDump2DCommand(IN gctUINT32_PTR Command, IN gctUINT32 Size);
+gceSTATUS gcoOS_Dump2DCommand(IN gctUINT32_PTR Command, IN gctUINT32 Size);
 #if gcdDUMP_2D
 #   define gcmDUMP_2D_COMMAND(cmd, size) \
         if (Hardware->newDump2DLevel > 1) \
-            gcfDump2DCommand(cmd, size)
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_2D_COMMAND(...)
+            gcoOS_Dump2DCommand(cmd, size)
 #else
-    gcmINLINE static void
-    __dummy_dump_2d_command(
-        IN gctUINT32_PTR Command,
-        IN gctUINT32 Size
-        )
-    {
-    }
-#   define gcmDUMP_2D_COMMAND       __dummy_dump_2d_command
+#   define gcmDUMP_2D_COMMAND(...)  do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4435,22 +4211,13 @@ gceSTATUS gcfDump2DCommand(IN gctUINT32_PTR Command, IN gctUINT32 Size);
 **      gctBOOL             Src.
 **      gctUINT32           Address.
 */
-gceSTATUS gcfDump2DSurface(IN gctBOOL Src, IN gctUINT32 Address);
+gceSTATUS gcoOS_Dump2DSurface(IN gctBOOL Src, IN gctUINT32 Address);
 #if gcdDUMP_2D
 #   define gcmDUMP_2D_SURFACE(src, addr) \
         if (Hardware->newDump2DLevel > 2) \
-           gcfDump2DSurface(src, addr)
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_2D_SURFACE(...)
+           gcoOS_Dump2DSurface(src, addr)
 #else
-    gcmINLINE static void
-    __dummy_dump_2d_surface(
-        IN gctBOOL Src,
-        IN gctUINT32 Address
-        )
-    {
-    }
-#   define gcmDUMP_2D_SURFACE       __dummy_dump_2d_surface
+#   define gcmDUMP_2D_SURFACE(...)  do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4463,22 +4230,11 @@ gceSTATUS gcfDump2DSurface(IN gctBOOL Src, IN gctUINT32 Address);
 **      gctUINT32           Address.
 **      gctSIZE_T           Size.
 */
-gceSTATUS gcfAddMemoryInfo(IN gctUINT32 GPUAddress, IN gctPOINTER Logical, IN gctUINT32 Physical, IN gctUINT32 Size);
+gceSTATUS gcfAddMemoryInfo(IN gctUINT32 GPUAddress, IN gctPOINTER Logical, IN gctUINT64 Physical, IN gctUINT32 Size);
 #if gcdDUMP_2D
 #   define gcmDUMP_ADD_MEMORY_INFO  gcfAddMemoryInfo
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_ADD_MEMORY_INFO(...)
 #else
-    gcmINLINE static void
-    __dummy_dump_add_memory_info(
-        IN gctUINT32 GPUAddress,
-        IN gctPOINTER Logical,
-        IN gctUINT32 Physical,
-        IN gctUINT32 Size
-        )
-    {
-    }
-#   define gcmDUMP_ADD_MEMORY_INFO  __dummy_dump_add_memory_info
+#   define gcmDUMP_ADD_MEMORY_INFO(...) do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4493,16 +4249,8 @@ gceSTATUS gcfAddMemoryInfo(IN gctUINT32 GPUAddress, IN gctPOINTER Logical, IN gc
 gceSTATUS gcfDelMemoryInfo(IN gctUINT32 Address);
 #if gcdDUMP_2D
 #   define gcmDUMP_DEL_MEMORY_INFO  gcfDelMemoryInfo
-#elif gcdHAS_ELLIPSIS
-#   define gcmDUMP_DEL_MEMORY_INFO(...)
 #else
-    gcmINLINE static void
-    __dummy_dump_del_memory_info(
-        IN gctUINT32 Address
-        )
-    {
-    }
-#   define gcmDUMP_DEL_MEMORY_INFO  __dummy_dump_del_memory_info
+#   define gcmDUMP_DEL_MEMORY_INFO(...) do {} while (0)
 #endif
 
 /*******************************************************************************
@@ -4603,6 +4351,38 @@ gckOS_DebugBreak(
 #   define gcmkASSERT(exp)
 #endif
 
+/*******************************************************************************
+**
+**  gcmSTATIC_ASSERT
+**
+**      Tests a software assertion at compile time. If the specific constant
+**      expression is false, the compiler displays the specified message and
+**      the compilation fails with an error, otherwise the declaration has
+**      no effect.
+**      Static assert is suitable for both user and kernel space.
+**
+**  ARGUMENTS:
+**
+**      exp     Constant expression.
+**      message Error message displayed on assertion failure.
+*/
+#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || (__GNUC__ > 4))
+#   define gcmSTATIC_ASSERT(constExp, message) \
+        do \
+        { \
+            _Static_assert((constExp), message); \
+        } \
+        while (0)
+
+#elif defined(_MSC_VER) && (_MSC_VER >= 1600)
+#   define gcmSTATIC_ASSERT(constExp, message) \
+        static_assert((constExp), message)
+
+#else
+#   define gcmSTATIC_ASSERT(constExp, message) \
+        do {} while (0)
+#endif
+
 /*******************************************************************************
 **
 **  gcmVERIFY
@@ -4618,8 +4398,8 @@ gckOS_DebugBreak(
 #   define gcmVERIFY(exp)           gcmASSERT(exp)
 #   define gcmkVERIFY(exp)          gcmkASSERT(exp)
 #else
-#   define gcmVERIFY(exp)           exp
-#   define gcmkVERIFY(exp)          exp
+#   define gcmVERIFY(exp)           (void)exp
+#   define gcmkVERIFY(exp)          (void)exp
 #endif
 
 /*******************************************************************************
@@ -4678,8 +4458,8 @@ gckOS_Verify(
         } \
         while (gcvFALSE)
 #else
-#   define gcmVERIFY_OK(func)       (void)func
-#   define gcmkVERIFY_OK(func)      (void)func
+#   define gcmVERIFY_OK(func)       func
+#   define gcmkVERIFY_OK(func)      func
 #endif
 
 gctCONST_STRING
@@ -4692,14 +4472,6 @@ gckOS_DebugStatus2Name(
     gceSTATUS status
     );
 
-#if gcmIS_DEBUG(gcdDEBUG)
-#   define gcmSTATUS2NAME             gcoOS_DebugStatus2Name
-#   define gcmkSTATUS2NAME            gckOS_DebugStatus2Name
-#else
-#   define gcmSTATUS2NAME(status)     status
-#   define gcmkSTATUS2NAME(status)    status
-#endif
-
 /*******************************************************************************
 **
 **  gcmERR_BREAK
@@ -4721,7 +4493,7 @@ gckOS_DebugStatus2Name(
         prefix##PRINT_VERSION(); \
         prefix##TRACE(gcvLEVEL_ERROR, \
             #prefix "ERR_BREAK: status=%d(%s) @ %s(%d)", \
-            status, gcmSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+            status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
         break; \
     } \
     do { } while (gcvFALSE)
@@ -4760,7 +4532,7 @@ gckOS_DebugStatus2Name(
         prefix##PRINT_VERSION(); \
         prefix##TRACE(gcvLEVEL_ERROR, \
             #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
-            status, gcmSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+            status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
         prefix##FOOTER(); \
         return status; \
     } \
@@ -4772,7 +4544,7 @@ gckOS_DebugStatus2Name(
         prefix##PRINT_VERSION(); \
         prefix##TRACE(gcvLEVEL_ERROR, \
             #prefix "ERR_RETURN: status=%d(%s) @ %s(%d)", \
-            status, gcmkSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+            status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
         prefix##FOOTER(); \
         return status; \
     } \
@@ -4804,7 +4576,7 @@ gckOS_DebugStatus2Name(
             prefix##PRINT_VERSION(); \
             prefix##TRACE(gcvLEVEL_ERROR, \
                 #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
-                status, gcmSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+                status, gcoOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
             goto OnError; \
         } \
     } \
@@ -4818,7 +4590,7 @@ gckOS_DebugStatus2Name(
             prefix##PRINT_VERSION(); \
             prefix##TRACE(gcvLEVEL_ERROR, \
                 #prefix "ONERROR: status=%d(%s) @ %s(%d)", \
-                status, gcmkSTATUS2NAME(status), __FUNCTION__, __LINE__); \
+                status, gckOS_DebugStatus2Name(status), __FUNCTION__, __LINE__); \
             goto OnError; \
         } \
     } \
@@ -5015,7 +4787,7 @@ gckOS_DebugStatus2Name(
         { \
             prefix##TRACE(gcvLEVEL_ERROR, \
                 #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
-                last, gcmSTATUS2NAME(last), __FUNCTION__, __LINE__); \
+                last, gcoOS_DebugStatus2Name(last), __FUNCTION__, __LINE__); \
             status = last; \
         } \
     } \
@@ -5028,7 +4800,7 @@ gckOS_DebugStatus2Name(
         { \
             prefix##TRACE(gcvLEVEL_ERROR, \
                 #prefix "CHECK_STATUS: status=%d(%s) @ %s(%d)", \
-                last, gcmkSTATUS2NAME(last), __FUNCTION__, __LINE__); \
+                last, gckOS_DebugStatus2Name(last), __FUNCTION__, __LINE__); \
             status = last; \
         } \
     } \
@@ -5226,61 +4998,12 @@ gcoHAL_GetUserDebugOption(
 
 #endif
 
-#if gcdSECURE_USER
-
-#   define gcmDEFINESECUREUSER() \
-        gctUINT         __secure_user_offset__; \
-        gctUINT32_PTR   __secure_user_hintArray__;
-
-#   define gcmBEGINSECUREUSER() \
-        __secure_user_offset__ = reserve->lastOffset; \
-        \
-        __secure_user_hintArray__ = gcmUINT64_TO_PTR(reserve->hintArrayTail)
-
-#   define gcmENDSECUREUSER() \
-        reserve->hintArrayTail = gcmPTR_TO_UINT64(__secure_user_hintArray__)
-
-#   define gcmSKIPSECUREUSER() \
-        __secure_user_offset__ += gcmSIZEOF(gctUINT32)
-
-#   define gcmUPDATESECUREUSER() \
-        *__secure_user_hintArray__ = __secure_user_offset__; \
-        \
-        __secure_user_offset__    += gcmSIZEOF(gctUINT32); \
-        __secure_user_hintArray__ += 1
-
-#else
-
-#   define gcmDEFINESECUREUSER()
-#   define gcmBEGINSECUREUSER()
-#   define gcmENDSECUREUSER()
-#   define gcmSKIPSECUREUSER()
-#   define gcmUPDATESECUREUSER()
-
-#endif
-
 /*----------------------------------------------------------------------------*/
 
-#if gcdDUMP
-#   define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data) \
-        if (FixedPoint) \
-        { \
-            gcmDUMP(gcvNULL, "#[state.x 0x%04X 0x%08X]", \
-                Address, Data \
-                ); \
-        } \
-        else \
-        { \
-            gcmDUMP(gcvNULL, "#[state 0x%04X 0x%08X]", \
-                Address, Data \
-                ); \
-        }
-#else
+/* This style of dump is deprecated. */
 #   define gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, Data)
-#endif
 
 #define gcmDEFINESTATEBUFFER(CommandBuffer, StateDelta, Memory, ReserveSize) \
-    gcmDEFINESECUREUSER() \
     gctSIZE_T ReserveSize; \
     gcoCMDBUF CommandBuffer; \
     gctUINT32_PTR Memory; \
@@ -5297,13 +5020,10 @@ gcoHAL_GetUserDebugOption(
     \
     StateDelta = Hardware->delta; \
     \
-    gcmBEGINSECUREUSER(); \
 }
 
 #define gcmENDSTATEBUFFER(Hardware, CommandBuffer, Memory, ReserveSize) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     gcmASSERT(\
         gcmUINT64_TO_TYPE(CommandBuffer->lastReserve, gctUINT8_PTR) + ReserveSize \
         == \
@@ -5327,8 +5047,6 @@ gcoHAL_GetUserDebugOption(
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmENDSTATEBATCH(CommandBuffer, Memory) \
@@ -5356,8 +5074,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5376,8 +5092,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 
@@ -5392,17 +5106,14 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETFILLER(CommandBuffer, Memory) \
 { \
     gcmVERIFYLOADSTATEDONE(CommandBuffer); \
     \
+    *(gctUINT32_PTR)Memory = 0x18000000; \
     Memory += 1; \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*----------------------------------------------------------------------------*/
@@ -5447,8 +5158,6 @@ gcoHAL_GetUserDebugOption(
     gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*******************************************************************************
@@ -5477,7 +5186,6 @@ gcoHAL_GetUserDebugOption(
 ** Temp command buffer macro
 */
 #define gcmDEFINESTATEBUFFER_NEW(CommandBuffer, StateDelta, Memory) \
-    gcmDEFINESECUREUSER() \
     gcmDEFINELOADSTATEBASE() \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
     gctUINT32_PTR Memory; \
@@ -5494,22 +5202,19 @@ gcoHAL_GetUserDebugOption(
     else \
     {\
         gcmONERROR(gcoBUFFER_StartTEMPCMDBUF(\
-            Hardware->engine[CurrentEngine].buffer, &CommandBuffer \
+            Hardware->engine[CurrentEngine].buffer, Hardware->engine[CurrentEngine].queue, &CommandBuffer \
             ));\
         \
         Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
         \
     }\
-    StateDelta = Hardware->delta; \
+    StateDelta = Hardware->tempDelta; \
     \
-    gcmBEGINSECUREUSER(); \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
 }
 
 #define gcmENDSTATEBUFFER_NEW(Hardware, CommandBuffer, Memory, OutSide) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     if (OutSide) \
     {\
         *OutSide = Memory; \
@@ -5520,12 +5225,15 @@ gcoHAL_GetUserDebugOption(
                                          (gctUINT8_PTR)CommandBuffer->buffer); \
         \
         gcmONERROR(gcoBUFFER_EndTEMPCMDBUF(Hardware->engine[CurrentEngine].buffer, gcvFALSE));\
+        if (Hardware->constructType != gcvHARDWARE_2D) \
+        { \
+            gcoHARDWARE_UpdateTempDelta(Hardware);\
+        } \
     }\
     gcmUNSETLOADSTATEBASE()\
 }
 
 #define gcmDEFINECTRLSTATEBUFFER(CommandBuffer, Memory)                         \
-    gcmDEFINESECUREUSER()                                                       \
     gcmDEFINELOADSTATEBASE()                                                    \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL;                                      \
     gctUINT32_PTR Memory;                                                       \
@@ -5540,12 +5248,12 @@ gcoHAL_GetUserDebugOption(
     else                                                                        \
     {                                                                           \
         gcmONERROR(gcoBUFFER_StartTEMPCMDBUF(\
-            Hardware->engine[CurrentEngine].buffer, &CommandBuffer              \
+            Hardware->engine[CurrentEngine].buffer, \
+            Hardware->engine[CurrentEngine].queue, &CommandBuffer               \
             ));                                                                 \
                                                                                 \
         Memory = (gctUINT32_PTR)(CommandBuffer->buffer);                        \
     }                                                                           \
-    gcmBEGINSECUREUSER();                                                       \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);                                 \
 }
 
@@ -5561,8 +5269,6 @@ gcoHAL_GetUserDebugOption(
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, FLOAT, FixedPoint) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, COUNT, Count) \
         | gcmSETFIELD     (0, AQ_COMMAND_LOAD_STATE_COMMAND, ADDRESS, Address); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmENDSTATEBATCH_NEW(CommandBuffer, Memory) \
@@ -5584,8 +5290,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_NEW(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5602,8 +5306,6 @@ gcoHAL_GetUserDebugOption(
         ); \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 
@@ -5616,15 +5318,12 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, gcvFALSE, Address, __temp_data32__); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETFILLER_NEW(CommandBuffer, Memory) \
 { \
+    *(gctUINT32_PTR)Memory = 0x18000000; \
     Memory += 1; \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 /*----------------------------------------------------------------------------*/
@@ -5669,8 +5368,6 @@ gcoHAL_GetUserDebugOption(
     gcmDUMP(gcvNULL, "#[stall 0x%08X 0x%08X]", \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, SOURCE, FRONT_END), \
         gcmSETFIELDVALUE(0, AQ_SEMAPHORE, DESTINATION, PIXEL_ENGINE)); \
-    \
-    gcmSKIPSECUREUSER(); \
 }
 
 #define gcmSETSTARTDECOMMAND_NEW(CommandBuffer, Memory, Count) \
@@ -5694,8 +5391,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5708,8 +5403,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSINGLESTATE_NEW_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5742,8 +5435,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSTATEDATAWITHMASK_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5758,8 +5449,6 @@ gcoHAL_GetUserDebugOption(
     *Memory++ = __temp_data32__; \
     \
     gcmDUMPSTATEDATA(StateDelta, FixedPoint, Address, __temp_data32__); \
-    \
-    gcmUPDATESECUREUSER(); \
 }
 
 #define gcmSETSINGLESTATE_FAST(StateDelta, CommandBuffer, Memory, FixedPoint, \
@@ -5781,13 +5470,11 @@ gcoHAL_GetUserDebugOption(
 }
 
 #define gcmDEFINESTATEBUFFER_NEW_FAST(CommandBuffer, Memory) \
-    gcmDEFINESECUREUSER() \
     gcmDEFINELOADSTATEBASE() \
     gcsTEMPCMDBUF CommandBuffer = gcvNULL; \
     gctUINT32_PTR Memory;
 
 #define gcmDEFINESTATEBUFFER_FAST(CommandBuffer, Memory, ReserveSize) \
-    gcmDEFINESECUREUSER() \
     gctSIZE_T ReserveSize; \
     gcoCMDBUF CommandBuffer; \
     gctUINT32_PTR Memory;
@@ -5800,7 +5487,6 @@ gcoHAL_GetUserDebugOption(
     \
     Memory = (gctUINT32_PTR) gcmUINT64_TO_PTR(CommandBuffer->lastReserve); \
     \
-    gcmBEGINSECUREUSER(); \
 }
 
 #define gcmBEGINSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
@@ -5812,21 +5498,18 @@ gcoHAL_GetUserDebugOption(
     else \
     {\
         gcmONERROR(gcoBUFFER_StartTEMPCMDBUF(\
-            Hardware->engine[gcvENGINE_RENDER].buffer, &CommandBuffer \
+            Hardware->engine[gcvENGINE_RENDER].buffer, Hardware->engine[gcvENGINE_RENDER].queue, &CommandBuffer \
             ));\
         \
         Memory = (gctUINT32_PTR)(CommandBuffer->buffer); \
         \
     }\
     \
-    gcmBEGINSECUREUSER(); \
     gcmSETLOADSTATEBASE(CommandBuffer,OutSide);\
 }
 
 #define gcmENDSTATEBUFFER_NEW_FAST(Hardware, CommandBuffer, Memory, OutSide) \
 { \
-    gcmENDSECUREUSER(); \
-    \
     if (OutSide) \
     {\
         *OutSide = Memory; \
@@ -5908,13 +5591,18 @@ gcoHAL_GetUserDebugOption(
     } \
 }
 #else
-#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, Halti5Avail, NumConstants, \
+#define gcmCONFIGUREUNIFORMS(ChipModel, ChipRevision, Halti5Avail, SmallBatch, NumConstants, \
              UnifiedConst, VsConstBase, PsConstBase, VsConstMax, PsConstMax, ConstMax) \
 { \
     if (NumConstants > 256) \
     { \
         UnifiedConst = gcvTRUE; \
-        if (Halti5Avail) \
+        if (SmallBatch) \
+        { \
+            VsConstBase  = 0xD000; \
+            PsConstBase  = 0xD000; \
+        } \
+        else if (Halti5Avail) \
         { \
             VsConstBase  = 0xD000; \
             PsConstBase  = 0xD800; \
@@ -6039,6 +5727,120 @@ gcoHAL_GetUserDebugOption(
     }\
 }\
 
+
+#define gcmCONFIGUSC(prefix, featureUSC, featureSeparateLS, featureComputeOnly, \
+    featureTS, featureGS, featureUSCFullCacheFix, featureL1CacheSize, featureUSCMaxPages, \
+    attribCacheRatio, L1CacheRatio) \
+{ \
+    attribCacheRatio = 0x2; \
+    \
+    if (featureUSC) \
+    { \
+        if (featureSeparateLS) \
+        { \
+            L1CacheRatio = 0x0; \
+        } \
+        else \
+        { \
+            gctUINT L1cacheSize; \
+            \
+            if (featureComputeOnly) \
+            { \
+                L1cacheSize = featureL1CacheSize; \
+            } \
+            else \
+            { \
+                gctUINT attribBufSizeInKB; \
+                if (featureTS) \
+                { \
+                    /* GS/TS must be bundled. */ \
+                    prefix##ASSERT(featureGS); \
+                    featureGS = featureGS; \
+                    attribBufSizeInKB = 42; \
+                } \
+                else \
+                { \
+                    prefix##ASSERT(!featureGS); \
+                    attribBufSizeInKB = 8; \
+                } \
+                if (attribBufSizeInKB < featureUSCMaxPages) \
+                { \
+                    L1cacheSize = featureUSCMaxPages - attribBufSizeInKB; \
+                } \
+                else \
+                { \
+                    attribBufSizeInKB -= 4; \
+                    L1cacheSize = 4; \
+                } \
+            } \
+            prefix##ASSERT(L1cacheSize); \
+            if (L1cacheSize >= featureL1CacheSize) \
+            { \
+                L1CacheRatio = 0x0; \
+                prefix##ASSERT(featureUSCFullCacheFix); \
+                featureUSCFullCacheFix = featureUSCFullCacheFix; \
+            } \
+            else \
+            { \
+                static const gctINT s_uscCacheRatio[] = \
+                { \
+                    100000,/* 1.0f */     \
+                    50000, /* 0.5f */     \
+                    25000, /* 0.25f */    \
+                    12500, /* 0.125f */   \
+                    62500, /* 0.0625f */  \
+                    3125, /* 0.03125f */ \
+                    75000, /* 0.75f */    \
+                    0, /*0.0f */      \
+                }; \
+                gctINT maxL1cacheSize = L1cacheSize * 100000; \
+                gctINT delta = 2147483647; /* start with very big delta */ \
+                gctINT i = 0; \
+                gctINT curIndex = -1; \
+                for (; i < gcmCOUNTOF(s_uscCacheRatio); ++i) \
+                { \
+                    gctINT curL1cacheSize = featureL1CacheSize * s_uscCacheRatio[i]; \
+                  \
+                    if ((maxL1cacheSize >= curL1cacheSize) && \
+                        ((maxL1cacheSize - curL1cacheSize) < delta)) \
+                    { \
+                        curIndex = i; \
+                        delta = maxL1cacheSize - curL1cacheSize; \
+                    } \
+                } \
+                prefix##ASSERT(-1 != curIndex); \
+                L1CacheRatio = curIndex; \
+            } \
+        } \
+    } \
+} \
+
+#if VIVANTE_PROFILER_SYSTEM_MEMORY
+typedef struct _memory_profile_info
+{
+    struct
+    {
+        gctUINT64     currentSize;
+        gctUINT64     peakSize;
+        gctUINT64     total_allocate;
+        gctUINT64     total_free;
+        gctUINT32     total_allocateCount;
+        gctUINT32     total_freeCount;
+    } system_memory, gpu_memory;
+} memory_profile_info;
+
+
+gceSTATUS
+gcoOS_GetMemoryProfileInfo(
+    size_t                      size,
+    struct _memory_profile_info *info
+    );
+
+gceSTATUS gcoOS_DumpMemoryProfile(void);
+gceSTATUS gcoOS_InitMemoryProfile(void);
+gceSTATUS gcoOS_DeInitMemoryProfile(void);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_debug_zones.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_debug_zones.h
new file mode 100644 (file)
index 0000000..256cd1d
--- /dev/null
@@ -0,0 +1,312 @@
+/****************************************************************************
+*
+*    The MIT License (MIT)
+*
+*    Copyright (c) 2014 - 2019 Vivante Corporation
+*
+*    Permission is hereby granted, free of charge, to any person obtaining a
+*    copy of this software and associated documentation files (the "Software"),
+*    to deal in the Software without restriction, including without limitation
+*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
+*    and/or sell copies of the Software, and to permit persons to whom the
+*    Software is furnished to do so, subject to the following conditions:
+*
+*    The above copyright notice and this permission notice shall be included in
+*    all copies or substantial portions of the Software.
+*
+*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+*    DEALINGS IN THE SOFTWARE.
+*
+*****************************************************************************
+*
+*    The GPL License (GPL)
+*
+*    Copyright (C) 2014 - 2019 Vivante Corporation
+*
+*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*
+*****************************************************************************
+*
+*    Note: This software is released under dual MIT and GPL licenses. A
+*    recipient may use this file under the terms of either the MIT license or
+*    GPL License. If you wish to use only one license not the other, you can
+*    indicate your decision by deleting one of the above license notices in your
+*    version of this file.
+*
+*****************************************************************************/
+
+
+#ifndef __gc_hal_debug_zones_h_
+#define __gc_hal_debug_zones_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************\
+ ************************ Debug Zone Pattern Summary ***************************
+ * A debug zone is an unsigned integer of 32 bit (Bit 31- Bit 0).              *
+ * Bit 31 to 28 defines API, which is 0 for HAL API and has value of 1 - 14    *
+ * for Khronos API. Value 15 (0xF) is reserved for gcdZONE_NONE.               *
+ * Bit 27 to 0 defines subzones of each API. Value 0xFFFFFFF is resevered for  *
+ * gcdZONE_ALL.                                                                *
+ *                                                                             *
+\******************************************************************************/
+
+/* Retrieve API bits 31 to 28 */
+#define gcmZONE_GET_API(zone)             ((zone) >> 28)
+
+/* Retrieve Subzone bits 27 to 0 */
+#define gcmZONE_GET_SUBZONES(zone)        ((zone) << 4)
+
+/******************************************************************************\
+******************************** HAL Zone **************************************
+\******************************************************************************/
+
+#define gcdZONE_API_HAL              ((gctUINT32) 0  << 28)
+
+/******************************************************************************\
+******************************** HAL Subzones **********************************
+\******************************************************************************/
+
+/* Subzones Kernel and User have in common */
+#define gcvZONE_OS              (1 << 0)
+#define gcvZONE_HARDWARE        (1 << 1)
+#define gcvZONE_HEAP            (1 << 2)
+#define gcvZONE_SIGNAL          (1 << 3)
+
+/* Subzones of HAL Kernel */
+#define gcvZONE_KERNEL          (1 << 4)
+#define gcvZONE_VIDMEM          (1 << 5)
+#define gcvZONE_COMMAND         (1 << 6)
+#define gcvZONE_DRIVER          (1 << 7)
+#define gcvZONE_CMODEL          (1 << 8)
+#define gcvZONE_MMU             (1 << 9)
+#define gcvZONE_EVENT           (1 << 10)
+#define gcvZONE_DEVICE          (1 << 11)
+#define gcvZONE_DATABASE        (1 << 12)
+#define gcvZONE_INTERRUPT       (1 << 13)
+#define gcvZONE_POWER           (1 << 14)
+#define gcvZONE_ASYNC_COMMAND   (1 << 15)
+#define gcvZONE_ALLOCATOR       (1 << 16)
+
+/* Subzones of HAL User */
+#define gcdZONE_HAL_API         (1 << 4)
+#define gcdZONE_BUFFER          (1 << 5)
+#define gcdZONE_VGBUFFER        (1 << 6)
+#define gcdZONE_SURFACE         (1 << 7)
+#define gcdZONE_INDEX           (1 << 8)
+#define gcdZONE_STREAM          (1 << 9)
+#define gcdZONE_TEXTURE         (1 << 10)
+#define gcdZONE_2D              (1 << 11)
+#define gcdZONE_3D              (1 << 12)
+#define gcdZONE_COMPILER        (1 << 13)
+#define gcdZONE_MEM             (1 << 14)
+#define gcdZONE_VERTEXARRAY     (1 << 15)
+#define gcdZONE_CL              (1 << 16)
+#define gcdZONE_VG              (1 << 17)
+#define gcdZONE_VX              (1 << 18)
+#define gcdZONE_UTILITY         (1 << 19)
+#define gcdZONE_RECT            (1 << 20)
+#define gcdZONE_BUFOBJ          (1 << 21)
+#define gcdZONE_PROFILER        (1 << 22)
+#define gcdZONE_SHADER          (1 << 23)
+
+/*#define gcvZONE_CONTEXT         (1 << 6) */
+/*#define gcvZONE_PARAMETERS      (1 << 23) */
+/*#define gcvZONE_STATE           (1 << 15) */
+/*#define gcvZONE_AUX             (1 << 16) */
+/*#define gcvZONE_IMAGE           (1 << 21) */
+/*#define gcvZONE_STREAM_OUT      (1 << 26) */
+
+
+
+/******************************************************************************\
+******************************** Khronos API Zones *****************************
+\******************************************************************************/
+
+#define gcdZONE_API_EGL              ((gctUINT32) 1  << 28)
+#define gcdZONE_API_ES11             ((gctUINT32) 2  << 28)
+#define gcdZONE_API_ES30             ((gctUINT32) 3  << 28)
+#define gcdZONE_API_GL40             ((gctUINT32) 4  << 28)
+#define gcdZONE_API_VG11             ((gctUINT32) 5  << 28)
+#define gcdZONE_API_CL               ((gctUINT32) 6  << 28)
+#define gcdZONE_API_VX               ((gctUINT32) 7  << 28)
+
+/******************************************************************************\
+************************* Subzones of Khronos API Zones ************************
+\******************************************************************************/
+
+/* Subzones of EGL API */
+#define gcdZONE_EGL_API              (gcdZONE_API_EGL | (1 << 0))
+#define gcdZONE_EGL_SURFACE          (gcdZONE_API_EGL | (1 << 1))
+#define gcdZONE_EGL_CONTEXT          (gcdZONE_API_EGL | (1 << 2))
+#define gcdZONE_EGL_CONFIG           (gcdZONE_API_EGL | (1 << 3))
+#define gcdZONE_EGL_OS               (gcdZONE_API_EGL | (1 << 4))  /* unused */
+#define gcdZONE_EGL_IMAGE            (gcdZONE_API_EGL | (1 << 5))
+#define gcdZONE_EGL_SWAP             (gcdZONE_API_EGL | (1 << 6))
+#define gcdZONE_EGL_INIT             (gcdZONE_API_EGL | (1 << 7))
+#define gcdZONE_EGL_SYNC             (gcdZONE_API_EGL | (1 << 8))
+#define gcdZONE_EGL_COMPOSE          (gcdZONE_API_EGL | (1 << 9))  /* unused */
+#define gcdZONE_EGL_RENDER_THREAD    (gcdZONE_API_EGL | (1 << 10)) /* unused */
+
+/* Subzones of ES11 API */
+#define gcdZONE_ES11_BUFFER          (gcdZONE_API_ES11 | (1 << 0))
+#define gcdZONE_ES11_CLEAR           (gcdZONE_API_ES11 | (1 << 1))
+#define gcdZONE_ES11_CLIP            (gcdZONE_API_ES11 | (1 << 2))
+#define gcdZONE_ES11_CONTEXT         (gcdZONE_API_ES11 | (1 << 3))
+#define gcdZONE_ES11_DRAW            (gcdZONE_API_ES11 | (1 << 4))
+#define gcdZONE_ES11_ENABLE          (gcdZONE_API_ES11 | (1 << 5))
+#define gcdZONE_ES11_EXTENTION       (gcdZONE_API_ES11 | (1 << 6))
+#define gcdZONE_ES11_FOG             (gcdZONE_API_ES11 | (1 << 7))
+#define gcdZONE_ES11_FRAGMENT        (gcdZONE_API_ES11 | (1 << 8))
+#define gcdZONE_ES11_LIGHT           (gcdZONE_API_ES11 | (1 << 9))
+#define gcdZONE_ES11_MATRIX          (gcdZONE_API_ES11 | (1 << 10))
+#define gcdZONE_ES11_PIXEL           (gcdZONE_API_ES11 | (1 << 11))
+#define gcdZONE_ES11_POLIGON         (gcdZONE_API_ES11 | (1 << 12))
+#define gcdZONE_ES11_LINE            (gcdZONE_API_ES11 | (1 << 13)) /* unused */
+#define gcdZONE_ES11_QUERY           (gcdZONE_API_ES11 | (1 << 14))
+#define gcdZONE_ES11_TEXTURE         (gcdZONE_API_ES11 | (1 << 15))
+#define gcdZONE_ES11_STATES          (gcdZONE_API_ES11 | (1 << 16))
+#define gcdZONE_ES11_STREAM          (gcdZONE_API_ES11 | (1 << 17))
+#define gcdZONE_ES11_VIEWPORT        (gcdZONE_API_ES11 | (1 << 18))
+#define gcdZONE_ES11_SHADER          (gcdZONE_API_ES11 | (1 << 19))
+#define gcdZONE_ES11_HASH            (gcdZONE_API_ES11 | (1 << 20))
+#define gcdZONE_ES11_TRACE           (gcdZONE_API_ES11 | (1 << 21))
+
+/* Subzones of ES30 API */
+#define gcdZONE_ES30_TRACE           (gcdZONE_API_ES30 | (1 << 0))
+#define gcdZONE_ES30_BUFFER          (gcdZONE_API_ES30 | (1 << 1))
+#define gcdZONE_ES30_CLEAR           (gcdZONE_API_ES30 | (1 << 2))
+#define gcdZONE_ES30_CODEC           (gcdZONE_API_ES30 | (1 << 3))
+#define gcdZONE_ES30_CONTEXT         (gcdZONE_API_ES30 | (1 << 4))
+#define gcdZONE_ES30_DEPTH           (gcdZONE_API_ES30 | (1 << 5))
+#define gcdZONE_ES30_DEVICE          (gcdZONE_API_ES30 | (1 << 6))
+#define gcdZONE_ES30_DRAW            (gcdZONE_API_ES30 | (1 << 7))
+#define gcdZONE_ES30_FBO             (gcdZONE_API_ES30 | (1 << 8))
+#define gcdZONE_ES30_PIXEL           (gcdZONE_API_ES30 | (1 << 9))
+#define gcdZONE_ES30_SHADER          (gcdZONE_API_ES30 | (1 << 10))
+#define gcdZONE_ES30_STATE           (gcdZONE_API_ES30 | (1 << 11))
+#define gcdZONE_ES30_TEXTURE         (gcdZONE_API_ES30 | (1 << 12))
+#define gcdZONE_ES30_UTILS           (gcdZONE_API_ES30 | (1 << 13))
+#define gcdZONE_ES30_PROFILER        (gcdZONE_API_ES30 | (1 << 14))
+#define gcdZONE_ES30_CORE            (gcdZONE_API_ES30 | (1 << 15))
+
+/* Subzones of GL40 API */
+#define gcdZONE_GL40_TRACE           (gcdZONE_API_GL40 | (1 << 0))
+#define gcdZONE_GL40_BUFFER          (gcdZONE_API_GL40 | (1 << 1))
+#define gcdZONE_GL40_CLEAR           (gcdZONE_API_GL40 | (1 << 2))  /* unused */
+#define gcdZONE_GL40_CODEC           (gcdZONE_API_GL40 | (1 << 3))
+#define gcdZONE_GL40_CONTEXT         (gcdZONE_API_GL40 | (1 << 4))
+#define gcdZONE_GL40_DEPTH           (gcdZONE_API_GL40 | (1 << 5))
+#define gcdZONE_GL40_DEVICE          (gcdZONE_API_GL40 | (1 << 6))
+#define gcdZONE_GL40_DRAW            (gcdZONE_API_GL40 | (1 << 7))
+#define gcdZONE_GL40_FBO             (gcdZONE_API_GL40 | (1 << 8))
+#define gcdZONE_GL40_PIXEL           (gcdZONE_API_GL40 | (1 << 9))
+#define gcdZONE_GL40_SHADER          (gcdZONE_API_GL40 | (1 << 10))
+#define gcdZONE_GL40_STATE           (gcdZONE_API_GL40 | (1 << 11))
+#define gcdZONE_GL40_TEXTURE         (gcdZONE_API_GL40 | (1 << 12))
+#define gcdZONE_GL40_UTILS           (gcdZONE_API_GL40 | (1 << 13))
+#define gcdZONE_GL40_PROFILER        (gcdZONE_API_GL40 | (1 << 14))
+#define gcdZONE_GL40_CORE            (gcdZONE_API_GL40 | (1 << 15))
+#define gcdZONE_GL40_FIXVERTEX       (gcdZONE_API_GL40 | (1 << 16))
+#define gcdZONE_GL40_FIXFRAG         (gcdZONE_API_GL40 | (1 << 17))
+#define gcdZONE_GL40_HASH            (gcdZONE_API_GL40 | (1 << 18))
+
+/* Subzones of VG11 API  */
+#define gcdZONE_VG_TRACE             (gcdZONE_API_VG11 | (1 << 0))
+#define gcdZONE_VG_STATE             (gcdZONE_API_VG11 | (1 << 1))  /* unused */
+#define gcdZONE_VG_FONT              (gcdZONE_API_VG11 | (1 << 2))  /* unused */
+#define gcdZONE_VG_HARDWARE          (gcdZONE_API_VG11 | (1 << 3))  /* unused */
+#define gcdZONE_VG_IMAGE             (gcdZONE_API_VG11 | (1 << 4))  /* unused */
+#define gcdZONE_VG_MASK              (gcdZONE_API_VG11 | (1 << 5))  /* unused */
+#define gcdZONE_VG_MATRIX            (gcdZONE_API_VG11 | (1 << 7))  /* unused */
+#define gcdZONE_VG_PATH              (gcdZONE_API_VG11 | (1 << 8))  /* unused */
+#define gcdZONE_VG_PAINT             (gcdZONE_API_VG11 | (1 << 9))  /* unused */
+#define gcdZONE_VG_TESSELLATOR       (gcdZONE_API_VG11 | (1 << 10)) /* unused */
+#define gcdZONE_VG_VGU               (gcdZONE_API_VG11 | (1 << 11)) /* unused */
+
+/* Subzones of CL API  */
+#define gcdZONE_CL_COMMAND           (gcdZONE_API_CL | (1 << 0))
+#define gcdZONE_CL_CONTEXT           (gcdZONE_API_CL | (1 << 1))
+#define gcdZONE_CL_DEVICE            (gcdZONE_API_CL | (1 << 2))
+#define gcdZONE_CL_ENQUEUE           (gcdZONE_API_CL | (1 << 3))
+#define gcdZONE_CL_EVENT             (gcdZONE_API_CL | (1 << 4))
+#define gcdZONE_CL_EXT               (gcdZONE_API_CL | (1 << 5))
+#define gcdZONE_CL_GL                (gcdZONE_API_CL | (1 << 6))
+#define gcdZONE_CL_KERNEL            (gcdZONE_API_CL | (1 << 7))
+#define gcdZONE_CL_MEM               (gcdZONE_API_CL | (1 << 8))
+#define gcdZONE_CL_PLATFORM          (gcdZONE_API_CL | (1 << 9))
+#define gcdZONE_CL_PROFILER          (gcdZONE_API_CL | (1 << 10))
+#define gcdZONE_CL_PROGRAM           (gcdZONE_API_CL | (1 << 11))
+#define gcdZONE_CL_SAMPLER           (gcdZONE_API_CL | (1 << 12))
+
+/* Subzones of VX API  */
+#define gcdZONE_VX_ARRAY             (gcdZONE_API_VX | (1 << 0))
+#define gcdZONE_VX_BINARY            (gcdZONE_API_VX | (1 << 1))
+#define gcdZONE_VX_CONTEXT           (gcdZONE_API_VX | (1 << 2))
+#define gcdZONE_VX_CONV              (gcdZONE_API_VX | (1 << 3))
+#define gcdZONE_VX_DELAY             (gcdZONE_API_VX | (1 << 4))
+#define gcdZONE_VX_DIST              (gcdZONE_API_VX | (1 << 5))
+#define gcdZONE_VX_GPULAYER          (gcdZONE_API_VX | (1 << 6))
+#define gcdZONE_VX_GRAPH             (gcdZONE_API_VX | (1 << 7))
+#define gcdZONE_VX_IMAGE             (gcdZONE_API_VX | (1 << 8))
+#define gcdZONE_VX_INTERFACE         (gcdZONE_API_VX | (1 << 9))
+#define gcdZONE_VX_KERNEL            (gcdZONE_API_VX | (1 << 10))
+#define gcdZONE_VX_LAYER             (gcdZONE_API_VX | (1 << 11))
+#define gcdZONE_VX_LUT               (gcdZONE_API_VX | (1 << 12))
+#define gcdZONE_VX_MATRIX            (gcdZONE_API_VX | (1 << 13))
+#define gcdZONE_VX_MEMORY            (gcdZONE_API_VX | (1 << 14))
+#define gcdZONE_VX_METAFMT           (gcdZONE_API_VX | (1 << 15))
+#define gcdZONE_VX_NODE              (gcdZONE_API_VX | (1 << 16))
+#define gcdZONE_VX_OBJARRAY          (gcdZONE_API_VX | (1 << 17))
+#define gcdZONE_VX_PARAM             (gcdZONE_API_VX | (1 << 18))
+#define gcdZONE_VX_PROGRAM           (gcdZONE_API_VX | (1 << 19))
+#define gcdZONE_VX_PYRAMID           (gcdZONE_API_VX | (1 << 20))
+#define gcdZONE_VX_REF               (gcdZONE_API_VX | (1 << 21))
+#define gcdZONE_VX_REMAP             (gcdZONE_API_VX | (1 << 22))
+#define gcdZONE_VX_SCALAR            (gcdZONE_API_VX | (1 << 23))
+#define gcdZONE_VX_TARGET            (gcdZONE_API_VX | (1 << 24))
+#define gcdZONE_VX_TENSOR            (gcdZONE_API_VX | (1 << 25))
+#define gcdZONE_VX_THRESHOLD         (gcdZONE_API_VX | (1 << 26))
+#define gcdZONE_VX_OTHERS            (gcdZONE_API_VX | (1 << 27))
+
+/******************************************************************************\
+******************************** Utility Zones *********************************
+\******************************************************************************/
+
+/* Value for Disabling All Subzones */
+#define gcdZONE_NONE                 0xF0000000
+
+/* Value for Enabling All Subzones */
+#define gcdZONE_ALL                  0x0FFFFFFF
+
+
+/******************************************************************************\
+*********************************** END ****************************************
+\******************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_debug_zones_h_ */
+
+
index a8acea2..2e59094 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -83,178 +83,182 @@ extern "C" {
 
 typedef enum _gceHAL_COMMAND_CODES
 {
-    /* Generic query. */
-    gcvHAL_QUERY_VIDEO_MEMORY,
+    /*************** Common ***************/
+
+    /* Chip info: count, type and so on. */
+    gcvHAL_CHIP_INFO,
+
+    /* HAL driver version. */
+    gcvHAL_VERSION,
+
+    /* Query chip id and options. */
     gcvHAL_QUERY_CHIP_IDENTITY,
+    gcvHAL_QUERY_CHIP_OPTION,
+
+    /* Query chip frequency, used by CL. */
     gcvHAL_QUERY_CHIP_FREQUENCY,
 
-    /* Contiguous memory. */
-    gcvHAL_ALLOCATE_NON_PAGED_MEMORY,
-    gcvHAL_FREE_NON_PAGED_MEMORY,
-    gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY,
-    gcvHAL_FREE_CONTIGUOUS_MEMORY,
+    /* Query system pool video memory, used by CL. */
+    gcvHAL_QUERY_VIDEO_MEMORY,
 
-    /* Video memory allocation. */
-    gcvHAL_ALLOCATE_VIDEO_MEMORY, /* Enforced alignment. */
-    gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY, /* No alignment. */
+    /* Memory management. */
+    gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY,
+    gcvHAL_WRAP_USER_MEMORY,
     gcvHAL_RELEASE_VIDEO_MEMORY,
-
-    /* Physical-to-logical mapping. */
+    gcvHAL_LOCK_VIDEO_MEMORY,
+    gcvHAL_UNLOCK_VIDEO_MEMORY,
+    gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY,
     gcvHAL_MAP_MEMORY,
     gcvHAL_UNMAP_MEMORY,
 
-    /* Logical-to-physical mapping. */
-    gcvHAL_MAP_USER_MEMORY,
-    gcvHAL_UNMAP_USER_MEMORY,
+    /* Cache operations. */
+    gcvHAL_CACHE,
 
-    /* Surface lock/unlock. */
-    gcvHAL_LOCK_VIDEO_MEMORY,
-    gcvHAL_UNLOCK_VIDEO_MEMORY,
+    /* HAL user attach and detach. */
+    gcvHAL_ATTACH,
+    gcvHAL_DETACH,
 
-    /* Event queue. */
+    /* Event commit. */
     gcvHAL_EVENT_COMMIT,
 
-    gcvHAL_USER_SIGNAL,
-    gcvHAL_SIGNAL,
-    gcvHAL_WRITE_DATA,
-
+    /* User command commit. */
     gcvHAL_COMMIT,
-    gcvHAL_STALL,
 
-    gcvHAL_READ_REGISTER,
-    gcvHAL_WRITE_REGISTER,
+    /* Set hardware timeout, used by CL. */
+    gcvHAL_SET_TIMEOUT,
 
-    gcvHAL_GET_PROFILE_SETTING,
-    gcvHAL_SET_PROFILE_SETTING,
+    /* User signal operations. */
+    gcvHAL_USER_SIGNAL,
 
-    gcvHAL_PROFILE_REGISTERS_2D,
+    /* Event signal, commit stall. */
+    gcvHAL_SIGNAL,
+
+    /* Profile related. */
+    gcvHAL_SET_PROFILE_SETTING,
+    gcvHAL_READ_PROFILER_REGISTER_SETTING,
     gcvHAL_READ_ALL_PROFILE_REGISTERS_PART1,
     gcvHAL_READ_ALL_PROFILE_REGISTERS_PART2,
-    gcvHAL_READ_PROFILER_REGISTER_SETTING,
-
-    /* Power management. */
-    gcvHAL_SET_POWER_MANAGEMENT_STATE,
-    gcvHAL_QUERY_POWER_MANAGEMENT_STATE,
-
-    gcvHAL_GET_BASE_ADDRESS,
-
-    gcvHAL_SET_IDLE, /* reserved */
-
-    /* Queries. */
-    gcvHAL_QUERY_KERNEL_SETTINGS,
-
-    /* Reset. */
-    gcvHAL_RESET,
-
-    /* Map physical address into handle. */
-    gcvHAL_MAP_PHYSICAL,
-
-    /* Debugger stuff. */
-    gcvHAL_DEBUG,
 
-    /* Cache stuff. */
-    gcvHAL_CACHE,
-
-    /* TimeStamp */
-    gcvHAL_TIMESTAMP,
-
-    /* Database. */
+    /* Query process database info when debug trace and proflie. */
     gcvHAL_DATABASE,
 
-    /* Version. */
-    gcvHAL_VERSION,
+    /* Power managment enable/disable. */
+    gcvHAL_CONFIG_POWER_MANAGEMENT,
 
-    /* Chip info */
-    gcvHAL_CHIP_INFO,
+    /* Debug/dump feature. */
+    gcvHAL_DEBUG_DUMP,
 
-    /* Process attaching/detaching. */
-    gcvHAL_ATTACH,
-    gcvHAL_DETACH,
+    /*************** Common end ***************/
 
-    /* Set timeOut value */
-    gcvHAL_SET_TIMEOUT,
+    /*************** GPU only ***************/
+    /* Register operations, 2D only. */
+    gcvHAL_READ_REGISTER,
+    gcvHAL_WRITE_REGISTER,
+    gcvHAL_PROFILE_REGISTERS_2D,
+
+    /* Get base address for old mmu. */
+    gcvHAL_GET_BASE_ADDRESS,
 
-    /* Frame database. */
+    /* Read frame database, 3D only. */
     gcvHAL_GET_FRAME_INFO,
 
-    /* GPU profile dump */
-    gcvHAL_DUMP_GPU_PROFILE,
+    /* Set video memory meta data. */
+    gcvHAL_SET_VIDEO_MEMORY_METADATA,
 
+    /* Query command buffer, VG only. */
     gcvHAL_QUERY_COMMAND_BUFFER,
 
-    gcvHAL_COMMIT_DONE,
+    /* Reset time stamp. */
+    gcvHAL_QUERY_RESET_TIME_STAMP,
 
-    /* GPU and event dump */
-    gcvHAL_DUMP_GPU_STATE,
-    gcvHAL_DUMP_EVENT,
+    /* Create native fence. */
+    gcvHAL_CREATE_NATIVE_FENCE,
 
-    /* Virtual command buffer. */
-    gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER,
-    gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER,
+    /* Wait native fence. */
+    gcvHAL_WAIT_NATIVE_FENCE,
 
-    /* FSCALE_VAL. */
-    gcvHAL_SET_FSCALE_VALUE,
-    gcvHAL_GET_FSCALE_VALUE,
+    /* Wait until GPU finishes access to a resource. */
+    gcvHAL_WAIT_FENCE,
 
-    /* Export video memory as dma_buf fd */
+    /* Video memory node operations. */
     gcvHAL_EXPORT_VIDEO_MEMORY,
     gcvHAL_NAME_VIDEO_MEMORY,
     gcvHAL_IMPORT_VIDEO_MEMORY,
 
-    /* Reset time stamp. */
-    gcvHAL_QUERY_RESET_TIME_STAMP,
-
-    /* Multi-GPU read/write. */
-    gcvHAL_READ_REGISTER_EX,
-    gcvHAL_WRITE_REGISTER_EX,
+    /* Mutex Operation. */
+    gcvHAL_DEVICE_MUTEX,
+    /*************** GPU only end ***************/
 
-    /* Create native fence and return its fd. */
-    gcvHAL_CREATE_NATIVE_FENCE,
+    /*************** DEC only ***************/
+    /* DEC200 test. */
+    gcvHAL_DEC200_TEST,
 
-    /* Let GPU wait on native fence. */
-    gcvHAL_WAIT_NATIVE_FENCE,
+    /* DEC300 related operations. */
+    gcvHAL_DEC300_READ,
+    gcvHAL_DEC300_WRITE,
+    gcvHAL_DEC300_FLUSH,
+    gcvHAL_DEC300_FLUSH_WAIT,
+    /*************** DEC only end ***************/
 
-    /* Destory MMU. */
-    gcvHAL_DESTROY_MMU,
+    /*************** OS specific ***************/
 
-    /* Shared buffer. */
+    /* Android gralloc: shared buffer operations. */
     gcvHAL_SHBUF,
 
-    /*
-     * Fd representation of android graphic buffer contents.
-     * Currently, it is only to reference video nodes, signal, etc to avoid being
-     * destroyed when trasfering across processes.
-     */
+    /* Android gralloc: get graphic buffer fd. */
     gcvHAL_GET_GRAPHIC_BUFFER_FD,
 
+    /* Vsimulator only. */
+    gcvHAL_UPDATE_DEBUG_CALLBACK,
 
-    gcvHAL_SET_VIDEO_MEMORY_METADATA,
+    /* Non paged memory management backup compatibility, windows, qnx. */
+    gcvHAL_ALLOCATE_NON_PAGED_MEMORY,
+    gcvHAL_FREE_NON_PAGED_MEMORY,
+
+    /* Write user data, windows only. */
+    gcvHAL_WRITE_DATA,
+
+    /*************** OS specific end ***************/
+
+    /*************** Reserved ***************/
+    gcvHAL_SET_IDLE,
+    gcvHAL_RESET,
+
+    /* Command commit done, kernel event only. */
+    gcvHAL_COMMIT_DONE,
 
-    /* Connect a video node to an OS native fd. */
+    /* Get video memory file description. */
     gcvHAL_GET_VIDEO_MEMORY_FD,
 
-    /* Config power management. */
-    gcvHAL_CONFIG_POWER_MANAGEMENT,
+    /* Get profile setting. */
+    gcvHAL_GET_PROFILE_SETTING,
 
-    /* Wrap a user memory into a video memory node. */
-    gcvHAL_WRAP_USER_MEMORY,
+    /* Read/Write register ex. */
+    gcvHAL_READ_REGISTER_EX,
+    gcvHAL_WRITE_REGISTER_EX,
 
-    /* Wait until GPU finishes access to a resource. */
-    gcvHAL_WAIT_FENCE,
+    /* Power managment state. */
+    gcvHAL_SET_POWER_MANAGEMENT_STATE,
+    gcvHAL_QUERY_POWER_MANAGEMENT_STATE,
 
-    /* Mutex Operation. */
-    gcvHAL_DEVICE_MUTEX,
+    /* Set debug level. */
+    gcvHAL_SET_DEBUG_LEVEL_ZONE,
 
-#if gcdDEC_ENABLE_AHB
-    gcvHAL_DEC300_READ,
-    gcvHAL_DEC300_WRITE,
-    gcvHAL_DEC300_FLUSH,
-    gcvHAL_DEC300_FLUSH_WAIT,
-#endif
+    /* Dump info. */
+    gcvHAL_DUMP_GPU_STATE,
+    gcvHAL_DUMP_EVENT,
+    gcvHAL_DUMP_GPU_PROFILE,
 
-    gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY,
-    gcvHAL_QUERY_CHIP_OPTION
+    /* Timer. */
+    gcvHAL_TIMESTAMP,
+
+    /* FSCALE_VAL. */
+    gcvHAL_SET_FSCALE_VALUE,
+    gcvHAL_GET_FSCALE_VALUE,
 
+    /* Destory MMU. */
+    gcvHAL_DESTROY_MMU,
+    /*************** Reserved end ***************/
 }
 gceHAL_COMMAND_CODES;
 
@@ -262,35 +266,62 @@ gceHAL_COMMAND_CODES;
 ****************************** Interface Structure *****************************
 \******************************************************************************/
 
-#define gcdMAX_PROFILE_FILE_NAME    128
+#define gcdMAX_PROFILE_FILE_NAME        128
+#define gcdMAX_FLAT_MAPPING_COUNT       16
 
-/* Kernel settings. */
-typedef struct _gcsKERNEL_SETTINGS
+/* gcvHAL_CHIP_INFO */
+typedef struct _gcsHAL_CHIP_INFO
 {
-    /* Used RealTime signal between kernel and user. */
-    gctINT signal;
+    /* Chip count. */
+    OUT gctINT32                count;
+
+    /* Chip types. */
+    OUT gceHARDWARE_TYPE        types[gcdCHIP_COUNT];
+
+    /* Chip IDs. */
+    OUT gctUINT32               ids[gcvCORE_COUNT];
 }
-gcsKERNEL_SETTINGS;
+gcsHAL_CHIP_INFO;
 
-typedef struct _gcsUSER_MEMORY_DESC
+/* gcvHAL_VERSION */
+typedef struct _gcsHAL_VERSION
 {
-    /* Import flag. */
-    gctUINT32                  flag;
+    /* version: <major>.<minor>.<patch>. */
+    OUT gctINT32                major;
+    OUT gctINT32                minor;
+    OUT gctINT32                patch;
 
-    /* gcvALLOC_FLAG_DMABUF */
-    gctUINT32                  handle;
-    gctUINT64                  dmabuf;
-
-    /* gcvALLOC_FLAG_USERMEMORY */
-    gctUINT64                  logical;
-    gctUINT32                  physical;
-    gctUINT32                  size;
+    /* Build version. */
+    OUT gctUINT32               build;
+}
+gcsHAL_VERSION;
 
-    /* gcvALLOC_FLAG_EXTERNAL_MEMORY */
-    gcsEXTERNAL_MEMORY_INFO    externalMemoryInfo;
+/* gcvHAL_SET_TIMEOUT. */
+typedef struct _gcsHAL_SET_TIMEOUT
+{
+    gctUINT32                   timeOut;
 }
-gcsUSER_MEMORY_DESC;
+gcsHAL_SET_TIMEOUT;
 
+/* gcvHAL_QUERY_VIDEO_MEMORY */
+typedef struct _gcsHAL_QUERY_VIDEO_MEMORY
+{
+    /* Physical memory address of internal memory. Just a name. */
+    OUT gctUINT32               internalPhysName;
+    /* Size in bytes of internal memory. */
+    OUT gctUINT64               internalSize;
+
+    /* Physical memory address of external memory. Just a name. */
+    OUT gctUINT32               externalPhysName;
+    /* Size in bytes of external memory.*/
+    OUT gctUINT64               externalSize;
+
+    /* Physical memory address of contiguous memory. Just a name. */
+    OUT gctUINT32               contiguousPhysName;
+    /* Size in bytes of contiguous memory.*/
+    OUT gctUINT64               contiguousSize;
+}
+gcsHAL_QUERY_VIDEO_MEMORY;
 
 enum
 {
@@ -300,16 +331,6 @@ enum
     gcvPLATFORM_FLAG_IMX_MM           = 1 << 1,
 };
 
-
-#define gcdMAX_FLAT_MAPPING_COUNT           16
-
-typedef struct _gcsFLAT_MAPPING_RANGE
-{
-    gctUINT64 start;
-    gctUINT64 end;
-}
-gcsFLAT_MAPPING_RANGE;
-
 /* gcvHAL_QUERY_CHIP_IDENTITY */
 typedef struct _gcsHAL_QUERY_CHIP_IDENTITY * gcsHAL_QUERY_CHIP_IDENTITY_PTR;
 typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
@@ -324,7 +345,6 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
     /* Chip date. */
     gctUINT32                   chipDate;
 
-#if gcdENABLE_VG
     /* Supported feature fields. */
     gctUINT32                   chipFeatures;
 
@@ -348,7 +368,6 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
 
     /* Supported minor feature 6 fields. */
     gctUINT32                   chipMinorFeatures6;
-#endif
 
     /* Number of streams supported. */
     gctUINT32                   streamCount;
@@ -371,6 +390,9 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
     /* Number of 3D GPUs */
     gctUINT32                   gpuCoreCount;
 
+    /* Physical mask of all AVAILABLE clusters in core.*/
+    gctUINT32                   clusterAvailMask;
+
     /* Product ID */
     gctUINT32                   productID;
 
@@ -383,1010 +405,994 @@ typedef struct _gcsHAL_QUERY_CHIP_IDENTITY
     /* Customer ID. */
     gctUINT32                   customerID;
 
-    gctUINT32                   platformFlagBits;
+    /* SRAM physical addresses and sizes. */
+    gctUINT64                   sRAMBases[gcvSRAM_COUNT];
+    gctUINT32                   sRAMSizes[gcvSRAM_COUNT];
+
+    gctUINT64                   platformFlagBits;
 }
 gcsHAL_QUERY_CHIP_IDENTITY;
 
+/* gcvHAL_QUERY_CHIP_OPTION. */
 typedef struct _gcsHAL_QUERY_CHIP_OPTIONS * gcsHAL_QUERY_CHIP_OPTIONS_PTR;
 typedef struct _gcsHAL_QUERY_CHIP_OPTIONS
 {
-    gctBOOL     gpuProfiler;
-    gctBOOL     allowFastClear;
-    gctBOOL     powerManagement;
+    gctBOOL                     gpuProfiler;
+    gctBOOL                     allowFastClear;
+    gctBOOL                     powerManagement;
     /* Whether use new MMU. It is meaningless
     ** for old MMU since old MMU is always enabled.
     */
-    gctBOOL     enableMMU;
-    gceCOMPRESSION_OPTION     allowCompression;
-    gctUINT     uscL1CacheRatio;
-    gceSECURE_MODE    secureMode;
+    gctBOOL                     enableMMU;
+    gceCOMPRESSION_OPTION       allowCompression;
+    gctBOOL                     smallBatch;
+    gctUINT32                   uscL1CacheRatio;
+    gctUINT32                   uscAttribCacheRatio;
+    gctUINT32                   userClusterMask;
+    gctUINT32                   sRAMBaseAddress[gcvSRAM_COUNT];
+    gceSECURE_MODE              secureMode;
 
 }
 gcsHAL_QUERY_CHIP_OPTIONS;
 
-typedef struct _gcsHAL_INTERFACE
+/* gcvHAL_QUERY_CHIP_FREQUENCY. */
+typedef struct _gcsHAL_QUERY_CHIP_FREQUENCY * gcsHAL_QUERY_CHIP_FREQUENCY_PTR;
+typedef struct _gcsHAL_QUERY_CHIP_FREQUENCY
 {
-    /* Command code. */
-    gceHAL_COMMAND_CODES        command;
+    OUT gctUINT32               mcClk;
+    OUT gctUINT32               shClk;
+}
+gcsHAL_QUERY_CHIP_FREQUENCY;
 
-    /* Hardware type. */
-    gceHARDWARE_TYPE            hardwareType;
+/* Obsolete for userpace. */
+/* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
+typedef struct _gcsHAL_ALLOCATE_NON_PAGED_MEMORY
+{
+    /* Allocation flags. */
+    IN gctUINT32                flags;
 
-    /* Core index for current hardware type. */
-    gctUINT32                   coreIndex;
+    /* Number of bytes to allocate. */
+    IN OUT gctUINT64            bytes;
 
-    /* Status value. */
-    gceSTATUS                   status;
+    /* Physical address of allocation. Just a name. */
+    OUT gctUINT32               physName;
 
-    /* Handle to this interface channel. */
-    gctUINT64                   handle;
+    /* Logical address of allocation. */
+    OUT gctUINT64               logical;
+}
+gcsHAL_ALLOCATE_NON_PAGED_MEMORY;
 
-    /* Pid of the client. */
-    gctUINT32                   pid;
+/* Obsolete for userpace. */
+/* gcvHAL_FREE_NON_PAGED_MEMORY */
+typedef struct _gcsHAL_FREE_NON_PAGED_MEMORY
+{
+    /* Number of bytes allocated. */
+    IN gctUINT64                bytes;
 
-    /* Engine */
-    gceENGINE                   engine;
+    /* Physical address of allocation. Just a name. */
+    IN gctUINT32                physName;
 
-    /* Ignore information from TSL when doing IO control */
-    gctBOOL                     ignoreTLS;
+    /* Logical address of allocation. */
+    IN gctUINT64                logical;
+}
+gcsHAL_FREE_NON_PAGED_MEMORY;
 
-    /* The mutext already acquired */
-    IN gctBOOL                  commitMutex;
+/* Video memory allocation. */
+/* gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY */
+typedef struct _gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY
+{
+    /* Number of bytes to allocate. */
+    IN OUT gctUINT64            bytes;
 
-    /* Union of command structures. */
-    union _u
-    {
-        /* gcvHAL_GET_BASE_ADDRESS */
-        struct _gcsHAL_GET_BASE_ADDRESS
-        {
-            /* Physical memory address of internal memory. */
-            OUT gctUINT32               baseAddress;
-
-            OUT gctUINT32               flatMappingRangeCount;
-
-            OUT gcsFLAT_MAPPING_RANGE   flatMappingRanges[gcdMAX_FLAT_MAPPING_COUNT];
-        }
-        GetBaseAddress;
-
-        /* gcvHAL_QUERY_VIDEO_MEMORY */
-        struct _gcsHAL_QUERY_VIDEO_MEMORY
-        {
-            /* Physical memory address of internal memory. Just a name. */
-            OUT gctUINT32               internalPhysical;
+    /* Buffer alignment. */
+    IN gctUINT32                alignment;
 
-            /* Size in bytes of internal memory. */
-            OUT gctUINT64               internalSize;
-
-            /* Physical memory address of external memory. Just a name. */
-            OUT gctUINT32               externalPhysical;
-
-            /* Size in bytes of external memory.*/
-            OUT gctUINT64               externalSize;
-
-            /* Physical memory address of contiguous memory. Just a name. */
-            OUT gctUINT32               contiguousPhysical;
-
-            /* Size in bytes of contiguous memory.*/
-            OUT gctUINT64               contiguousSize;
-        }
-        QueryVideoMemory;
-
-        /* gcvHAL_QUERY_CHIP_IDENTITY */
-        gcsHAL_QUERY_CHIP_IDENTITY      QueryChipIdentity;
-
-        struct _gcsHAL_QUERY_CHIP_FREQUENCY
-        {
-            OUT gctUINT32               mcClk;
-            OUT gctUINT32               shClk;
-        }
-        QueryChipFrequency;
-
-        /* gcvHAL_MAP_MEMORY */
-        struct _gcsHAL_MAP_MEMORY
-        {
-            /* Physical memory address to map. Just a name on Linux/Qnx. */
-            IN gctUINT32                physical;
-
-            /* Number of bytes in physical memory to map. */
-            IN gctUINT64                bytes;
-
-            /* Address of mapped memory. */
-            OUT gctUINT64               logical;
-        }
-        MapMemory;
-
-        /* gcvHAL_UNMAP_MEMORY */
-        struct _gcsHAL_UNMAP_MEMORY
-        {
-            /* Physical memory address to unmap. Just a name on Linux/Qnx. */
-            IN gctUINT32                physical;
-
-            /* Number of bytes in physical memory to unmap. */
-            IN gctUINT64                bytes;
-
-            /* Address of mapped memory to unmap. */
-            IN gctUINT64                logical;
-        }
-        UnmapMemory;
-
-        /* gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY */
-        struct _gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY
-        {
-            /* Number of bytes to allocate. */
-            IN OUT gctUINT              bytes;
-
-            /* Buffer alignment. */
-            IN gctUINT                  alignment;
-
-            /* Type of allocation. */
-            IN gceSURF_TYPE             type;
-
-            /* Flag of allocation. */
-            IN gctUINT32                flag;
-
-            /* Memory pool to allocate from. */
-            IN OUT gcePOOL              pool;
-
-            /* Allocated video memory. */
-            OUT gctUINT32               node;
-        }
-        AllocateLinearVideoMemory;
-
-        /* gcvHAL_ALLOCATE_VIDEO_MEMORY */
-        struct _gcsHAL_ALLOCATE_VIDEO_MEMORY
-        {
-            /* Width of rectangle to allocate. */
-            IN OUT gctUINT              width;
+    /* Type of allocation, see gceVIDMEM_TYPE. */
+    IN gctUINT32                type;
 
-            /* Height of rectangle to allocate. */
-            IN OUT gctUINT              height;
+    /* Flag of allocation. */
+    IN gctUINT32                flag;
 
-            /* Depth of rectangle to allocate. */
-            IN gctUINT                  depth;
+    /* Memory pool to allocate from. */
+    IN OUT gctUINT32            pool;
 
-            /* Format rectangle to allocate in gceSURF_FORMAT. */
-            IN gceSURF_FORMAT           format;
+    /* Allocated video memory. */
+    OUT gctUINT32               node;
+}
+gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY;
 
-            /* Type of allocation. */
-            IN gceSURF_TYPE             type;
+typedef struct _gcsUSER_MEMORY_DESC
+{
+    /* Import flag. */
+    gctUINT32                  flag;
 
-            /* Memory pool to allocate from. */
-            IN OUT gcePOOL              pool;
+    /* gcvALLOC_FLAG_DMABUF */
+    gctUINT32                  handle;
+    gctUINT64                  dmabuf;
 
-            /* Allocated video memory. */
-            OUT gctUINT32               node;
-        }
-        AllocateVideoMemory;
+    /* gcvALLOC_FLAG_USERMEMORY */
+    gctUINT64                  logical;
+    gctUINT64                  physical;
+    gctUINT32                  size;
 
-        /* gcvHAL_RELEASE_VIDEO_MEMORY */
-        struct _gcsHAL_RELEASE_VIDEO_MEMORY
-        {
-            /* Allocated video memory. */
-            IN gctUINT32                node;
+    /* gcvALLOC_FLAG_EXTERNAL_MEMORY */
+    gcsEXTERNAL_MEMORY_INFO    externalMemoryInfo;
+}
+gcsUSER_MEMORY_DESC;
+
+/* gcvHAL_WRAP_USER_MEMORY. */
+typedef struct _gcsHAL_WRAP_USER_MEMORY
+{
+    /* Description of user memory. */
+    IN gcsUSER_MEMORY_DESC      desc;
+
+    /* Video memory allocation type. */
+    IN gctUINT32                type;
+
+    /* Output video mmory node. */
+    OUT gctUINT32               node;
+
+    /* size of the node in bytes */
+    OUT gctUINT64               bytes;
+}
+gcsHAL_WRAP_USER_MEMORY;
+
+/* gcvHAL_RELEASE_VIDEO_MEMORY */
+typedef struct _gcsHAL_RELEASE_VIDEO_MEMORY
+{
+    /* Allocated video memory. */
+    IN gctUINT32                node;
 
 #ifdef __QNXNTO__
-            /* Mapped logical address to unmap in user space. */
-            OUT gctUINT64               memory;
+    /* Mapped logical address to unmap in user space. */
+    OUT gctUINT64               memory;
 
-            /* Number of bytes to allocated. */
-            OUT gctUINT64               bytes;
+    /* Number of bytes to allocated. */
+    OUT gctUINT64               bytes;
 #endif
-        }
-        ReleaseVideoMemory;
-
-        /* gcvHAL_LOCK_VIDEO_MEMORY */
-        struct _gcsHAL_LOCK_VIDEO_MEMORY
-        {
-            /* Allocated video memory. */
-            IN gctUINT32                node;
-
-            /* Cache configuration. */
-            /* Only gcvPOOL_CONTIGUOUS and gcvPOOL_VIRUTAL
-            ** can be configured */
-            IN gctBOOL                  cacheable;
-
-            /* Hardware specific address. */
-            OUT gctUINT32               address;
-
-            /* Mapped logical address. */
-            OUT gctUINT64               memory;
-
-            /* Customer priviate handle*/
-            OUT gctUINT32               gid;
-
-            /* Bus address of a contiguous video node. */
-            OUT gctUINT64               physicalAddress;
-        }
-        LockVideoMemory;
-
-        /* gcvHAL_UNLOCK_VIDEO_MEMORY */
-        struct _gcsHAL_UNLOCK_VIDEO_MEMORY
-        {
-            /* Allocated video memory. */
-            IN gctUINT64                node;
+}
+gcsHAL_RELEASE_VIDEO_MEMORY;
 
-            /* Type of surface. */
-            IN gceSURF_TYPE             type;
+/* gcvHAL_LOCK_VIDEO_MEMORY */
+typedef struct _gcsHAL_LOCK_VIDEO_MEMORY
+{
+    /* Allocated video memory. */
+    IN gctUINT32                node;
 
-            /* Pool of the unlock node */
-            OUT gcePOOL                 pool;
+    /* Cache configuration. */
+    /* Only gcvPOOL_VIRTUAL can be configured */
+    IN gctBOOL                  cacheable;
 
-            /* Bytes of the unlock node */
-            OUT gctUINT                 bytes;
+    /* Hardware specific address. */
+    OUT gctUINT32               address;
 
-            /* Flag to unlock surface asynchroneously. */
-            IN OUT gctBOOL              asynchroneous;
-        }
-        UnlockVideoMemory;
+    /* Mapped logical address. */
+    OUT gctUINT64               memory;
 
-        /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
-        struct _gcsHAL_ALLOCATE_NON_PAGED_MEMORY
-        {
-            /* Number of bytes to allocate. */
-            IN OUT gctUINT64        bytes;
+    /* Customer priviate handle*/
+    OUT gctUINT32               gid;
 
-            /* Physical address of allocation. Just a name. */
-            OUT gctUINT32           physical;
+    /* Bus address of a contiguous video node. */
+    OUT gctUINT64               physicalAddress;
+}
+gcsHAL_LOCK_VIDEO_MEMORY;
 
-            /* Logical address of allocation. */
-            OUT gctUINT64           logical;
-        }
-        AllocateNonPagedMemory;
+/* gcvHAL_UNLOCK_VIDEO_MEMORY */
+typedef struct _gcsHAL_UNLOCK_VIDEO_MEMORY
+{
+    /* Allocated video memory. */
+    IN gctUINT64                node;
 
-        /* gcvHAL_FREE_NON_PAGED_MEMORY */
-        struct _gcsHAL_FREE_NON_PAGED_MEMORY
-        {
-            /* Number of bytes allocated. */
-            IN gctUINT64            bytes;
+    /* Video memory allocation type. */
+    IN gctUINT32                type;
 
-            /* Physical address of allocation. Just a name. */
-            IN gctUINT32            physical;
+    /* Pool of the unlock node */
+    OUT gctUINT32               pool;
 
-            /* Logical address of allocation. */
-            IN gctUINT64            logical;
-        }
-        FreeNonPagedMemory;
+    /* Bytes of the unlock node */
+    OUT gctUINT64               bytes;
 
-        /* gcvHAL_ALLOCATE_NON_PAGED_MEMORY */
-        struct _gcsHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER
-        {
-            /* Number of bytes to allocate. */
-            IN OUT gctUINT64        bytes;
+    /* Flag to unlock surface asynchroneously. */
+    IN OUT gctBOOL              asynchroneous;
+}
+gcsHAL_UNLOCK_VIDEO_MEMORY;
 
-            /* Physical address of allocation. Just a name. */
-            OUT gctUINT32           physical;
+/* gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY: */
+typedef struct _gcsHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY
+{
+    /* Allocated video memory. */
+    IN gctUINT32                node;
 
-            /* Logical address of allocation. */
-            OUT gctUINT64           logical;
-        }
-        AllocateVirtualCommandBuffer;
+    /* Video memory allocation type. */
+    IN gctUINT32                type;
+}
+gcsHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY;
+
+/* gcvHAL_EXPORT_VIDEO_MEMORY. */
+typedef struct _gcsHAL_EXPORT_VIDEO_MEMORY
+{
+    /* Allocated video memory. */
+    IN gctUINT32                node;
+
+    /* Export flags */
+    IN gctUINT32                flags;
+
+    /* Exported dma_buf fd */
+    OUT gctINT32                fd;
+}
+gcsHAL_EXPORT_VIDEO_MEMORY;
+
+/* gcvHAL_NAME_VIDEO_MEMORY. */
+typedef struct _gcsHAL_NAME_VIDEO_MEMORY
+{
+    IN gctUINT32                handle;
+    OUT gctUINT32               name;
+}
+gcsHAL_NAME_VIDEO_MEMORY;
+
+/* gcvHAL_IMPORT_VIDEO_MEMORY. */
+typedef struct _gcsHAL_IMPORT_VIDEO_MEMORY
+{
+    IN gctUINT32                name;
+    OUT gctUINT32               handle;
+}
+gcsHAL_IMPORT_VIDEO_MEMORY;
+
+/* gcvHAL_MAP_MEMORY */
+typedef struct _gcsHAL_MAP_MEMORY
+{
+    /* Physical memory address to map. Just a name on Linux/Qnx. */
+    IN gctUINT32                physName;
+
+    /* Number of bytes in physical memory to map. */
+    IN gctUINT64                bytes;
 
-        /* gcvHAL_FREE_NON_PAGED_MEMORY */
-        struct _gcsHAL_FREE_VIRTUAL_COMMAND_BUFFER
-        {
-            /* Number of bytes allocated. */
-            IN gctUINT64            bytes;
-
-            /* Physical address of allocation. Just a name. */
-            IN gctUINT32            physical;
-
-            /* Logical address of allocation. */
-            IN gctUINT64            logical;
-        }
-        FreeVirtualCommandBuffer;
-
-        /* gcvHAL_EVENT_COMMIT. */
-        struct _gcsHAL_EVENT_COMMIT
-        {
-            /* Event queue in gcsQUEUE. */
-            IN gctUINT64            queue;
-        }
-        Event;
-
-        /* gcvHAL_COMMIT */
-        struct _gcsHAL_COMMIT
-        {
-            /* Context buffer object gckCONTEXT. */
-            IN gctUINT64            context;
-
-            /* Command buffer gcoCMDBUF. */
-            IN gctUINT64            commandBuffer;
-
-            /* State delta buffer in gcsSTATE_DELTA. */
-            gctUINT64               delta;
-
-            gctUINT64               deltas[gcvCORE_COUNT];
-
-            gctUINT64               contexts[gcvCORE_COUNT];
-
-            gctUINT64               commandBuffers[gcvCORE_COUNT];
-
-
-            /* Event queue in gcsQUEUE. */
-            IN gctUINT64            queue;
+    /* Address of mapped memory. */
+    OUT gctUINT64               logical;
+}
+gcsHAL_MAP_MEMORY;
 
-            /* Used to distinguish different FE. */
-            IN gceENGINE            engine1;
+/* gcvHAL_UNMAP_MEMORY */
+typedef struct _gcsHAL_UNMAP_MEMORY
+{
+    /* Physical memory address to unmap. Just a name on Linux/Qnx. */
+    IN gctUINT32                physName;
 
-            /* The command buffer is linked to multiple command queue. */
-            IN gctBOOL              shared;
-
-            /* Index of command queue. */
-            IN gctUINT32            index;
-
-            /* Count of gpu core. */
-            IN gctUINT32            count;
-
-            /* Commit stamp of this commit. */
-            OUT gctUINT64           commitStamp;
-
-            /* If context switch for this commit */
-            OUT gctBOOL             contextSwitched;
-        }
-        Commit;
+    /* Number of bytes in physical memory to unmap. */
+    IN gctUINT64                bytes;
 
-        /* gcvHAL_MAP_USER_MEMORY */
-        struct _gcsHAL_MAP_USER_MEMORY
-        {
-            /* Base address of user memory to map. */
-            IN gctUINT64                memory;
-
-            /* Physical address of user memory to map. */
-            IN gctUINT32                physical;
-
-            /* Size of user memory in bytes to map. */
-            IN gctUINT64                size;
+    /* Address of mapped memory to unmap. */
+    IN gctUINT64                logical;
+}
+gcsHAL_UNMAP_MEMORY;
 
-            /* Info record required by gcvHAL_UNMAP_USER_MEMORY. Just a name. */
-            OUT gctUINT32               info;
+/* gcvHAL_CACHE */
+typedef struct _gcsHAL_CACHE
+{
+    IN gceCACHEOPERATION        operation;
+    IN gctUINT64                process;
+    IN gctUINT64                logical;
+    IN gctUINT64                bytes;
+    IN gctUINT32                node;
+}
+gcsHAL_CACHE;
 
-            /* Physical address of mapped memory. */
-            OUT gctUINT32               address;
-        }
-        MapUserMemory;
+/* gcvHAL_ATTACH */
+typedef struct _gcsHAL_ATTACH
+{
+    /* Handle of context buffer object. */
+    OUT gctUINT32               context;
 
-        /* gcvHAL_UNMAP_USER_MEMORY */
-        struct _gcsHAL_UNMAP_USER_MEMORY
-        {
-            /* Base address of user memory to unmap. */
-            IN gctUINT64                memory;
+    /* Maximum state in the buffer. */
+    OUT gctUINT64               maxState;
 
-            /* Size of user memory in bytes to unmap. */
-            IN gctUINT64                size;
+    /* Number of states in the buffer. */
+    OUT gctUINT32               numStates;
 
-            /* Info record returned by gcvHAL_MAP_USER_MEMORY. Just a name. */
-            IN gctUINT32                info;
+    /* Map context buffer to user or not. */
+    IN gctBOOL                  map;
 
-            /* Physical address of mapped memory as returned by
-               gcvHAL_MAP_USER_MEMORY. */
-            IN gctUINT32                address;
-        }
-        UnmapUserMemory;
-#if !USE_NEW_LINUX_SIGNAL
-        /* gcsHAL_USER_SIGNAL  */
-        struct _gcsHAL_USER_SIGNAL
-        {
-            /* Command. */
-            gceUSER_SIGNAL_COMMAND_CODES command;
+    /* Physical of context buffer. */
+    OUT gctUINT64               logicals[2];
 
-            /* Signal ID. */
-            IN OUT gctINT               id;
+    /* Bytes of context buffer. */
+    OUT gctUINT32               bytes;
+}
+gcsHAL_ATTACH;
 
-            /* Reset mode. */
-            IN gctBOOL                  manualReset;
+/* gcvHAL_DETACH */
+typedef struct _gcsHAL_DETACH
+{
+    /* Context buffer object gckCONTEXT. Just a name. */
+    IN gctUINT32                context;
+}
+gcsHAL_DETACH;
+
+
+/* gcvHAL_EVENT_COMMIT. */
+typedef struct _gcsHAL_EVENT_COMMIT
+{
+    /* Event queue in gcsQUEUE. */
+    IN gctUINT64                queue;
+}
+gcsHAL_EVENT_COMMIT;
+
+typedef struct _gcsHAL_COMMAND_LOCATION
+{
+    gctUINT32                   priority;
+    gctUINT32                   channelId;
 
-            /* Wait timedout. */
-            IN gctUINT32                wait;
+    gctUINT32                   videoMemNode;
 
-            /* State. */
-            IN gctBOOL                  state;
-        }
-        UserSignal;
+    gctUINT32                   address;
+    gctUINT64                   logical;
+    gctUINT32                   startOffset;
+    /* size includes reservedHead and reservedTail. */
+    gctUINT32                   size;
+
+    gctUINT32                   reservedHead;
+    gctUINT32                   reservedTail;
+
+    /* Pointer to patch list. */
+    gctUINT64                   patchHead;
+
+    /*
+     * Location index of exit commands, ie where to put the chipEnable/link back
+     * commands in the reservedTail area.
+     * It's used in fully shared command buffer for multiple cores.
+     */
+    gctUINT32                   exitIndex;
+    gctUINT32                   entryPipe;
+    gctUINT32                   exitPipe;
+
+    /* struct _gcsHAL_COMMAND_LOCATION * next; */
+    gctUINT64                   next;
+}
+gcsHAL_COMMAND_LOCATION;
+
+typedef struct _gcsHAL_SUBCOMMIT
+{
+    gctUINT32                   coreId;
+
+    /* user gcsSTATE_DELTA_PTR. */
+    gctUINT64                   delta;
+
+    /* Kernel gckCONTEXT. */
+    gctUINT64                   context;
+
+    /* Event queue in user gcsQUEUE *. */
+    gctUINT64                   queue;
+
+    /* Locate the commands. */
+    gcsHAL_COMMAND_LOCATION     commandBuffer;
+
+    /* struct _gcsHAL_SUBCOMMIT * next; */
+    gctUINT64                   next;
+}
+gcsHAL_SUBCOMMIT;
+
+/* gcvHAL_COMMIT */
+typedef struct _gcsHAL_COMMIT
+{
+    gcsHAL_SUBCOMMIT            subCommit;
+
+    gctBOOL                     shared;
+
+    /* Commit stamp of this commit. */
+    OUT gctUINT64               commitStamp;
+}
+gcsHAL_COMMIT;
+
+#if gcdENABLE_VG
+/* gcvHAL_COMMIT */
+typedef struct _gcsHAL_VGCOMMIT
+{
+    /* Context buffer. gcsVGCONTEXT_PTR */
+    IN gctUINT64                context;
+
+    /* Command queue. gcsVGCMDQUEUE_PTR */
+    IN gctUINT64                queue;
+
+    /* Number of entries in the queue. */
+    IN gctUINT32                entryCount;
+
+    /* Task table. gcsTASK_MASTER_TABLE_PTR */
+    IN gctUINT64                taskTable;
+}
+gcsHAL_VGCOMMIT;
 #endif
 
-        /* gcvHAL_SIGNAL. */
-        struct _gcsHAL_SIGNAL
-        {
-            /* Signal handle to signal gctSIGNAL. */
-            IN gctUINT64                signal;
+typedef struct _gcsHAL_COMMIT_DONE
+{
+    IN gctUINT64                context;
+}
+gcsHAL_COMMIT_DONE;
+
+/* gcvHAL_USER_SIGNAL  */
+typedef struct _gcsHAL_USER_SIGNAL
+{
+    /* Command. */
+    gceUSER_SIGNAL_COMMAND_CODES command;
+
+    /* Signal ID. */
+    IN OUT gctINT32             id;
+
+    /* Reset mode. */
+    IN gctBOOL                  manualReset;
+
+    /* Wait timedout. */
+    IN gctUINT32                wait;
+
+    /* State. */
+    IN gctBOOL                  state;
+}
+gcsHAL_USER_SIGNAL;
+
+/* gcvHAL_SIGNAL. */
+typedef struct _gcsHAL_SIGNAL
+{
+    /* Signal handle to signal gctSIGNAL. */
+    IN gctUINT64                signal;
 
-            /* Reserved gctSIGNAL. */
-            IN gctUINT64                auxSignal;
+    /* Reserved gctSIGNAL. */
+    IN gctUINT64                auxSignal;
 
-            /* Process owning the signal gctHANDLE. */
-            IN gctUINT64                process;
+    /* Process owning the signal gctHANDLE. */
+    IN gctUINT64                process;
 
 #if defined(__QNXNTO__)
-            /* Client pulse side-channel connection ID. Set by client in gcoOS_CreateSignal. */
-            IN gctINT32                 coid;
+    /* Client pulse side-channel connection ID. Set by client in gcoOS_CreateSignal. */
+    IN gctINT32                 coid;
 
-            /* Set by server. */
-            IN gctINT32                 rcvid;
+    /* Set by server. */
+    IN gctINT32                 rcvid;
 #endif
-            /* Event generated from where of pipeline */
-            IN gceKERNEL_WHERE          fromWhere;
-        }
-        Signal;
-
-        /* gcvHAL_WRITE_DATA. */
-        struct _gcsHAL_WRITE_DATA
-        {
-            /* Address to write data to. */
-            IN gctUINT32                address;
-
-            /* Data to write. */
-            IN gctUINT32                data;
-        }
-        WriteData;
-
-        /* gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY */
-        struct _gcsHAL_ALLOCATE_CONTIGUOUS_MEMORY
-        {
-            /* Number of bytes to allocate. */
-            IN OUT gctUINT64            bytes;
-
-            /* Hardware address of allocation. */
-            OUT gctUINT32               address;
-
-            /* Physical address of allocation. Just a name. */
-            OUT gctUINT32               physical;
-
-            /* Logical address of allocation. */
-            OUT gctUINT64               logical;
-        }
-        AllocateContiguousMemory;
-
-        /* gcvHAL_FREE_CONTIGUOUS_MEMORY */
-        struct _gcsHAL_FREE_CONTIGUOUS_MEMORY
-        {
-            /* Number of bytes allocated. */
-            IN gctUINT64                bytes;
-
-            /* Physical address of allocation. Just a name. */
-            IN gctUINT32                physical;
-
-            /* Logical address of allocation. */
-            IN gctUINT64                logical;
-        }
-        FreeContiguousMemory;
-
-        /* gcvHAL_READ_REGISTER */
-        struct _gcsHAL_READ_REGISTER
-        {
-            /* Logical address of memory to write data to. */
-            IN gctUINT32            address;
-
-            /* Data read. */
-            OUT gctUINT32           data;
-        }
-        ReadRegisterData;
-
-        /* gcvHAL_WRITE_REGISTER */
-        struct _gcsHAL_WRITE_REGISTER
-        {
-            /* Logical address of memory to write data to. */
-            IN gctUINT32            address;
-
-            /* Data read. */
-            IN gctUINT32            data;
-        }
-        WriteRegisterData;
-
-        /* gcvHAL_READ_REGISTER_EX */
-        struct _gcsHAL_READ_REGISTER_EX
-        {
-            /* Logical address of memory to write data to. */
-            IN gctUINT32            address;
-
-            IN gctUINT32            coreSelect;
-
-            /* Data read. */
-            OUT gctUINT32           data[4];
-        }
-        ReadRegisterDataEx;
-
-        /* gcvHAL_WRITE_REGISTER_EX */
-        struct _gcsHAL_WRITE_REGISTER_EX
-        {
-            /* Logical address of memory to write data to. */
-            IN gctUINT32            address;
-
-            IN gctUINT32            coreSelect;
-
-            /* Data read. */
-            IN gctUINT32            data[4];
-        }
-        WriteRegisterDataEx;
+    /* Event generated from where of pipeline */
+    IN gceKERNEL_WHERE          fromWhere;
+}
+gcsHAL_SIGNAL;
+
+/* gcvHAL_WRITE_DATA. */
+typedef struct _gcsHAL_WRITE_DATA
+{
+    /* Address to write data to. */
+    IN gctUINT32                address;
+
+    /* Data to write. */
+    IN gctUINT32                data;
+}
+gcsHAL_WRITE_DATA;
+
+/* gcvHAL_READ_REGISTER */
+typedef struct _gcsHAL_READ_REGISTER
+{
+    /* Logical address of memory to write data to. */
+    IN gctUINT32                address;
+
+    /* Data read. */
+    OUT gctUINT32               data;
+}
+gcsHAL_READ_REGISTER;
+
+/* gcvHAL_WRITE_REGISTER */
+typedef struct _gcsHAL_WRITE_REGISTER
+{
+    /* Logical address of memory to write data to. */
+    IN gctUINT32                address;
+
+    /* Data read. */
+    IN gctUINT32                data;
+}
+gcsHAL_WRITE_REGISTER;
+
+/* gcvHAL_READ_REGISTER_EX */
+typedef struct _gcsHAL_READ_REGISTER_EX
+{
+    /* Logical address of memory to write data to. */
+    IN gctUINT32                address;
+
+    IN gctUINT32                coreSelect;
+
+    /* Data read. */
+    OUT gctUINT32               data[4];
+}
+gcsHAL_READ_REGISTER_EX;
+
+/* gcvHAL_WRITE_REGISTER_EX */
+typedef struct _gcsHAL_WRITE_REGISTER_EX
+{
+    /* Logical address of memory to write data to. */
+    IN gctUINT32                address;
+
+    IN gctUINT32                coreSelect;
+
+    /* Data read. */
+    IN gctUINT32                data[4];
+}
+gcsHAL_WRITE_REGISTER_EX;
 
 #if VIVANTE_PROFILER
-        /* gcvHAL_GET_PROFILE_SETTING */
-        struct _gcsHAL_GET_PROFILE_SETTING
-        {
-            /* Enable profiling */
-            OUT gctBOOL             enable;
-        }
-        GetProfileSetting;
-
-        /* gcvHAL_SET_PROFILE_SETTING */
-        struct _gcsHAL_SET_PROFILE_SETTING
-        {
-            /* Enable profiling */
-            IN gctBOOL              enable;
-        }
-        SetProfileSetting;
-
-        /* gcvHAL_READ_PROFILER_REGISTER_SETTING */
-        struct _gcsHAL_READ_PROFILER_REGISTER_SETTING
-        {
-            /*Should Clear Register*/
-            IN gctBOOL               bclear;
-        }
-        SetProfilerRegisterClear;
-
-        struct _gcsHAL_READ_ALL_PROFILE_REGISTERS_PART1
-        {
-            /* Context buffer object gckCONTEXT. Just a name. */
-            IN gctUINT32                    context;
-
-            /* Data read. */
-            OUT gcsPROFILER_COUNTERS_PART1    Counters;
-        }
-        RegisterProfileData_part1;
-
-        struct _gcsHAL_READ_ALL_PROFILE_REGISTERS_PART2
-        {
-            /* Context buffer object gckCONTEXT. Just a name. */
-            IN gctUINT32                    context;
-
-            /* Data read. */
-            OUT gcsPROFILER_COUNTERS_PART2    Counters;
-        }
-        RegisterProfileData_part2;
-
-        /* gcvHAL_PROFILE_REGISTERS_2D */
-        struct _gcsHAL_PROFILE_REGISTERS_2D
-        {
-            /* Data read in gcs2D_PROFILE. */
-            OUT gctUINT64       hwProfile2D;
-        }
-        RegisterProfileData2D;
+/* gcvHAL_GET_PROFILE_SETTING */
+typedef struct _gcsHAL_GET_PROFILE_SETTING
+{
+    /* Enable profiling */
+    OUT gctBOOL                 enable;
+}
+gcsHAL_GET_PROFILE_SETTING;
+
+/* gcvHAL_SET_PROFILE_SETTING */
+typedef struct _gcsHAL_SET_PROFILE_SETTING
+{
+    /* Enable profiling */
+    IN gctBOOL                  enable;
+}
+gcsHAL_SET_PROFILE_SETTING;
+
+/* gcvHAL_READ_PROFILER_REGISTER_SETTING */
+typedef struct _gcsHAL_READ_PROFILER_REGISTER_SETTING
+{
+    /*Should Clear Register*/
+    IN gctBOOL                  bclear;
+}
+gcsHAL_READ_PROFILER_REGISTER_SETTING;
+
+typedef struct _gcsHAL_READ_ALL_PROFILE_REGISTERS_PART1
+{
+    /* Context buffer object gckCONTEXT. Just a name. */
+    IN gctUINT32                context;
+
+    /* Data read. */
+    OUT gcsPROFILER_COUNTERS_PART1 Counters;
+}
+gcsHAL_READ_ALL_PROFILE_REGISTERS_PART1;
+
+typedef struct _gcsHAL_READ_ALL_PROFILE_REGISTERS_PART2
+{
+    /* Context buffer object gckCONTEXT. Just a name. */
+    IN gctUINT32                context;
+
+    /* Data read. */
+    OUT gcsPROFILER_COUNTERS_PART2 Counters;
+}
+gcsHAL_READ_ALL_PROFILE_REGISTERS_PART2;
+
+/* gcvHAL_PROFILE_REGISTERS_2D */
+typedef struct _gcsHAL_PROFILE_REGISTERS_2D
+{
+    /* Data read in gcs2D_PROFILE. */
+    OUT gctUINT64               hwProfile2D;
+}
+gcsHAL_PROFILE_REGISTERS_2D;
 #endif
 
-        /* Power management. */
-        /* gcvHAL_SET_POWER_MANAGEMENT_STATE */
-        struct _gcsHAL_SET_POWER_MANAGEMENT
-        {
-            /* Data read. */
-            IN gceCHIPPOWERSTATE        state;
-        }
-        SetPowerManagement;
-
-        /* gcvHAL_QUERY_POWER_MANAGEMENT_STATE */
-        struct _gcsHAL_QUERY_POWER_MANAGEMENT
-        {
-            /* Data read. */
-            OUT gceCHIPPOWERSTATE       state;
-
-            /* Idle query. */
-            OUT gctBOOL                 isIdle;
-        }
-        QueryPowerManagement;
-
-        /* gcvHAL_QUERY_KERNEL_SETTINGS */
-        struct _gcsHAL_QUERY_KERNEL_SETTINGS
-        {
-            /* Settings.*/
-            OUT gcsKERNEL_SETTINGS      settings;
-        }
-        QueryKernelSettings;
-
-        /* gcvHAL_MAP_PHYSICAL */
-        struct _gcsHAL_MAP_PHYSICAL
-        {
-            /* gcvTRUE to map, gcvFALSE to unmap. */
-            IN gctBOOL                  map;
-
-            /* Physical address. */
-            IN OUT gctUINT64            physical;
-        }
-        MapPhysical;
-
-        /* gcvHAL_DEBUG */
-        struct _gcsHAL_DEBUG
-        {
-            /* If gcvTRUE, set the debug information. */
-            IN gctBOOL                  set;
-            IN gctUINT32                level;
-            IN gctUINT32                zones;
-            IN gctBOOL                  enable;
-
-            IN gceDEBUG_MESSAGE_TYPE    type;
-            IN gctUINT32                messageSize;
-
-            /* Message to print if not empty. */
-            IN gctCHAR                  message[80];
-
-        }
-        Debug;
-
-        /* gcvHAL_CACHE */
-        struct _gcsHAL_CACHE
-        {
-            IN gceCACHEOPERATION        operation;
-            IN gctUINT64                process;
-            IN gctUINT64                logical;
-            IN gctUINT64                bytes;
-            IN gctUINT32                node;
-        }
-        Cache;
-
-        /* gcvHAL_TIMESTAMP */
-        struct _gcsHAL_TIMESTAMP
-        {
-            /* Timer select. */
-            IN gctUINT32                timer;
-
-            /* Timer request type (0-stop, 1-start, 2-send delta). */
-            IN gctUINT32                request;
-
-            /* Result of delta time in microseconds. */
-            OUT gctINT32                timeDelta;
-        }
-        TimeStamp;
-
-        /* gcvHAL_DATABASE */
-        struct _gcsHAL_DATABASE
-        {
-            /* Set to gcvTRUE if you want to query a particular process ID.
-            ** Set to gcvFALSE to query the last detached process. */
-            IN gctBOOL                  validProcessID;
-
-            /* Process ID to query. */
-            IN gctUINT32                processID;
-
-            /* Information. */
-            OUT gcuDATABASE_INFO        vidMem;
-            OUT gcuDATABASE_INFO        nonPaged;
-            OUT gcuDATABASE_INFO        contiguous;
-            OUT gcuDATABASE_INFO        gpuIdle;
-
-            /* Detail information about video memory. */
-            OUT gcuDATABASE_INFO        vidMemPool[3];
-        }
-        Database;
-
-        /* gcvHAL_VERSION */
-        struct _gcsHAL_VERSION
-        {
-            /* Major version: N.n.n. */
-            OUT gctINT32                major;
-
-            /* Minor version: n.N.n. */
-            OUT gctINT32                minor;
-
-            /* Patch version: n.n.N. */
-            OUT gctINT32                patch;
-
-            /* Build version. */
-            OUT gctUINT32               build;
-        }
-        Version;
-
-        /* gcvHAL_CHIP_INFO */
-        struct _gcsHAL_CHIP_INFO
-        {
-            /* Chip count. */
-            OUT gctINT32                count;
-
-            /* Chip types. */
-            OUT gceHARDWARE_TYPE        types[gcdCHIP_COUNT];
-
-            /* Chip IDs. */
-            OUT gctUINT32               ids[gcvCORE_COUNT];
-        }
-        ChipInfo;
-
-        /* gcvHAL_ATTACH */
-        struct _gcsHAL_ATTACH
-        {
-            /* Handle of context buffer object. */
-            OUT gctUINT32               context;
-
-            /* Maximum state in the buffer. */
-            OUT gctUINT64               maxState;
-
-            /* Number of states in the buffer. */
-            OUT gctUINT32               numStates;
-
-            /* Map context buffer to user or not. */
-            IN gctBOOL                  map;
-
-            /* Physical of context buffer. */
-            OUT gctUINT32               physicals[2];
-
-            /* Physical of context buffer. */
-            OUT gctUINT64               logicals[2];
-
-            /* Bytes of context buffer. */
-            OUT gctUINT32               bytes;
-        }
-        Attach;
-
-        /* gcvHAL_DETACH */
-        struct _gcsHAL_DETACH
-        {
-            /* Context buffer object gckCONTEXT. Just a name. */
-            IN gctUINT32                context;
-        }
-        Detach;
-
-        /* gcvHAL_GET_FRAME_INFO. */
-        struct _gcsHAL_GET_FRAME_INFO
-        {
-            /* gcsHAL_FRAME_INFO* */
-            OUT gctUINT64     frameInfo;
-        }
-        GetFrameInfo;
-
-        /* gcvHAL_SET_TIME_OUT. */
-        struct _gcsHAL_SET_TIMEOUT
-        {
-            gctUINT32                   timeOut;
-        }
-        SetTimeOut;
+/* gcvHAL_SET_POWER_MANAGEMENT_STATE */
+typedef struct _gcsHAL_SET_POWER_MANAGEMENT
+{
+    /* Data read. */
+    IN gceCHIPPOWERSTATE        state;
+}
+gcsHAL_SET_POWER_MANAGEMENT;
+
+/* gcvHAL_QUERY_POWER_MANAGEMENT_STATE */
+typedef struct _gcsHAL_QUERY_POWER_MANAGEMENT
+{
+    /* Data read. */
+    OUT gceCHIPPOWERSTATE       state;
 
-#if gcdENABLE_VG
-        /* gcvHAL_COMMIT */
-        struct _gcsHAL_VGCOMMIT
-        {
-            /* Context buffer. gcsVGCONTEXT_PTR */
-            IN gctUINT64                context;
-
-            /* Command queue. gcsVGCMDQUEUE_PTR */
-            IN gctUINT64                queue;
-
-            /* Number of entries in the queue. */
-            IN gctUINT                  entryCount;
-
-            /* Task table. gcsTASK_MASTER_TABLE_PTR */
-            IN gctUINT64                taskTable;
-        }
-        VGCommit;
-
-        /* gcvHAL_QUERY_COMMAND_BUFFER */
-        struct _gcsHAL_QUERY_COMMAND_BUFFER
-        {
-            /* Command buffer attributes. */
-            OUT gcsCOMMAND_BUFFER_INFO    information;
-        }
-        QueryCommandBuffer;
+    /* Idle query. */
+    OUT gctBOOL                 isIdle;
+}
+gcsHAL_QUERY_POWER_MANAGEMENT;
+
+/* gcvHAL_CONFIG_POWER_MANAGEMENT. */
+typedef struct _gcsHAL_CONFIG_POWER_MANAGEMENT
+{
+    IN gctBOOL                  enable;
+}
+gcsHAL_CONFIG_POWER_MANAGEMENT;
+
+typedef struct _gcsFLAT_MAPPING_RANGE
+{
+    gctUINT64 start;
+    gctUINT64 end;
+    gctUINT32 size;
+    gceFLATMAP_FLAG flag;
+}
+gcsFLAT_MAPPING_RANGE;
+
+/* gcvHAL_GET_BASE_ADDRESS */
+typedef struct _gcsHAL_GET_BASE_ADDRESS
+{
+    /* Physical memory address of internal memory. */
+    OUT gctUINT32               baseAddress;
+
+    OUT gctUINT32               flatMappingRangeCount;
+
+    OUT gcsFLAT_MAPPING_RANGE   flatMappingRanges[gcdMAX_FLAT_MAPPING_COUNT];
+}
+gcsHAL_GET_BASE_ADDRESS;
+
+typedef struct _gcsHAL_SET_DEBUG_LEVEL_ZONE
+{
+    IN gctUINT32                level;
+    IN gctUINT32                zones;
+    IN gctBOOL                  enable;
+}
+gcsHAL_SET_DEBUG_LEVEL_ZONE;
+
+/* gcvHAL_DEBUG_DUMP. */
+typedef struct _gcsHAL_DEBUG_DUMP
+{
+    /* gceDUMP_BUFFER_TYPE      type. */
+    IN gctUINT32                type;
+
+    IN gctUINT64                ptr;
+    IN gctUINT32                address;
+    IN gctUINT32                size;
+}
+gcsHAL_DEBUG_DUMP;
+
+
+/* gcvHAL_TIMESTAMP */
+typedef struct _gcsHAL_TIMESTAMP
+{
+    /* Timer select. */
+    IN gctUINT32                timer;
+
+    /* Timer request type (0-stop, 1-start, 2-send delta). */
+    IN gctUINT32                request;
+
+    /* Result of delta time in microseconds. */
+    OUT gctINT32                timeDelta;
+}
+gcsHAL_TIMESTAMP;
+
+/* gcvHAL_DATABASE */
+typedef struct _gcsHAL_DATABASE
+{
+    /* Set to gcvTRUE if you want to query a particular process ID.
+    ** Set to gcvFALSE to query the last detached process. */
+    IN gctBOOL                  validProcessID;
+
+    /* Process ID to query. */
+    IN gctUINT32                processID;
+
+    /* Information. */
+    OUT gcuDATABASE_INFO        vidMem;
+    OUT gcuDATABASE_INFO        nonPaged;
+    OUT gcuDATABASE_INFO        gpuIdle;
+
+    /* Detail information about video memory. */
+    OUT gcuDATABASE_INFO        vidMemPool[3];
+}
+gcsHAL_DATABASE;
+
+/* gcvHAL_GET_FRAME_INFO. */
+typedef struct _gcsHAL_GET_FRAME_INFO
+{
+    /* gcsHAL_FRAME_INFO* */
+    OUT gctUINT64     frameInfo;
+}
+gcsHAL_GET_FRAME_INFO;
 
+#if gcdENABLE_VG
+/* gcvHAL_QUERY_COMMAND_BUFFER */
+typedef struct _gcsHAL_QUERY_COMMAND_BUFFER
+{
+    /* Command buffer attributes. */
+    OUT gcsCOMMAND_BUFFER_INFO  information;
+}
+gcsHAL_QUERY_COMMAND_BUFFER;
 #endif
 
-        struct _gcsHAL_SET_FSCALE_VALUE
-        {
-            IN gctUINT              value;
-        }
-        SetFscaleValue;
-
-        struct _gcsHAL_GET_FSCALE_VALUE
-        {
-            OUT gctUINT             value;
-            OUT gctUINT             minValue;
-            OUT gctUINT             maxValue;
-        }
-        GetFscaleValue;
-
-        /* gcvHAL_EXPORT_VIDEO_MEMORY */
-        struct _gcsHAL_EXPORT_VIDEO_MEMORY
-        {
-            /* Allocated video memory. */
-            IN gctUINT32                node;
-
-            /* Export flags */
-            IN gctUINT32                flags;
-
-            /* Exported dma_buf fd */
-            OUT gctINT32                fd;
-        }
-        ExportVideoMemory;
-
-        struct _gcsHAL_NAME_VIDEO_MEMORY
-        {
-            IN gctUINT32            handle;
-            OUT gctUINT32           name;
-        }
-        NameVideoMemory;
-
-        struct _gcsHAL_IMPORT_VIDEO_MEMORY
-        {
-            IN gctUINT32            name;
-            OUT gctUINT32           handle;
-        }
-        ImportVideoMemory;
-
-        struct _gcsHAL_QUERY_RESET_TIME_STAMP
-        {
-            OUT gctUINT64           timeStamp;
-            OUT gctUINT64           contextID;
-        }
-        QueryResetTimeStamp;
-
-        struct _gcsHAL_CREATE_NATIVE_FENCE
-        {
-            /* Signal id. */
-            IN gctUINT64                signal;
-
-            /* Native fence file descriptor. */
-            OUT gctINT                  fenceFD;
-
-        }
-        CreateNativeFence;
-
-        struct _gcsHAL_WAIT_NATIVE_FENCE
-        {
-            /* Native fence file descriptor. */
-            IN gctINT                   fenceFD;
-
-            /* Wait timeout. */
-            IN gctUINT32                timeout;
-        }
-        WaitNativeFence;
-
-        struct _gcsHAL_DESTROY_MMU
-        {
-            /* Mmu object. */
-            IN gctUINT64                mmu;
-        }
-        DestroyMmu;
-
-        struct _gcsHAL_SHBUF
-        {
-            gceSHBUF_COMMAND_CODES      command;
-
-            /* Shared buffer. */
-            IN OUT gctUINT64            id;
-
-            /* User data to be shared. */
-            IN gctUINT64                data;
-
-            /* Data size. */
-            IN OUT gctUINT32            bytes;
-        }
-        ShBuf;
-
-        struct _gcsHAL_GET_GRAPHIC_BUFFER_FD
-        {
-            /* Max 3 video nodes, node handle here. */
-            IN gctUINT32                node[3];
-
-            /* A shBuf. */
-            IN gctUINT64                shBuf;
-
-            /* A signal. */
-            IN gctUINT64                signal;
-
-            OUT gctINT32                fd;
-        }
-        GetGraphicBufferFd;
-
-
-        struct _gcsHAL_VIDEO_MEMORY_METADATA
-        {
-            /* Allocated video memory. */
-            IN gctUINT32            node;
-
-            IN gctUINT32            readback;
-
-            INOUT gctINT32          ts_fd;
-            INOUT gctUINT32         fc_enabled;
-            INOUT gctUINT32         fc_value;
-            INOUT gctUINT32         fc_value_upper;
-
-            INOUT gctUINT32         compressed;
-            INOUT gctUINT32         compress_format;
-        }
-        SetVidMemMetadata;
-
-        struct _gcsHAL_GET_VIDEO_MEMORY_FD
-        {
-            IN gctUINT32            handle;
-            OUT gctINT              fd;
-        }
-        GetVideoMemoryFd;
-
-        struct _gcsHAL_CONFIG_POWER_MANAGEMENT
-        {
-            IN gctBOOL                  enable;
-        }
-        ConfigPowerManagement;
-
-        struct _gcsHAL_WRAP_USER_MEMORY
-        {
-            /* Description of user memory. */
-            IN gcsUSER_MEMORY_DESC      desc;
-
-            /* Output video mmory node. */
-            OUT gctUINT32               node;
-
-            /* size of the node in bytes */
-            OUT gctUINT64               bytes;
-        }
-        WrapUserMemory;
-
-        struct _gcsHAL_WAIT_FENCE
-        {
-            IN gctUINT32                handle;
-            IN gctUINT32                timeOut;
-        }
-        WaitFence;
-
-        struct _gcsHAL_COMMIT_DONE
-        {
-            IN gctUINT64                context;
-        }
-        CommitDone;
+typedef struct _gcsHAL_SET_FSCALE_VALUE
+{
+    IN gctUINT32                value;
+}
+gcsHAL_SET_FSCALE_VALUE;
+
+typedef struct _gcsHAL_GET_FSCALE_VALUE
+{
+    OUT gctUINT32               value;
+    OUT gctUINT32               minValue;
+    OUT gctUINT32               maxValue;
+}
+gcsHAL_GET_FSCALE_VALUE;
+
+/* gcvHAL_QUERY_RESET_TIME_STAMP. */
+typedef struct _gcsHAL_QUERY_RESET_TIME_STAMP
+{
+    OUT gctUINT64               timeStamp;
+    OUT gctUINT64               contextID;
+}
+gcsHAL_QUERY_RESET_TIME_STAMP;
+
+/* gcvHAL_CREATE_NATIVE_FENCE. */
+typedef struct _gcsHAL_CREATE_NATIVE_FENCE
+{
+    /* Signal id. */
+    IN gctUINT64                signal;
+
+    /* Native fence file descriptor. */
+    OUT gctINT32                fenceFD;
+
+}
+gcsHAL_CREATE_NATIVE_FENCE;
+
+/* gcvHAL_WAIT_NATIVE_FENCE. */
+typedef struct _gcsHAL_WAIT_NATIVE_FENCE
+{
+    /* Native fence file descriptor. */
+    IN gctINT32                 fenceFD;
+
+    /* Wait timeout. */
+    IN gctUINT32                timeout;
+}
+gcsHAL_WAIT_NATIVE_FENCE;
+
+/* gcvHAL_SHBUF. */
+typedef struct _gcsHAL_SHBUF
+{
+    gceSHBUF_COMMAND_CODES      command;
+
+    /* Shared buffer. */
+    IN OUT gctUINT64            id;
+
+    /* User data to be shared. */
+    IN gctUINT64                data;
+
+    /* Data size. */
+    IN OUT gctUINT32            bytes;
+}
+gcsHAL_SHBUF;
+
+/* gcvHAL_GET_GRAPHIC_BUFFER_FD. */
+/*
+ * Fd representation of android graphic buffer contents.
+ * Currently, it is only to reference video nodes, signal, etc to avoid being
+ * destroyed when trasfering across processes.
+ */
+typedef struct _gcsHAL_GET_GRAPHIC_BUFFER_FD
+{
+    /* Max 3 video nodes, node handle here. */
+    IN gctUINT32                node[3];
+
+    /* A shBuf. */
+    IN gctUINT64                shBuf;
+
+    /* A signal. */
+    IN gctUINT64                signal;
+
+    OUT gctINT32                fd;
+}
+gcsHAL_GET_GRAPHIC_BUFFER_FD;
+
+typedef struct _gcsHAL_VIDEO_MEMORY_METADATA
+{
+    /* Allocated video memory. */
+    IN gctUINT32            node;
+
+    IN gctUINT32            readback;
+
+    INOUT gctINT32          ts_fd;
+    INOUT gctUINT32         fc_enabled;
+    INOUT gctUINT32         fc_value;
+    INOUT gctUINT32         fc_value_upper;
+
+    INOUT gctUINT32         compressed;
+    INOUT gctUINT32         compress_format;
+}
+gcsHAL_VIDEO_MEMORY_METADATA;
+
+/* gcvHAL_GET_VIDEO_MEMORY_FD. */
+typedef struct _gcsHAL_GET_VIDEO_MEMORY_FD
+{
+    IN gctUINT32                handle;
+    OUT gctINT32                fd;
+}
+gcsHAL_GET_VIDEO_MEMORY_FD;
+
+/* gcvHAL_DESTROY_MMU. */
+typedef struct _gcsHAL_DESTROY_MMU
+{
+    /* Mmu object. */
+    IN gctUINT64                mmu;
+}
+gcsHAL_DESTROY_MMU;
+
+/* gcvHAL_WAIT_FENCE. */
+typedef struct _gcsHAL_WAIT_FENCE
+{
+    IN gctUINT32                handle;
+    IN gctUINT32                timeOut;
+}
+gcsHAL_WAIT_FENCE;
+
+/* gcvHAL_DEVICE_MUTEX: */
+typedef struct _gcsHAL_DEVICE_MUTEX
+{
+    /* Lock or Release device mutex. */
+    gctBOOL                     isMutexLocked;
+}
+gcsHAL_DEVICE_MUTEX;
+
 
 #if gcdDEC_ENABLE_AHB
-        struct _gcsHAL_DEC300_READ
-        {
-            gctUINT32      enable;
-            gctUINT32      readId;
-            gctUINT32      format;
-            gctUINT32      strides[3];
-            gctUINT32      is3D;
-            gctUINT32      isMSAA;
-            gctUINT32      clearValue;
-            gctUINT32      isTPC;
-            gctUINT32      isTPCCompressed;
-            gctUINT32      surfAddrs[3];
-            gctUINT32      tileAddrs[3];
-        }
-        DEC300Read;
-
-        struct _gcsHAL_DEC300_WRITE
-        {
-            gctUINT32       enable;
-            gctUINT32       readId;
-            gctUINT32       writeId;
-            gctUINT32       format;
-            gctUINT32       surfAddr;
-            gctUINT32       tileAddr;
-        }
-        DEC300Write;
-
-        struct _gcsHAL_DEC300_FLUSH
-        {
-            IN gctUINT8     useless;
-        }
-        DEC300Flush;
-
-        struct _gcsHAL_DEC300_FLUSH_WAIT
-        {
-            IN gctUINT32    done;
-        }
-        DEC300FlushWait;
+/* gcvHAL_DEC300_READ. */
+typedef struct _gcsHAL_DEC300_READ
+{
+    gctUINT32                   enable;
+    gctUINT32                   readId;
+    gctUINT32                   format;
+    gctUINT32                   strides[3];
+    gctUINT32                   is3D;
+    gctUINT32                   isMSAA;
+    gctUINT32                   clearValue;
+    gctUINT32                   isTPC;
+    gctUINT32                   isTPCCompressed;
+    gctUINT32                   surfAddrs[3];
+    gctUINT32                   tileAddrs[3];
+}
+DEC300Read;
+
+/* gcvHAL_DEC300_WRITE. */
+typedef struct _gcsHAL_DEC300_WRITE
+{
+    gctUINT32                   enable;
+    gctUINT32                   readId;
+    gctUINT32                   writeId;
+    gctUINT32                   format;
+    gctUINT32                   surfAddr;
+    gctUINT32                   tileAddr;
+}
+DEC300Write;
+
+/* gcvHAL_DEC300_FLUSH. */
+typedef struct _gcsHAL_DEC300_FLUSH
+{
+    IN gctUINT8                 useless;
+}
+DEC300Flush;
+
+/* gcvHAL_DEC300_FLUSH_WAIT. */
+typedef struct _gcsHAL_DEC300_FLUSH_WAIT
+{
+    IN gctUINT32                done;
+}
+DEC300FlushWait;
 #endif
-        /* gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY: */
-        struct _gcsHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY
-        {
-            /* Allocated video memory. */
-            IN gctUINT32                node;
 
-            /* Type of surface. */
-            IN gceSURF_TYPE             type;
-        }
-        BottomHalfUnlockVideoMemory;
+
+typedef struct _gcsHAL_INTERFACE
+{
+    /* Command code. */
+    gceHAL_COMMAND_CODES        command;
+
+    /* Hardware type. */
+    gceHARDWARE_TYPE            hardwareType;
+
+    /* Core index for current hardware type. */
+    gctUINT32                   coreIndex;
+
+    /* Status value. */
+    gceSTATUS                   status;
+
+    /* Engine */
+    gceENGINE                   engine;
+
+    /* Ignore information from TSL when doing IO control */
+    gctBOOL                     ignoreTLS;
+
+    /* The mutext already acquired */
+    IN gctBOOL                  commitMutex;
+
+    /* Union of command structures. */
+    union _u
+    {
+        gcsHAL_CHIP_INFO                    ChipInfo;
+        gcsHAL_VERSION                      Version;
+        gcsHAL_SET_TIMEOUT                  SetTimeOut;
+
+        gcsHAL_QUERY_VIDEO_MEMORY           QueryVideoMemory;
+        gcsHAL_QUERY_CHIP_IDENTITY          QueryChipIdentity;
+        gcsHAL_QUERY_CHIP_OPTIONS           QueryChipOptions;
+        gcsHAL_QUERY_CHIP_FREQUENCY         QueryChipFrequency;
+
+        gcsHAL_ALLOCATE_NON_PAGED_MEMORY    AllocateNonPagedMemory;
+        gcsHAL_FREE_NON_PAGED_MEMORY        FreeNonPagedMemory;
+
+        gcsHAL_ALLOCATE_LINEAR_VIDEO_MEMORY AllocateLinearVideoMemory;
+        gcsHAL_WRAP_USER_MEMORY             WrapUserMemory;
+        gcsHAL_RELEASE_VIDEO_MEMORY         ReleaseVideoMemory;
+
+        gcsHAL_LOCK_VIDEO_MEMORY            LockVideoMemory;
+        gcsHAL_UNLOCK_VIDEO_MEMORY          UnlockVideoMemory;
+        gcsHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY BottomHalfUnlockVideoMemory;
+
+        gcsHAL_EXPORT_VIDEO_MEMORY          ExportVideoMemory;
+        gcsHAL_NAME_VIDEO_MEMORY            NameVideoMemory;
+        gcsHAL_IMPORT_VIDEO_MEMORY          ImportVideoMemory;
+
+        gcsHAL_MAP_MEMORY                   MapMemory;
+        gcsHAL_UNMAP_MEMORY                 UnmapMemory;
+
+        gcsHAL_CACHE                        Cache;
+
+        gcsHAL_ATTACH                       Attach;
+        gcsHAL_DETACH                       Detach;
+
+        gcsHAL_EVENT_COMMIT                 Event;
+        gcsHAL_COMMIT                       Commit;
+#if gcdENABLE_VG
+        gcsHAL_VGCOMMIT                     VGCommit;
+#endif
+        gcsHAL_COMMIT_DONE                  CommitDone;
+
+        gcsHAL_USER_SIGNAL                  UserSignal;
+        gcsHAL_SIGNAL                       Signal;
+
+        gcsHAL_WRITE_DATA                   WriteData;
+        gcsHAL_READ_REGISTER                ReadRegisterData;
+        gcsHAL_WRITE_REGISTER               WriteRegisterData;
+        gcsHAL_READ_REGISTER_EX             ReadRegisterDataEx;
+        gcsHAL_WRITE_REGISTER_EX            WriteRegisterDataEx;
+
+#if VIVANTE_PROFILER
+        gcsHAL_GET_PROFILE_SETTING          GetProfileSetting;
+        gcsHAL_SET_PROFILE_SETTING          SetProfileSetting;
+        gcsHAL_READ_PROFILER_REGISTER_SETTING SetProfilerRegisterClear;
+        gcsHAL_READ_ALL_PROFILE_REGISTERS_PART1 RegisterProfileData_part1;
+        gcsHAL_READ_ALL_PROFILE_REGISTERS_PART2 RegisterProfileData_part2;
+        gcsHAL_PROFILE_REGISTERS_2D         RegisterProfileData2D;
+#endif
+
+        gcsHAL_SET_POWER_MANAGEMENT         SetPowerManagement;
+        gcsHAL_QUERY_POWER_MANAGEMENT       QueryPowerManagement;
+        gcsHAL_CONFIG_POWER_MANAGEMENT      ConfigPowerManagement;
+
+        gcsHAL_GET_BASE_ADDRESS             GetBaseAddress;
+
+        gcsHAL_SET_DEBUG_LEVEL_ZONE         DebugLevelZone;
+        gcsHAL_DEBUG_DUMP                   DebugDump;
+
+        gcsHAL_TIMESTAMP                    TimeStamp;
+        gcsHAL_DATABASE                     Database;
+
+        gcsHAL_GET_FRAME_INFO               GetFrameInfo;
+
+#if gcdENABLE_VG
+        gcsHAL_QUERY_COMMAND_BUFFER         QueryCommandBuffer;
+#endif
+
+        /* gcsHAL_DUMP_GPU_STATE */
+        /* gcsHAL_DUMP_EVENT */
+
+        gcsHAL_SET_FSCALE_VALUE             SetFscaleValue;
+        gcsHAL_GET_FSCALE_VALUE             GetFscaleValue;
+
+        gcsHAL_QUERY_RESET_TIME_STAMP       QueryResetTimeStamp;
+
+        gcsHAL_CREATE_NATIVE_FENCE          CreateNativeFence;
+        gcsHAL_WAIT_NATIVE_FENCE            WaitNativeFence;
+        gcsHAL_SHBUF                        ShBuf;
+        gcsHAL_GET_GRAPHIC_BUFFER_FD        GetGraphicBufferFd;
+        gcsHAL_VIDEO_MEMORY_METADATA        SetVidMemMetadata;
+        gcsHAL_GET_VIDEO_MEMORY_FD          GetVideoMemoryFd;
+
+        gcsHAL_DESTROY_MMU                  DestroyMmu;
+
+        gcsHAL_WAIT_FENCE                   WaitFence;
 
         /* gcvHAL_DEVICE_MUTEX: */
-        struct _gcsHAL_DEVICE_MUTEX
-        {
-            /* Lock or Release device mutex. */
-            gctBOOL                     isMutexLocked;
-        }
-        DeviceMutex;
-
-        gcsHAL_QUERY_CHIP_OPTIONS QueryChipOptions;
+        gcsHAL_DEVICE_MUTEX                 DeviceMutex;
+
+
+#if gcdDEC_ENABLE_AHB
+        gcsHAL_DEC300_READ                  DEC300Read;
+        gcsHAL_DEC300_WRITE                 DEC300Write;
+        gcsHAL_DEC300_FLUSH                 DEC300Flush;
+        gcsHAL_DEC300_FLUSH_WAIT            DEC300FlushWait;
+#endif
     }
     u;
 }
index 4fd5d01..68c9786 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -135,7 +135,6 @@ typedef enum _gceTASK
     gcvTASK_UNLOCK_VIDEO_MEMORY,
     gcvTASK_FREE_VIDEO_MEMORY,
     gcvTASK_FREE_CONTIGUOUS_MEMORY,
-    gcvTASK_UNMAP_USER_MEMORY
 }
 gceTASK;
 
@@ -272,27 +271,6 @@ typedef struct _gcsTASK_FREE_CONTIGUOUS_MEMORY
 }
 gcsTASK_FREE_CONTIGUOUS_MEMORY;
 
-typedef struct _gcsTASK_UNMAP_USER_MEMORY * gcsTASK_UNMAP_USER_MEMORY_PTR;
-typedef struct _gcsTASK_UNMAP_USER_MEMORY
-{
-    /* Task ID (gcvTASK_UNMAP_USER_MEMORY). */
-    IN gceTASK                  id;
-
-    /* Base address of user memory to unmap. */
-    IN gctPOINTER               memory;
-
-    /* Size of user memory in bytes to unmap. */
-    IN gctSIZE_T                size;
-
-    /* Info record returned by gcvHAL_MAP_USER_MEMORY. */
-    IN gctPOINTER               info;
-
-    /* Physical address of mapped memory as returned by
-       gcvHAL_MAP_USER_MEMORY. */
-    IN gctUINT32                address;
-}
-gcsTASK_UNMAP_USER_MEMORY;
-
 #ifdef __cplusplus
 }
 #endif
index cc8eab7..1355bcd 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -69,7 +69,6 @@ extern "C" {
 #define DRM_VIV_GEM_CACHED          (1u << 1)
 #define DRM_VIV_GEM_SECURE          (1u << 2)
 #define DRM_VIV_GEM_CMA_LIMIT       (1u << 3)
-#define DRM_VIV_GEM_VIRTUAL_POOL    (1u << 4)
 
 struct drm_viv_gem_create {
     __u64 size;
index b8c9ffa..b8b8c1b 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 #ifndef __gc_hal_dump_h_
 #define __gc_hal_dump_h_
 
-#ifdef __cplusplus
-extern "C" {
+/*
+    gcdDUMP_KEY
+
+        Set this to a string that appears in 'cat /proc/<pid>/cmdline'. E.g. 'camera'.
+        HAL will create dumps for the processes matching this key.
+*/
+#ifndef gcdDUMP_KEY
+#   define gcdDUMP_KEY                          "process"
 #endif
 
 /*
-**    FILE LAYOUT:
-**
-**        gcsDUMP_FILE structure
-**
-**        gcsDUMP_DATA frame
-**            gcsDUMP_DATA or gcDUMP_DATA_SIZE records rendingring the frame
-**            gctUINT8 data[length]
+    gcdDUMP_PATH
+
+        The dump file location. Some processes cannot write to the sdcard.
+        Try apps' data dir, e.g. /data/data/com.android.launcher
 */
+#ifndef gcdDUMP_PATH
+#if defined(ANDROID)
+#   define gcdDUMP_PATH                         "/mnt/sdcard/"
+#else
+#   define gcdDUMP_PATH                         "./"
+#endif
+#endif
+
+/*
+    gcdDUMP_FILE_IN_KERNEL
 
-#define gcvDUMP_FILE_SIGNATURE        gcmCC('g','c','D','B')
-
-typedef struct _gcsDUMP_FILE
-{
-    gctUINT32           signature;    /* File signature */
-    gctSIZE_T             length;        /* Length of file */
-    gctUINT32             frames;        /* Number of frames in file */
-}
-gcsDUMP_FILE;
-
-typedef enum _gceDUMP_TAG
-{
-    gcvTAG_SURFACE                  = gcmCC('s','u','r','f'),
-    gcvTAG_FRAME                    = gcmCC('f','r','m',' '),
-    gcvTAG_COMMAND                  = gcmCC('c','m','d',' '),
-    gcvTAG_INDEX                    = gcmCC('i','n','d','x'),
-    gcvTAG_STREAM                   = gcmCC('s','t','r','m'),
-    gcvTAG_TEXTURE                  = gcmCC('t','e','x','t'),
-    gcvTAG_RENDER_TARGET            = gcmCC('r','n','d','r'),
-    gcvTAG_DEPTH                    = gcmCC('z','b','u','f'),
-    gcvTAG_RESOLVE                  = gcmCC('r','s','l','v'),
-    gcvTAG_DELETE                   = gcmCC('d','e','l',' '),
-    gcvTAG_BUFOBJ                   = gcmCC('b','u','f','o'),
-}
-gceDUMP_TAG;
-
-typedef struct _gcsDUMP_SURFACE
-{
-    gceDUMP_TAG            type;        /* Type of record. */
-    gctUINT32             address;    /* Address of the surface. */
-    gctINT16              width;        /* Width of surface. */
-    gctINT16               height;        /* Height of surface. */
-    gceSURF_FORMAT        format;        /* Surface pixel format. */
-    gctSIZE_T            length;        /* Number of bytes inside the surface. */
-}
-gcsDUMP_SURFACE;
-
-typedef struct _gcsDUMP_DATA
-{
-    gceDUMP_TAG             type;        /* Type of record. */
-    gctSIZE_T             length;        /* Number of bytes of data. */
-    gctUINT32             address;    /* Address for the data. */
-}
-gcsDUMP_DATA;
-
-#ifdef __cplusplus
-}
+        Default dump file for gcdDUMP_IN_KERNEL.
+        The file will be writen globally in kernel side.
+        Can be overwriten in runtime by debugfs:/gc/dump/dump_file
+
+        2 pseudo files:
+        [dmesg]:    means dump to kernel debug message.
+        [ignored]:  means dump ignored, nothing will be dumpped.
+ */
+#ifndef gcdDUMP_FILE_IN_KERNEL
+#  define gcdDUMP_FILE_IN_KERNEL                "[dmesg]"
+#endif
+
+/*
+    gcdDUMP_VERIFY_PER_DRAW
+
+        Sub feature of gcdDUMP.
+        When set to 1, verify RT and images(if used) for every single draw to ease simulation debug.
+        Only valid for ES3 driver for now.
+*/
+#ifndef gcdDUMP_VERIFY_PER_DRAW
+#   define gcdDUMP_VERIFY_PER_DRAW              0
+#endif
+
+/* Standalone dump features below. */
+
+/*
+    gcdDUMP_FRAMERATE
+        When set to a value other than zero, averaqe frame rate will be dumped.
+        The value set is the starting frame that the average will be calculated.
+        This is needed because sometimes first few frames are too slow to be included
+        in the average. Frame count starts from 1.
+*/
+#ifndef gcdDUMP_FRAMERATE
+#   define gcdDUMP_FRAMERATE                    0
+#endif
+
+
+/*
+    gcdDUMP_FRAME_TGA
+
+    When set to a value other than 0, a dump of the frame specified by the value,
+    will be done into frame.tga. Frame count starts from 1.
+ */
+#ifndef gcdDUMP_FRAME_TGA
+#   define gcdDUMP_FRAME_TGA                    0
+#endif
+
+/*
+    gcdDUMP_AHB_ACCESS
+
+        When set to 1, a dump of all AHB register access will be printed to kernel
+        message.
+*/
+#ifndef gcdDUMP_AHB_ACCESS
+#   define gcdDUMP_AHB_ACCESS                   0
 #endif
 
 #endif /* __gc_hal_dump_h_ */
index 7d2a6fa..5246100 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index c35cab5..22d2778 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 4c2f925..4e29628 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -326,8 +326,8 @@ typedef enum _gceSPLIT_DRAW_TYPE
     gcvSPLIT_DRAW_XFB,
     gcvSPLIT_DRAW_INDEX_FETCH,
     gcvSPLIT_DRAW_TCS,
-    gcvSPLIT_DRAW_WIDE_LINE,
     gcvSPLIT_DRAW_STIPPLE,
+    gcvSPLIT_DRAW_WIDE_LINE,
     gcvSPLIT_DRAW_LAST
 }
 gceSPLIT_DRAW_TYPE;
@@ -1645,10 +1645,11 @@ typedef struct _gcsTHREAD_WALKER_INFO
 
     gctUINT32   threadAllocation;
     gctBOOL     barrierUsed;
-
+    gctUINT32   memoryAccessFlag; /* same as gceMEMORY_ACCESS_FLAG */
     gctBOOL     indirect;
     gctUINT32   groupNumberUniformIdx;
     gctUINT32   baseAddress;
+    gctBOOL     bDual16;
 }
 gcsTHREAD_WALKER_INFO;
 
@@ -2032,6 +2033,7 @@ typedef struct _gcsTEXTURE
     gceTEXTURE_SRGBDECODE       sRGB;
 
     gcuVALUE                    borderColor[4];
+    gctBOOL                     descDirty;
 }
 gcsTEXTURE, * gcsTEXTURE_PTR;
 
@@ -2402,6 +2404,7 @@ typedef enum _gceVERTEX_FORMAT
     gcvVERTEX_FIXED,
     gcvVERTEX_HALF,
     gcvVERTEX_FLOAT,
+    gcvVERTEX_DOUBLE,
     gcvVERTEX_UNSIGNED_INT_10_10_10_2,
     gcvVERTEX_INT_10_10_10_2,
     gcvVERTEX_UNSIGNED_INT_2_10_10_10_REV,
@@ -2424,6 +2427,7 @@ typedef enum _gceATTRIB_SCHEME
     gcvATTRIB_SCHEME_UBYTE_TO_UVEC4,
     gcvATTRIB_SCHEME_USHORT_TO_UVEC4,
     gcvATTRIB_SCHEME_UINT_TO_UVEC4,
+    gcvATTRIB_SCHEME_DOUBLE_TO_FLOAT,
 } gceATTRIB_SCHEME;
 
 gceSTATUS
@@ -2956,8 +2960,9 @@ gcoBUFOBJ_ReAllocBufNode(
 
 /* Handle GPU cache operations */
 gceSTATUS
-gcoBUFOBJ_GPUCacheOperation(
-    gcoBUFOBJ BufObj
+gcoBUFOBJ_SetCPUWrite(
+    gcoBUFOBJ BufObj,
+    gctBOOL Value
     );
 
 /* Dump buffer. */
index 9bbbe05..6c4f1c4 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -781,6 +781,13 @@ gcoVG_Destroy(
 #endif
     );
 
+void
+gcoVG_SetTesselationSize(
+    IN gcoVG Vg,
+    IN gctUINT Width,
+    IN gctUINT Height
+    );
+
 gceSTATUS
 gcoVG_SetTarget(
     IN gcoVG Vg,
@@ -1157,11 +1164,30 @@ gcoVG_DrawSurfaceToImage(
 #endif
     IN gcoSURF Image,
     IN const gcsVG_RECT_PTR SrcRectangle,
-    IN const gcsVG_RECT_PTR DstRectangle,
-    IN const gctFLOAT Matrix[9],
+    IN const gctFLOAT  DstBounds[4],
+    IN const gctFLOAT DstPoints[8],
+    IN const gctFLOAT ImgMatrix[9],
+    IN const gctFLOAT RectMatrix[9],
     IN gceIMAGE_FILTER Filter,
     IN gctBOOL Mask,
     IN gctBOOL FirstTime
+#if gcdMOVG
+,
+    IN gctINT   TSWidth,
+    IN gctINT   TSHeight
+#endif
+    );
+
+gceSTATUS
+gcoVG_DrawSurfaceToImageMasked(
+    IN gcoVG Vg,
+    IN gcoSURF Image,
+    IN gcsVG_RECT_PTR SrcRect,
+    IN gctINT  X,
+    IN gctINT  Y,
+    IN gctINT  Width,
+    IN gctINT  Height,
+    IN const gctFLOAT Matrix[9]
     );
 
 gceSTATUS
@@ -1293,6 +1319,28 @@ gcoVG_SetColorIndexTable(
     IN gctINT32      Count
 );
 
+gceSTATUS
+gcoVG_SetYUV2RGBStdCust(
+    IN gcoVG            Vg,
+    IN gctBOOL          YUV2RGBStdCust
+    );
+
+gceSTATUS
+gcoVG_SetYUV2RGB(
+    IN gcoVG            Vg,
+    IN gctFLOAT         *coef,
+    IN gctFLOAT         *offset,
+    IN gctBOOL          *cfg
+);
+
+gceSTATUS
+gcoVG_SetRGB2YUVParameters(
+    IN gcoVG            Vg,
+    IN gctFLOAT         *coef,
+    IN gctFLOAT         *offset,
+    IN gctBOOL          *cfg
+);
+
 /* VG RS feature support: YUV format conversion. */
 gceSTATUS
 gcoVG_Resolve(
@@ -1309,7 +1357,8 @@ gcoVG_Resolve(
     IN gctINT       Src_standard,
     IN gctINT       Dst_uv,
     IN gctINT       Dst_standard,
-    IN gctINT       Dst_alpha
+    IN gctINT       Dst_alpha,
+    IN gctBOOL      Dst_standard_cust
 );
 #ifdef __cplusplus
 }
index b854dc6..91cc179 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -148,6 +148,7 @@ typedef enum _gceFEATURE
     gcvFEATURE_VG_FILTER,
     gcvFEATURE_VG21,
     gcvFEATURE_VG_DOUBLE_BUFFER,
+    gcvFEATURE_VG_RESOLUTION_8K,
     gcvFEATURE_MC20,
     gcvFEATURE_SUPER_TILED,
     gcvFEATURE_FAST_CLEAR_FLUSH,
@@ -190,7 +191,7 @@ typedef enum _gceFEATURE
     gcvFEATURE_SUPERTILED_TEXTURE,
     gcvFEATURE_2D_NO_COLORBRUSH_INDEX8,
     gcvFEATURE_RS_YUV_TARGET,
-    gcvFEATURE_2D_FC_SOURCE,
+    gcvFEATURE_2D_FC_SOURCE, /* For tilestatus compression feature*/
     gcvFEATURE_2D_CC_NOAA_SOURCE,
     gcvFEATURE_PE_DITHER_FIX,
     gcvFEATURE_2D_YUV_SEPARATE_STRIDE,
@@ -344,7 +345,6 @@ typedef enum _gceFEATURE
     gcvFEATURE_SEPARATE_RT_CTRL,
     gcvFEATURE_RENDER_ARRAY,
     gcvFEATURE_BLT_ENGINE,
-    gcvFEATURE_SMALLDRAW_BATCH,
     gcvFEATURE_TEXTURE_BUFFER,
     gcvFEATURE_GS_SUPPORT_EMIT,
     gcvFEATURE_SAMPLER_BASE_OFFSET,
@@ -495,6 +495,8 @@ typedef enum _gceFEATURE
     gcvFEATURE_RA_CG_FIX,
     gcvFEATURE_EVIS_VX2,
     gcvFEATURE_SH_HALF_DEPENDENCY_FIX,
+    gcvFEATURE_FE_BASEINSTANCE,
+    gcvFEATURE_FE_COMPUREINDIRECT_SKIP_UNIFORM,
     gcvFEATURE_SH_CLOCK_GATE_FIX,
     gcvFEATURE_GPIPE_CLOCK_GATE_FIX,
     gcvFEATURE_TP_ENGINE,
@@ -505,19 +507,108 @@ typedef enum _gceFEATURE
     gcvFEATURE_PE_VMSAA_COVERAGE_CACHE_FIX,
     gcvFEATURE_SECURITY_AHB,
     gcvFEATURE_TX_LERP_LESS_BIT,
+    gcvFEATURE_SMALL_BATCH,
+    gcvFEATURE_SH_IDIV0_SWZL_EHS,
+    gcvFEATURE_SH_CMPLX,
     gcvFEATURE_VIP_V7,
+    gcvFEATURE_SH_GM_ENDIAN,
+    gcvFEATURE_SH_GM_USC_UNALLOC,
+    gcvFEATURE_SH_END_OF_BB,
     gcvFEATURE_ASYNC_BLIT,
     gcvFEATURE_ASYNC_FE_FENCE_FIX,
     gcvFEATURE_PSCS_THROTTLE,
+    gcvFEATURE_SEPARATE_LS,
+    gcvFEATURE_PA_VARYING_COMPONENT_TOGGLE_FIX,
+    gcvFEATURE_TX_MULTISAMPLER_FC_FIX,
     gcvFEATURE_WIDELINE_TRIANGLE_EMU,
     gcvFEATURE_FENCE,
+    gcvFEATURE_MCFE,
+    gcvFEATURE_NN_INTERLEAVE8,
+    gcvFEATURE_TP_REORDER,
+    gcvFEATURE_TP_RTNE,
+    gcvFEATURE_TP_LRN,
+    gcvFEATURE_TP_ROI_POOLING,
+    gcvFEATURE_TP_MAX_POOLING_STRIDE1,
+    gcvFEATURE_NN_BRICK_MODE,
+    gcvFEATURE_NN_BORDER_MODE,
+    gcvFEATURE_NN_FP16_ALU,
+    gcvFEATURE_NN_INT16_ALU,
+    gcvFEATURE_NN_ZDP3,
+    gcvFEATURE_NN_ZDP6,
     gcvFEATURE_PE_DEPTH_ONLY_OQFIX,
-    gcvFEATURE_VG_RESOLUTION_8K,
+    gcvFEATURE_TX_SNORM_SUPPORT,
+    gcvFEATURE_HWMANAGED_LS,
+    gcvFEATURE_SH_SCATTER_GATHER,
+    gcvFEATURE_NN_POWER_ISOLATION,
+    gcvFEATURE_SWTILING_PHASE1,
+    gcvFEATURE_SWTILING_PHASE2,
+    gcvFEATURE_SWTILING_PHASE3,
+    gcvFEATURE_TF_QUANTIZATION,
+    gcvFEATURE_NN_XYDP9,
+    gcvFEATURE_TP_SIMPLE_INT16,
+    gcvFEATURE_TP_REAL_INT16,
+    gcvFEATURE_NN_FIRST_PIXEL_POOLING,
+    gcvFEATURE_NN_STRIDE_SUPPORT,
+    gcvFEATURE_NN_XYDP6,
+    gcvFEATURE_NN_XYDP0,
+    gcvFEATURE_TP_REORDER_FIX,
+    gcvFEATURE_NN_CONV1x1_PERF_FIX,
+    gcvFEATURE_NN_CACHELINE_MODE_PERF_FIX,
+    gcvFEATURE_NN_PER3DTILE_BUBBLE_FIX,
+    gcvFEATURE_SH_IO_CG_FIX,
+    gcvFEATURE_USC_STAY_LRU,
+    gcvFEATURE_NN_NONZERO_MIRROR_BORDER,
+    gcvFEATURE_NN_COEF_DECOMPRESS_PERF2X,
+    gcvFEATURE_4BIT_INPUT,
+    gcvFEATURE_COEF_COMPRESSION_ENHANCEMENT,
+    gcvFEATURE_NN_ZDP3_NO_COMPRESS_FIX,
+    gcvFEATURE_NN_ASYNC_COPY_PERF_FIX,
+    gcvFEATURE_OCB_COUNTER,
+    gcvFEATURE_NN_ZXDP3_KERNEL_READ_CONFLICT_FIX,
+
     gcvFEATURE_IMAGE_LS_NO_FULLMASK_FIX,
+    gcvFEATURE_BLT_YUV_OUTPUT,
     gcvFEATURE_PE_TILE_CACHE_FLUSH_FIX,
+    gcvFEATURE_SH_ROBUSTNESS_FIX,
     gcvFEATURE_USC_ATOMIC_FIX2,
+    gcvFEATURE_MULTIVIEW_RENDER,
+    gcvFEATURE_FE_DRAW_DIRECT,
+    gcvFEATURE_TX_VKBORDER_MODE,
+    gcvFEATURE_TX_UNNORMALIZED_COORD,
+    gcvFEATURE_VG_IMAGE_16K,
+    gcvFEATURE_MULTICORE_CONFIG,
     gcvFEATURE_PA_LINECLIP_FIX,
+    gcvFEATURE_NN_ENGINE,
+    gcvFEATURE_NN_ASYNC_COPY_MERGE_FIX,
+    gcvFEATURE_NN_CONVOUT_FIFO_DEPTH_FIX,
+    gcvFEATURE_NN_SMALLBATCH_PHASE1,
+    gcvFEATURE_TP_SMALLBATCH_PHASE1,
+    gcvFEATURE_VIP_SCALER,
+    gcvFEATURE_TX_8bit_UVFrac_ROUNDING_FIX,
+    gcvFEATURE_NN_REQ_SLOWARBITRATION_FIX,
+    gcvFEATUER_IMAGE_PARTIAL_CACHE,
+    gcvFEATURE_FULLCACHE_KERNELHEAD_FIX,
+    gcvFEATURE_NN_SINGLEPORT_ACCUMBUFFER,
+    gcvFEATURE_NN_SMALLBATCH,
+    gcvFEATURE_TP_SMALLBATCH,
+    gcvFEATURE_NN_ZDP_INIMAGE_SIZE_FIX,
+    gcvFEATURE_HI_REORDER_FIX,
+    gcvFEATURE_TP_COEF_COMPRESSION_ENHANCEMENT,
+    gcvFEATURE_NN_DEPTHWISE_SUPPORT,
+    gcvFEATURE_IMAGE_NOT_PACKED_IN_SRAM_FIX,
+    gcvFEATURE_IDLE_BEFORE_FLUSH_COMPLETE_FIX,
+    gcvFEATURE_NO_FLUSH_USC_FIX,
+    gcvFEATURE_COEF_DELTA_CORD_OVERFLOW_ZRL_8BIT_FIX,
+    gcvFEATURE_XY_OFFSET_LIMITATION_FIX,
+    gcvFEATURE_USC_INVALIDATE_CACHE_LINE_FIX,
+    gcvFEATURE_LOW_EFFICIENCY_OF_ID_WRITE_IMGBUF_FIX,
+    gcvFEATURE_KERNEL_PER_CORE_LESS_THAN_THIRD_COEF_BUFF_DEPTH_FIX,
+    gcvFEATURE_NN_PER_CHANNEL_POST_MULTIPLY,
+    gcvFEATURE_NN_NO_Z_LOCATION_OFFSET,
+    gcvFEATURE_NN_PRELU,
+    gcvFEATURE_VIP_DEC400,
     gcvFEATURE_MAX_POINTSIZE_CLAMP,
+    gcvFEATURE_2D_FAST_CLEAR, /* For tilestatus Fast Clear feature*/
 
     /* Insert features above this comment only. */
     gcvFEATURE_COUNT                /* Not a feature. */
@@ -533,19 +624,6 @@ typedef enum _gceDUMMY_DRAW_TYPE
 }
 gceDUMMY_DRAW_TYPE;
 
-/* Chip SWWA. */
-typedef enum _gceSWWA
-{
-    gcvSWWA_601 = 0,
-    gcvSWWA_706,
-    gcvSWWA_1163,
-    gcvSWWA_1165,
-    /* Insert SWWA above this comment only. */
-    gcvSWWA_COUNT                   /* Not a SWWA. */
-}
-gceSWWA;
-
-
 /* Option Set*/
 typedef enum _gceOPTION
 {
@@ -566,10 +644,22 @@ typedef enum _gceOPTION
     gcvOPTION_FBO_PREFER_MEM = 54,
     gcvOPTION_GPU_TEX_UPLOAD = 55,
     gcvOPTION_GPU_BUFOBJ_UPLOAD = 56,
-    gcvOPTION_OCL_ASYNC_BLT = 57,
-    gcvOPTION_OCL_IN_THREAD = 58,
-    gcvOPTION_COMPRESSION_DEC400 = 59,
-    gcvOPTION_NO_Y_INVERT = 60,
+
+    /* OCL option */
+    gcvOPTION_OCL_ASYNC_BLT = 200,
+    gcvOPTION_OCL_IN_THREAD,
+    gcvOPTION_COMPRESSION_DEC400,
+    gcvOPTION_OCL_VIR_SHADER,
+    gcvOPTION_OCL_USE_MULTI_DEVICES,
+
+#if gcdUSE_VX
+    /* OVX options that HAL could access */
+    gcvOPTION_OVX_ENABLE_NN_ZDP3 = 500,
+    gcvOPTION_OVX_ENABLE_NN_ZDP6,
+    gcvOPTION_OVX_ENABLE_NN_STRIDE,
+    gcvOPTION_OVX_USE_MULTI_DEVICES,
+#endif
+
     /* Insert option above this comment only */
     gcvOPTION_COUNT                     /* Not a OPTION*/
 }
@@ -607,15 +697,30 @@ gceFRAMEINFO_OP;
 /* Chip Power Status. */
 typedef enum _gceCHIPPOWERSTATE
 {
+    gcvPOWER_INVALID = -1,
+
+    /* Global/base states. */
     gcvPOWER_ON = 0,
-    gcvPOWER_OFF,
     gcvPOWER_IDLE,
     gcvPOWER_SUSPEND,
-    gcvPOWER_IDLE_BROADCAST,
-    gcvPOWER_SUSPEND_BROADCAST,
-    gcvPOWER_OFF_BROADCAST,
-    gcvPOWER_OFF_TIMEOUT,
-    gcvPOWER_ON_AUTO
+    gcvPOWER_OFF,
+
+    /* Power on but not global or broadcast. */
+    gcvPOWER_ON_AUTO,
+
+    /* Broadcast states. */
+    gcvPOWER_FLAG_BROADCAST    = 0x10,
+    gcvPOWER_IDLE_BROADCAST    = gcvPOWER_IDLE    | gcvPOWER_FLAG_BROADCAST,
+    gcvPOWER_SUSPEND_BROADCAST = gcvPOWER_SUSPEND | gcvPOWER_FLAG_BROADCAST,
+    gcvPOWER_OFF_BROADCAST     = gcvPOWER_OFF     | gcvPOWER_FLAG_BROADCAST,
+
+
+    /* Timeout states. */
+    gcvPOWER_FLAG_TIMEOUT      = 0x20,
+    gcvPOWER_IDLE_TIMEOUT      = gcvPOWER_IDLE    | gcvPOWER_FLAG_TIMEOUT,
+    gcvPOWER_SUSPEND_TIMEOUT   = gcvPOWER_SUSPEND | gcvPOWER_FLAG_TIMEOUT,
+    gcvPOWER_OFF_TIMEOUT       = gcvPOWER_OFF     | gcvPOWER_FLAG_TIMEOUT,
+
 }
 gceCHIPPOWERSTATE;
 
@@ -762,6 +867,8 @@ typedef enum _gceSURF_FLAG
     gcvSURF_FLAG_CONTENT_YINVERTED   = 0x4,
     /* surface has multiple nodes */
     gcvSURF_FLAG_MULTI_NODE          = 0x8,
+    /* surface no need do dither when resovle*/
+    gcvSURF_FLAG_DITHER_DISABLED     = 0x10,
 }
 gceSURF_FLAG;
 
@@ -891,6 +998,8 @@ typedef enum _gceSURF_FORMAT
     gcvSURF_AYUY2,
     gcvSURF_ANV12,
     gcvSURF_ANV16,
+    gcvSURF_AUYVY,
+    gcvSURF_YV16,
 #endif
 
     /* Depth formats. */
@@ -915,8 +1024,6 @@ typedef enum _gceSURF_FORMAT
     gcvSURF_A32,
     gcvSURF_A1,
 
-    gcvSURF_A8_1_A8R8G8B8,
-
     /* Luminance formats. */
     gcvSURF_L4                  = 800,
     gcvSURF_L8,
@@ -1191,6 +1298,8 @@ typedef enum _gceIMAGE_MEM_TYPE
     gcvIMAGE_MEM_DEFAULT,
     gcvIMAGE_MEM_HOST_PTR,
     gcvIMAGE_MEM_HOST_PTR_UNCACHED,
+    gcvIMAGE_MEM_HOST_PHY_PTR,
+    gcvIMAGE_MEM_HOST_PHY_PTR_UNCACHED,
 }
 gceIMAGE_MEM_TYPE;
 
@@ -2010,17 +2119,6 @@ typedef enum _gceHAL_ARG_VERSION
 gceHAL_ARG_VERSION;
 
 
-typedef enum _gceCMDBUF_TYPE
-{
-    /* Contiguous command buffer. */
-    gcvCMDBUF_CONTIGUOUS,
-    /* Virtual command buffer. */
-    gcvCMDBUF_VIRTUAL,
-    /* Command buffer allocated from reserved memory. */
-    gcvCMDBUF_RESERVED,
-}
-gceCMDBUF_SOURCE;
-
 typedef enum _gceCHIP_FLAG
 {
     gcvCHIP_FLAG_MSAA_COHERENCEY_ECO_FIX = 1 << 0,
@@ -2065,15 +2163,6 @@ typedef enum _gceCORE
 gceCORE;
 
 
-typedef enum _gceADDRESS_AREA
-{
-    gcvADDRESS_AREA_NORMAL,
-    gcvADDRESS_AREA_SECURE,
-
-    gcvADDRESS_AREA_COUNT
-}
-gceADDRESS_AREA;
-
 typedef enum _gceSECURE_MODE
 {
     /* For cores without gcvFEATURE_SECURITY. */
@@ -2109,23 +2198,106 @@ typedef enum _gceCOMPRESSION_OPTION
 }
 gceCOMPRESSION_OPTION;
 
+typedef enum _gceHW_FE_TYPE
+{
+    gcvHW_FE_WAIT_LINK,
+    gcvHW_FE_ASYNC,
+    gcvHW_FE_MULTI_CHANNEL,
+}
+gceHW_FE_TYPE;
+
+typedef enum _gceMCFE_CHANNEL_TYPE
+{
+    gcvMCFE_CHANNEL_NONE = 0,
+    gcvMCFE_CHANNEL_SYSTEM,
+    gcvMCFE_CHANNEL_SHADER,
+    gcvMCFE_CHANNEL_NN,
+    gcvMCFE_CHANNEL_TP,
+
+    gcvMCFE_CHANNEL_3DBLIT = 128,
+}
+gceMCFE_CHANNEL_TYPE;
+
+typedef enum _gceSRAM
+{
+    gcvSRAM_INTERNAL  = 0,
+    gcvSRAM_EXTERNAL0 = 1,
+    gcvSRAM_EXTERNAL1 = 2,
+    gcvSRAM_COUNT
+}
+gceSRAM;
+
+typedef enum _gceFLATMAP_FLAG
+{
+    gcvFLATMAP_DIRECT,
+    gcvFLATMAP_SHIFT,
+}
+gceFLATMAP_FLAG;
+
+typedef enum _gcePAGE_TYPE
+{
+    gcvPAGE_TYPE_1M,
+    gcvPAGE_TYPE_4K,
+}
+gcePAGE_TYPE;
+
+typedef enum _gceAREA_TYPE
+{
+    gcvAREA_TYPE_UNKNOWN = 0,
+    gcvAREA_TYPE_FLATMAP,
+    gcvAREA_TYPE_1M,
+    gcvAREA_TYPE_4K,
+}
+gceAREA_TYPE;
+
+/* Video memory alloation type. */
+typedef enum _gceVIDMEM_TYPE
+{
+    gcvVIDMEM_TYPE_GENERIC          = gcvSURF_TYPE_UNKNOWN,
+    gcvVIDMEM_TYPE_INDEX_BUFFER     = gcvSURF_INDEX,
+    gcvVIDMEM_TYPE_VERTEX_BUFFER    = gcvSURF_VERTEX,
+    gcvVIDMEM_TYPE_TEXTURE          = gcvSURF_TEXTURE,
+    gcvVIDMEM_TYPE_COLOR_BUFFER     = gcvSURF_RENDER_TARGET,
+    gcvVIDMEM_TYPE_DEPTH_BUFFER     = gcvSURF_DEPTH,
+    gcvVIDMEM_TYPE_BITMAP           = gcvSURF_BITMAP,
+    gcvVIDMEM_TYPE_TILE_STATUS      = gcvSURF_TILE_STATUS,
+    gcvVIDMEM_TYPE_IMAGE            = gcvSURF_IMAGE,
+    gcvVIDMEM_TYPE_MASK             = gcvSURF_MASK,
+    gcvVIDMEM_TYPE_SCISSOR          = gcvSURF_SCISSOR,
+    gcvVIDMEM_TYPE_HZ_BUFFER        = gcvSURF_HIERARCHICAL_DEPTH,
+    gcvVIDMEM_TYPE_ICACHE           = gcvSURF_ICACHE,
+    gcvVIDMEM_TYPE_TXDESC           = gcvSURF_TXDESC,
+    gcvVIDMEM_TYPE_FENCE            = gcvSURF_FENCE,
+    gcvVIDMEM_TYPE_TFBHEADER        = gcvSURF_TFBHEADER,
+    gcvVIDMEM_TYPE_COMMAND,
+    gcvVIDMEM_TYPE_COUNT
+}
+gceVIDMEM_TYPE;
+
 /* No special needs. */
 #define gcvALLOC_FLAG_NONE                  0x00000000
 
 /* Physical contiguous. */
 #define gcvALLOC_FLAG_CONTIGUOUS            0x00000001
-/* Can be remapped as cacheable. */
-#define gcvALLOC_FLAG_CACHEABLE             0x00000002
-/* Secure buffer. */
-#define gcvALLOC_FLAG_SECURITY              0x00000004
 /* Physical non contiguous. */
-#define gcvALLOC_FLAG_NON_CONTIGUOUS        0x00000008
-/* Can be exported as dmabuf-fd */
-#define gcvALLOC_FLAG_DMABUF_EXPORTABLE     0x00000010
+#define gcvALLOC_FLAG_NON_CONTIGUOUS        0x00000002
 
+/* Should not swap out. */
+#define gcvALLOC_FLAG_NON_PAGED             0x00000004
+
+/* CPU access explicitly needed. */
+#define gcvALLOC_FLAG_CPU_ACCESS            0x00000008
+/* Can be remapped as cacheable. */
+#define gcvALLOC_FLAG_CACHEABLE             0x00000010
+
+/* Need 32bit address. */
 #define gcvALLOC_FLAG_4GB_ADDR              0x00000020
 
-/* Do not try slow pools (gcvPOOL_VIRTUAL/gcvPOOL_CONTIGUOUS) */
+/* Secure buffer. */
+#define gcvALLOC_FLAG_SECURITY              0x00000040
+/* Can be exported as dmabuf-fd */
+#define gcvALLOC_FLAG_DMABUF_EXPORTABLE     0x00000080
+/* Do not try slow pools (gcvPOOL_VIRTUAL) */
 #define gcvALLOC_FLAG_FAST_POOLS            0x00000100
 
 /* Import DMABUF. */
@@ -2137,6 +2309,12 @@ gceCOMPRESSION_OPTION;
 /* Import linux reserved memory. */
 #define gcvALLOC_FLAG_LINUX_RESERVED_MEM    0x00008000
 
+/* 1M pages unit allocation. */
+#define gcvALLOC_FLAG_1M_PAGES              0x00010000
+
+/* Non 1M pages unit allocation. */
+#define gcvALLOC_FLAG_4K_PAGES              0x00020000
+
 /* Real allocation happens when GPU page fault. */
 #define gcvALLOC_FLAG_ALLOC_ON_FAULT        0x01000000
 /* Alloc with memory limit. */
index 399eb8d..83a04ac 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -112,6 +112,9 @@ typedef struct _gcsSTATE_DELTA
        the overflow.*/
     gctUINT                     id;
 
+    /* The number of contexts pending modification by the delta. */
+    gctINT                      refCount;
+
     /* Vertex element count for the delta buffer. */
     gctUINT                     elementCount;
 
@@ -120,7 +123,6 @@ typedef struct _gcsSTATE_DELTA
 
     /* Record array; holds all modified states in gcsSTATE_DELTA_RECORD. */
     gctUINT64                   recordArray;
-    gctUINT                     recordSize;
 
     /* Map entry ID is used for map entry validation. If map entry ID does not
        match the main state delta ID, the entry and the corresponding state are
@@ -131,35 +133,12 @@ typedef struct _gcsSTATE_DELTA
     /* If the map entry ID matches the main state delta ID, index points to
        the state record in the record array. */
     gctUINT64                   mapEntryIndex;
-}
-gcsSTATE_DELTA;
-
-#define gcdPATCH_LIST_SIZE      1024
 
-/* Command buffer patch record. */
-typedef struct _gcsPATCH
-{
-    /* Handle of a video memory node. */
-    gctUINT32                   handle;
-
-    /* Flag */
-    gctUINT32                   flag;
-}
-gcsPATCH;
-
-/* List of patches for the command buffer. */
-typedef struct _gcsPATCH_LIST
-{
-    /* Array of patch records. */
-    struct _gcsPATCH            patch[gcdPATCH_LIST_SIZE];
-
-    /* Number of patches in the array. */
-    gctUINT                     count;
-
-    /* Next item in the list. */
-    struct _gcsPATCH_LIST       *next;
+    /* Previous and next state deltas in gcsSTATE_DELTA. */
+    gctUINT64                   prev;
+    gctUINT64                   next;
 }
-gcsPATCH_LIST;
+gcsSTATE_DELTA;
 
 #define FENCE_NODE_LIST_INIT_COUNT         100
 
@@ -189,6 +168,43 @@ typedef struct _gcsFENCE_LIST
 gcsFENCE_LIST;
 
 /* Command buffer object. */
+/*
+ * Initial (before put commands):
+ *
+ *    +-------------------------------------------
+ * ...|reservedHead|
+ *    +-------------------------------------------
+ *    ^            ^
+ *    |            |
+ * startOffset   offset
+ *
+ *
+ * After put command, in commit:
+ *
+ *    +------------------------------------------+
+ * .. |reservedHead| .. commands .. |reservedTail| ..
+ *    +------------------------------------------+
+ *    ^                             ^
+ *    |                             |
+ * startOffset                    offset
+ *
+ *
+ * Commit done, becomes initial state:
+ *
+ *    +------------------------------------------+-----------------
+ * .. |reservedHead| .. commands .. |reservedTail|reservedHead| ..
+ *    +------------------------------------------+-----------------
+ *                                               ^            ^
+ *                                               |            |
+ *                                          startOffset    offset
+ *
+ * reservedHead:
+ * Select pipe commands.
+ *
+ * reservedTail:
+ * Link, Fence, ChipEnable
+ *
+ */
 struct _gcoCMDBUF
 {
     /* The object. */
@@ -205,11 +221,15 @@ struct _gcoCMDBUF
     gctBOOL                     using2D;
     gctBOOL                     using3D;
 
-    /* Size of reserved tail for each commit. */
+    /* Size of reserved head and tail for each commit. */
+    gctUINT32                   reservedHead;
     gctUINT32                   reservedTail;
 
-    /* Physical address of command buffer. Just a name. */
-    gctUINT32                   physical;
+    /* Video memory handle of command buffer. */
+    gctUINT32                   videoMemNode;
+
+    /* GPU address of command buffer. */
+    gctUINT32                   address;
 
     /* Logical address of command buffer. */
     gctUINT64                   logical;
@@ -230,24 +250,11 @@ struct _gcoCMDBUF
     gctUINT64                   lastReserve;
     gctUINT32                   lastOffset;
 
-#if gcdSECURE_USER
-    /* Hint array for the current command buffer. */
-    gctUINT                     hintArraySize;
-    gctUINT64                   hintArray;
-    gctUINT64                   hintArrayTail;
-#endif
-
     /* Last load state command location and hardware address. */
     gctUINT64                   lastLoadStatePtr;
     gctUINT32                   lastLoadStateAddress;
     gctUINT32                   lastLoadStateCount;
 
-    /* List of patches. */
-    gctUINT64                   patchHead;
-
-    /* Link to next gcoCMDBUF object in one commit. */
-    gctUINT64                   nextCMDBUF;
-
     /*
     * Put pointer type member after this line.
     */
@@ -274,6 +281,15 @@ typedef struct _gcsQUEUE
 }
 gcsQUEUE;
 
+/* A record chunk include multiple records to save allocation. */
+typedef struct _gcsQUEUE_CHUNK
+{
+    struct _gcsQUEUE_CHUNK *    next;
+
+    gcsQUEUE                    record[16];
+}
+gcsQUEUE_CHUNK;
+
 /* Event queue. */
 struct _gcoQUEUE
 {
@@ -284,15 +300,17 @@ struct _gcoQUEUE
     gcsQUEUE_PTR                head;
     gcsQUEUE_PTR                tail;
 
-    /* chunks of the records. */
-    gctPOINTER                  chunks;
-
     /* List of free records. */
     gcsQUEUE_PTR                freeList;
 
+    /* chunks of the records. */
+    gcsQUEUE_CHUNK *            chunks;
+
     #define gcdIN_QUEUE_RECORD_LIMIT 16
     /* Number of records currently in queue */
     gctUINT32                   recordCount;
+    /* Number of records which release resource currently in queue */
+    gctUINT32                   tmpBufferRecordCount;
 
     /* Max size of pending unlock node in vidmem pool not committed */
     gctUINT                     maxUnlockBytes;
index 0adf62f..c13297b 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 619c7a5..c59b03e 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 2c41d15..7b7747d 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -107,7 +107,7 @@ This define enables the use of VM for gckCommand and fence buffers.
 /*
     VIVANTE_PROFILER
 
-        This define enables the profiler.
+        This define enables the profiler for hardware counters.
 */
 #ifndef VIVANTE_PROFILER
 #   define VIVANTE_PROFILER                     1
@@ -167,65 +167,73 @@ This define enables the use of VM for gckCommand and fence buffers.
 #define COMMAND_PROCESSOR_VERSION               1
 
 /*
-    gcdDUMP_KEY
+    gcdDUMP
+
+        Dump for hw capture.
+        When set to 1, a dump of all states and memory uploads, as well as other
+        hardware related execution will be printed to the debug console.  This
+        data can be used for playing back applications.
 
-        Set this to a string that appears in 'cat /proc/<pid>/cmdline'. E.g. 'camera'.
-        HAL will create dumps for the processes matching this key.
+        When set to 2, for vxc, all output memory will be dump.
+
+        Please get tweak settings in gc_hal_dump.h.
 */
-#ifndef gcdDUMP_KEY
-#   define gcdDUMP_KEY                          "process"
+#ifndef gcdDUMP
+#   define gcdDUMP                              0
 #endif
 
 /*
-    gcdDUMP_PATH
+    gcdDUMP_IN_KERNEL
+
+        Enhanced feature for hw capture capture.
+        Required for MCFE.
+        When set to 1, all dumps will happen in the kernel.  This is handy if
+        you want the kernel to dump its command buffers as well and the data
+        needs to be in sync.
 
-        The dump file location. Some processes cannot write to the sdcard.
-        Try apps' data dir, e.g. /data/data/com.android.launcher
+        Dump in kernel implies kernel command dump.
+        See debugfs:/gc/dump/ for runtime configuration.
 */
-#ifndef gcdDUMP_PATH
-#if defined(ANDROID)
-#   define gcdDUMP_PATH                         "/mnt/sdcard/"
-#else
-#   define gcdDUMP_PATH                         "./"
-#endif
+#ifndef gcdDUMP_IN_KERNEL
+#   define gcdDUMP_IN_KERNEL                    0
 #endif
 
 /*
-    gcdDUMP
-
-        When set to 1, a dump of all states and memory uploads, as well as other
-        hardware related execution will be printed to the debug console.  This
-        data can be used for playing back applications.
+    gcdDUMP_2D
 
-        When set to 2, for vxc, all output memory will be dump.
+        Dump for 2D capture.
+        When set to non-zero, it will dump the 2D command and surface.
 
+        Please get tweak settings in gc_hal_dump.h.
 */
-#ifndef gcdDUMP
-#   define gcdDUMP                              0
+#ifndef gcdDUMP_2D
+#   define gcdDUMP_2D                           0
 #endif
 
 /*
     gcdDUMP_API
 
+        Dump driver level API.
         When set to 1, a high level dump of the EGL and GL/VG APs's are
         captured.
+
+        Please get tweak settings in gc_hal_dump.h.
 */
 #ifndef gcdDUMP_API
 #   define gcdDUMP_API                          0
 #endif
 
-#ifndef gcdDUMP_2DVG
-#   define gcdDUMP_2DVG                         0
-#endif
-
 /*
-    gcdDUMP_AHB_ACCESS
+    gcdDUMP_PER_OPERATION
 
-        When set to 1, a dump of all AHB register access will be printed to kernel
-        message.
+        Operation based dump.
+
+        Dump the block as below.
+        1. Multiple operations belong to the same SW tiling block.
+        2. Single operation which is NOT in any SW tiling block.
 */
-#ifndef gcdDUMP_AHB_ACCESS
-#   define gcdDUMP_AHB_ACCESS                   0
+#ifndef gcdDUMP_PER_OPERATION
+#   define gcdDUMP_PER_OPERATION                0
 #endif
 
 /*
@@ -310,29 +318,6 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   endif
 #endif
 
-/*
-    gcdDUMP_VERIFY_PER_DRAW
-
-        When set to 1, verify RT and images(if used) for every single draw to ease simulation debug.
-        Only valid for ES3 driver for now.
-*/
-#ifndef gcdDUMP_VERIFY_PER_DRAW
-#   define gcdDUMP_VERIFY_PER_DRAW                0
-#endif
-
-
-
-/*
-    gcdDUMP_FRAMERATE
-        When set to a value other than zero, averaqe frame rate will be dumped.
-        The value set is the starting frame that the average will be calculated.
-        This is needed because sometimes first few frames are too slow to be included
-        in the average. Frame count starts from 1.
-*/
-#ifndef gcdDUMP_FRAMERATE
-#   define gcdDUMP_FRAMERATE                    0
-#endif
-
 /*
     gcdENABLE_FSCALE_VAL_ADJUST
         When non-zero, FSCALE_VAL when gcvPOWER_ON can be adjusted externally.
@@ -341,46 +326,6 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   define gcdENABLE_FSCALE_VAL_ADJUST          1
 #endif
 
-/*
-    gcdDUMP_IN_KERNEL
-
-        When set to 1, all dumps will happen in the kernel.  This is handy if
-        you want the kernel to dump its command buffers as well and the data
-        needs to be in sync.
-*/
-#ifndef gcdDUMP_IN_KERNEL
-#   define gcdDUMP_IN_KERNEL                    0
-#endif
-
-/*
-    gcdDUMP_COMMAND
-
-        When set to non-zero, the command queue will dump all incoming command
-        and context buffers as well as all other modifications to the command
-        queue.
-*/
-#ifndef gcdDUMP_COMMAND
-#   define gcdDUMP_COMMAND                      0
-#endif
-
-/*
-    gcdDUMP_2D
-
-        When set to non-zero, it will dump the 2D command and surface.
-*/
-#ifndef gcdDUMP_2D
-#   define gcdDUMP_2D                           0
-#endif
-
-/*
-    gcdDUMP_FRAME_TGA
-
-    When set to a value other than 0, a dump of the frame specified by the value,
-    will be done into frame.tga. Frame count starts from 1.
- */
-#ifndef gcdDUMP_FRAME_TGA
-#   define gcdDUMP_FRAME_TGA                    0
-#endif
 /*
     gcdNULL_DRIVER
 
@@ -469,52 +414,6 @@ This define enables the use of VM for gckCommand and fence buffers.
 #ifndef gcdGC355_VGMMU_MEMORY_SIZE_KB
 #   define gcdGC355_VGMMU_MEMORY_SIZE_KB   32
 #endif
-/*
-    gcdSECURE_USER
-
-        Use logical addresses instead of physical addresses in user land.  In
-        this case a hint table is created for both command buffers and context
-        buffers, and that hint table will be used to patch up those buffers in
-        the kernel when they are ready to submit.
-*/
-#ifndef gcdSECURE_USER
-#   define gcdSECURE_USER                       0
-#endif
-
-/*
-    gcdSECURE_CACHE_SLOTS
-
-        Number of slots in the logical to DMA address cache table.  Each time a
-        logical address needs to be translated into a DMA address for the GPU,
-        this cache will be walked.  The replacement scheme is LRU.
-*/
-#ifndef gcdSECURE_CACHE_SLOTS
-#   define gcdSECURE_CACHE_SLOTS                1024
-#endif
-
-/*
-    gcdSECURE_CACHE_METHOD
-
-        Replacement scheme used for Secure Cache.  The following options are
-        available:
-
-            gcdSECURE_CACHE_LRU
-                A standard LRU cache.
-
-            gcdSECURE_CACHE_LINEAR
-                A linear walker with the idea that an application will always
-                render the scene in a similar way, so the next entry in the
-                cache should be a hit most of the time.
-
-            gcdSECURE_CACHE_HASH
-                A 256-entry hash table.
-
-            gcdSECURE_CACHE_TABLE
-                A simple cache but with potential of a lot of cache replacement.
-*/
-#ifndef gcdSECURE_CACHE_METHOD
-#   define gcdSECURE_CACHE_METHOD               gcdSECURE_CACHE_HASH
-#endif
 
 /*
     gcdREGISTER_ACCESS_FROM_USER
@@ -564,8 +463,12 @@ This define enables the use of VM for gckCommand and fence buffers.
         If the value is 0, no timeout will be checked for.
 */
 #ifndef gcdGPU_TIMEOUT
+#if gcdFPGA_BUILD
+#   define gcdGPU_TIMEOUT                   2000000
+#else
 #   define gcdGPU_TIMEOUT                   20000
 #endif
+#endif
 
 /*
     gcdGPU_2D_TIMEOUT
@@ -724,22 +627,6 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   define gcdFRAME_DB_NAME                     "/var/log/frameDB.log"
 #endif
 
-/*
-   gcdPAGED_MEMORY_CACHEABLE
-
-        When non-zero, paged memory will be cacheable.
-
-        Normally, driver will detemines whether a video memory
-        is cacheable or not. When cacheable is not neccessary,
-        it will be writecombine.
-
-        This option is only for those SOC which can't enable
-        writecombine without enabling cacheable.
-*/
-#ifndef gcdPAGED_MEMORY_CACHEABLE
-#   define gcdPAGED_MEMORY_CACHEABLE            0
-#endif
-
 /*
    gcdENABLE_CACHEABLE_COMMAND_BUFFER
 
@@ -800,17 +687,6 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   define gcdUSE_TRIANGLE_STRIP_PATCH          1
 #endif
 
-/*
-    gcdPROCESS_ADDRESS_SPACE
-
-        When non-zero, every process which attaches to galcore has its own GPU
-        address space, size of which is gcdPROCESS_ADDRESS_SPACE_SIZE.
-*/
-#ifndef gcdPROCESS_ADDRESS_SPACE
-#   define gcdPROCESS_ADDRESS_SPACE             0
-#   define gcdPROCESS_ADDRESS_SPACE_SIZE        0x80000000
-#endif
-
 /*
     gcdSHARED_PAGETABLE
 
@@ -833,7 +709,7 @@ This define enables the use of VM for gckCommand and fence buffers.
         whose requesting size is less than gcdSMALL_BLOCK_SIZE.
 
         For Linux, it's the size of a page. If this requeset fallbacks
-        to gcvPOOL_CONTIGUOUS or gcvPOOL_VIRTUAL, memory will be wasted
+        to gcvPOOL_VIRTUAL, memory will be wasted
         because they allocate a page at least.
 */
 #ifndef gcdSMALL_BLOCK_SIZE
@@ -841,9 +717,22 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   define gcdRATIO_FOR_SMALL_MEMORY            32
 #endif
 
+/*
+    gcdENABLE_GPU_1M_PAGE
+        When non-zero, GPU page size will be 1M until the pool is out of memory
+        and low-level to 4K pages. When zero, it uses 4k GPU pages.
+*/
+#ifndef gcdENABLE_GPU_1M_PAGE
+#if !gcdSECURITY && defined(LINUX)
+#   define gcdENABLE_GPU_1M_PAGE                1
+#else
+#   define gcdENABLE_GPU_1M_PAGE                0
+#endif
+#endif
+
 /*
     gcdCONTIGUOUS_SIZE_LIMIT
-        When non-zero, size of video node from gcvPOOL_CONTIGUOUS is
+        When non-zero, size of video node from gcvPOOL_VIRTUAL contiguous is
         limited by gcdCONTIGUOUS_SIZE_LIMIT.
 */
 #ifndef gcdCONTIGUOUS_SIZE_LIMIT
@@ -1257,6 +1146,9 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   define gcdGC355_PROFILER                    0
 #endif
 
+/*
+    This definition must be paired with VIVANTE_PROFILER_SYSTEM_MEMORY
+*/
 #ifndef gcdGC355_MEM_PRINT
 #   define gcdGC355_MEM_PRINT                      0
 #else
@@ -1325,6 +1217,13 @@ This define enables the use of VM for gckCommand and fence buffers.
 #   define gcdENABLE_APPCTXT_BLITDRAW                     0
 #endif
 
+/*
+    When enabled, use 1K mode for MMU version 2.0. otherwise use 4K mode.
+*/
+#ifndef gcdENABLE_MMU_1KMODE
+#   define gcdENABLE_MMU_1KMODE                  1
+#endif
+
 /*
     gcdENABLE_TRUST_APPLICATION
 
@@ -1350,8 +1249,12 @@ This define enables the use of VM for gckCommand and fence buffers.
 #endif
 
 #ifndef gcdMMU_SECURE_AREA_SIZE
+#if defined(gcdENABLE_MMU_1KMODE)
+#   define gcdMMU_SECURE_AREA_SIZE              32
+#else
 #   define gcdMMU_SECURE_AREA_SIZE              128
 #endif
+#endif
 
 /*
 VIV:gcdUSE_MMU_EXCEPTION
@@ -1366,10 +1269,6 @@ VIV:gcdUSE_MMU_EXCEPTION
 #   define gcdVX_OPTIMIZER                      0
 #endif
 
-#ifndef gcdOCL_READ_IMAGE_OPTIMIZATION
-#   define gcdOCL_READ_IMAGE_OPTIMIZATION       0
-#endif
-
 #ifndef gcdALLOC_ON_FAULT
 #   define gcdALLOC_ON_FAULT                    0
 #endif
@@ -1402,6 +1301,36 @@ VIV:gcdUSE_MMU_EXCEPTION
 #   define gcdENABLE_KERNEL_FENCE               0
 #endif
 
+/*
+    gcdUSE_VXC_BINARY
+        When enabled, will use prebuilt shader binary in VX driver.
+ */
+#ifndef gcdUSE_VXC_BINARY
+#   define gcdUSE_VXC_BINARY                    0
+#endif
+
+/*
+    gcdFEATURE_SANITYCHECK
+        When enabled, will do hardware feature sanity check, each
+        used hardware feature should be printed out.
+ */
+#ifndef gcdFEATURE_SANITYCHECK
+#   define gcdFEATURE_SANITYCHECK                0
+#endif
+
+
+/*
+    VIVANTE_PROFILER_SYSTEM_MEMORY
+
+        This define enables the profiling data for system memory allocated by driver
+*/
+#ifndef VIVANTE_PROFILER_SYSTEM_MEMORY
+#   define VIVANTE_PROFILER_SYSTEM_MEMORY        1
+#   define VP_MALLOC_OFFSET                     (16)
+
+#endif
+
+#define gcdHAL_TEST 1
 
 #endif /* __gc_hal_options_h_ */
 
index 38f4270..49e2cc4 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -594,7 +594,9 @@ extern "C" {
 #define VPNC_HIIDLECYCLES                (VPNG_HI + 16)
 #define VPNC_HIREAD8BYTE                 (VPNG_HI + 17)
 #define VPNC_HIWRITE8BYTE                (VPNG_HI + 18)
-#define VPNC_HI_COUNT                    VPNC_HIWRITE8BYTE - VPNG_HI
+#define VPNC_HIOCBREAD16BYTE             (VPNG_HI + 19)
+#define VPNC_HIOCBWRITE16BYTE            (VPNG_HI + 20)
+#define VPNC_HI_COUNT                    VPNC_HIOCBWRITE16BYTE - VPNG_HI
 
 /* HW: L2 Counters. */
 #define VPNC_L2AXI0READREQCOUNT          (VPNG_L2 + 1)
@@ -681,6 +683,12 @@ extern "C" {
 #define DEFAULT_PROFILE_FILE_NAME   "vprofiler.vpd"
 #endif
 
+#define VPHEADER_VERSION "VP20"
+
+#define VPFILETYPE_GL "10"
+
+#define VPFILETYPE_CL "00"
+
 #if gcdENDIAN_BIG
 #define BIG_ENDIAN_TRANS_INT(x) ((gctUINT32)(\
         (((gctUINT32)(x) & (gctUINT32)0x000000FFUL) << 24) | \
@@ -760,18 +768,24 @@ extern "C" {
     } \
     while (gcvFALSE)
 
+
 #define gcmGET_COUNTER(counter, counterId) \
     do \
     { \
-        if ((gctUINT32)*(memory + counterId + offset) == 0xdeaddead) \
+        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) \
         { \
             counter = 0xdeaddead; \
         } \
         else \
         { \
-            gctUINT64_PTR Memory = memory; \
-            Memory += TOTAL_PROBE_NUMBER * CoreId; \
-            counter = (gctUINT32)*(Memory + counterId + offset); \
+            gctUINT32 i; \
+            gctUINT32_PTR Memory = memory; \
+            counter = 0; \
+            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * (1 << clusterIDWidth); \
+            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) \
+            { \
+                counter += *(Memory + (counterId + offset) * (1 << clusterIDWidth) + i); \
+            } \
         } \
     } \
     while (gcvFALSE)
@@ -779,18 +793,22 @@ extern "C" {
 #define gcmGET_LATENCY_COUNTER(minLatency, maxLatency, counterId) \
     do \
     { \
-        if ((gctUINT32)*(memory + counterId + offset) == 0xdeaddead) \
+        if (*(memory + (counterId + offset) * (1 << clusterIDWidth)) == 0xdeaddead) \
         { \
             minLatency = maxLatency = 0xdeaddead; \
         } \
         else \
         { \
-            gctUINT64_PTR Memory = memory; \
-            Memory += TOTAL_PROBE_NUMBER * CoreId; \
-            maxLatency = (((gctUINT32)*(Memory + counterId + offset) & 0xfff000) >> 12); \
-            minLatency = ((gctUINT32)*(Memory + counterId + offset) & 0x000fff); \
-            if (minLatency == 4095) \
-                minLatency = 0; \
+            gctUINT32 i; \
+            gctUINT32_PTR Memory = memory; \
+            Memory = memory + TOTAL_PROBE_NUMBER * CoreId * (1 << clusterIDWidth); \
+            for (i = 0; i < (gctUINT32)(1 << clusterIDWidth); i++) \
+            { \
+                maxLatency += ((*(Memory + (counterId + offset) * (1 << clusterIDWidth) + i) & 0xfff000) >> 12); \
+                minLatency += (*(Memory + (counterId + offset) * (1 << clusterIDWidth) + i) & 0x000fff); \
+                if (minLatency == 4095) \
+                    minLatency = 0; \
+            } \
         } \
     } \
     while (gcvFALSE)
@@ -1005,6 +1023,8 @@ typedef struct _gcsPROFILER_COUNTERS_PART2
     gctUINT32       hi_total_idle_cycle_count;
     gctUINT32       hi_total_read_8B_count;
     gctUINT32       hi_total_write_8B_count;
+    gctUINT32       hi_total_readOCB_16B_count;
+    gctUINT32       hi_total_writeOCB_16B_count;
 
     /* L2 */
     gctUINT32       l2_total_axi0_read_request_count;
@@ -1133,7 +1153,7 @@ gcoPROFILER_Destroy(
     );
 
 gceSTATUS
-gcoPROFILER_Enable(
+gcoPROFILER_Initialize(
     IN gcoPROFILER Profiler
     );
 
@@ -1143,7 +1163,7 @@ gcoPROFILER_Disable(
     );
 
 gceSTATUS
-gcoPROFILER_Begin(
+gcoPROFILER_EnableCounters(
     IN gcoPROFILER Profiler,
     IN gceCOUNTER_OPTYPE operationType
     );
index 988577f..1aba11c 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -473,7 +473,6 @@ gco2D_SetTarget64(
     IN gctUINT32 SurfaceHeight
     );
 
-
 /* Calculate and program the stretch factors. */
 gceSTATUS
 gco2D_CalcStretchFactor(
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_rename.h
deleted file mode 100644 (file)
index df842af..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/****************************************************************************
-*
-*    The MIT License (MIT)
-*
-*    Copyright (c) 2014 - 2018 Vivante Corporation
-*
-*    Permission is hereby granted, free of charge, to any person obtaining a
-*    copy of this software and associated documentation files (the "Software"),
-*    to deal in the Software without restriction, including without limitation
-*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
-*    and/or sell copies of the Software, and to permit persons to whom the
-*    Software is furnished to do so, subject to the following conditions:
-*
-*    The above copyright notice and this permission notice shall be included in
-*    all copies or substantial portions of the Software.
-*
-*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-*    DEALINGS IN THE SOFTWARE.
-*
-*****************************************************************************
-*
-*    The GPL License (GPL)
-*
-*    Copyright (C) 2014 - 2018 Vivante Corporation
-*
-*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*
-*****************************************************************************
-*
-*    Note: This software is released under dual MIT and GPL licenses. A
-*    recipient may use this file under the terms of either the MIT license or
-*    GPL License. If you wish to use only one license not the other, you can
-*    indicate your decision by deleting one of the above license notices in your
-*    version of this file.
-*
-*****************************************************************************/
-
-
-#ifndef __gc_hal_rename_h_
-#define __gc_hal_rename_h_
-
-
-#if defined(_HAL2D_APPENDIX)
-
-#define _HAL2D_RENAME_2(api, appendix)  api ## appendix
-#define _HAL2D_RENAME_1(api, appendix)  _HAL2D_RENAME_2(api, appendix)
-#define gcmHAL2D(api)                   _HAL2D_RENAME_1(api, _HAL2D_APPENDIX)
-
-
-#define gckOS_Construct                 gcmHAL2D(gckOS_Construct)
-#define gckOS_Destroy                   gcmHAL2D(gckOS_Destroy)
-#define gckOS_QueryVideoMemory          gcmHAL2D(gckOS_QueryVideoMemory)
-#define gckOS_Allocate                  gcmHAL2D(gckOS_Allocate)
-#define gckOS_Free                      gcmHAL2D(gckOS_Free)
-#define gckOS_AllocateMemory            gcmHAL2D(gckOS_AllocateMemory)
-#define gckOS_FreeMemory                gcmHAL2D(gckOS_FreeMemory)
-#define gckOS_AllocatePagedMemory       gcmHAL2D(gckOS_AllocatePagedMemory)
-#define gckOS_AllocatePagedMemoryEx     gcmHAL2D(gckOS_AllocatePagedMemoryEx)
-#define gckOS_LockPages                 gcmHAL2D(gckOS_LockPages)
-#define gckOS_MapPages                  gcmHAL2D(gckOS_MapPages)
-#define gckOS_UnlockPages               gcmHAL2D(gckOS_UnlockPages)
-#define gckOS_FreePagedMemory           gcmHAL2D(gckOS_FreePagedMemory)
-#define gckOS_AllocateNonPagedMemory    gcmHAL2D(gckOS_AllocateNonPagedMemory)
-#define gckOS_FreeNonPagedMemory        gcmHAL2D(gckOS_FreeNonPagedMemory)
-#define gckOS_AllocateContiguous        gcmHAL2D(gckOS_AllocateContiguous)
-#define gckOS_FreeContiguous            gcmHAL2D(gckOS_FreeContiguous)
-#define gckOS_GetPageSize               gcmHAL2D(gckOS_GetPageSize)
-#define gckOS_GetPhysicalAddress        gcmHAL2D(gckOS_GetPhysicalAddress)
-#define gckOS_UserLogicalToPhysical     gcmHAL2D(gckOS_UserLogicalToPhysical)
-#define gckOS_GetPhysicalAddressProcess gcmHAL2D(gckOS_GetPhysicalAddressProcess)
-#define gckOS_MapPhysical               gcmHAL2D(gckOS_MapPhysical)
-#define gckOS_UnmapPhysical             gcmHAL2D(gckOS_UnmapPhysical)
-#define gckOS_ReadRegister              gcmHAL2D(gckOS_ReadRegister)
-#define gckOS_WriteRegister             gcmHAL2D(gckOS_WriteRegister)
-#define gckOS_WriteMemory               gcmHAL2D(gckOS_WriteMemory)
-#define gckOS_MapMemory                 gcmHAL2D(gckOS_MapMemory)
-#define gckOS_UnmapMemory               gcmHAL2D(gckOS_UnmapMemory)
-#define gckOS_UnmapMemoryEx             gcmHAL2D(gckOS_UnmapMemoryEx)
-#define gckOS_CreateMutex               gcmHAL2D(gckOS_CreateMutex)
-#define gckOS_DeleteMutex               gcmHAL2D(gckOS_DeleteMutex)
-#define gckOS_AcquireMutex              gcmHAL2D(gckOS_AcquireMutex)
-#define gckOS_ReleaseMutex              gcmHAL2D(gckOS_ReleaseMutex)
-#define gckOS_AtomicExchange            gcmHAL2D(gckOS_AtomicExchange)
-#define gckOS_AtomicExchangePtr         gcmHAL2D(gckOS_AtomicExchangePtr)
-#define gckOS_AtomConstruct             gcmHAL2D(gckOS_AtomConstruct)
-#define gckOS_AtomDestroy               gcmHAL2D(gckOS_AtomDestroy)
-#define gckOS_AtomGet                   gcmHAL2D(gckOS_AtomGet)
-#define gckOS_AtomIncrement             gcmHAL2D(gckOS_AtomIncrement)
-#define gckOS_AtomDecrement             gcmHAL2D(gckOS_AtomDecrement)
-#define gckOS_Delay                     gcmHAL2D(gckOS_Delay)
-#define gckOS_GetTime                   gcmHAL2D(gckOS_GetTime)
-#define gckOS_MemoryBarrier             gcmHAL2D(gckOS_MemoryBarrier)
-#define gckOS_MapUserPointer            gcmHAL2D(gckOS_MapUserPointer)
-#define gckOS_UnmapUserPointer          gcmHAL2D(gckOS_UnmapUserPointer)
-#define gckOS_QueryNeedCopy             gcmHAL2D(gckOS_QueryNeedCopy)
-#define gckOS_CopyFromUserData          gcmHAL2D(gckOS_CopyFromUserData)
-#define gckOS_CopyToUserData            gcmHAL2D(gckOS_CopyToUserData)
-#define gckOS_SuspendInterrupt          gcmHAL2D(gckOS_SuspendInterrupt)
-#define gckOS_ResumeInterrupt           gcmHAL2D(gckOS_ResumeInterrupt)
-#define gckOS_GetBaseAddress            gcmHAL2D(gckOS_GetBaseAddress)
-#define gckOS_MemCopy                   gcmHAL2D(gckOS_MemCopy)
-#define gckOS_ZeroMemory                gcmHAL2D(gckOS_ZeroMemory)
-#define gckOS_DeviceControl             gcmHAL2D(gckOS_DeviceControl)
-#define gckOS_GetProcessID              gcmHAL2D(gckOS_GetProcessID)
-#define gckOS_GetThreadID               gcmHAL2D(gckOS_GetThreadID)
-#define gckOS_CreateSignal              gcmHAL2D(gckOS_CreateSignal)
-#define gckOS_DestroySignal             gcmHAL2D(gckOS_DestroySignal)
-#define gckOS_Signal                    gcmHAL2D(gckOS_Signal)
-#define gckOS_WaitSignal                gcmHAL2D(gckOS_WaitSignal)
-#define gckOS_MapSignal                 gcmHAL2D(gckOS_MapSignal)
-#define gckOS_MapUserMemory             gcmHAL2D(gckOS_MapUserMemory)
-#define gckOS_UnmapUserMemory           gcmHAL2D(gckOS_UnmapUserMemory)
-#define gckOS_CreateUserSignal          gcmHAL2D(gckOS_CreateUserSignal)
-#define gckOS_DestroyUserSignal         gcmHAL2D(gckOS_DestroyUserSignal)
-#define gckOS_WaitUserSignal            gcmHAL2D(gckOS_WaitUserSignal)
-#define gckOS_SignalUserSignal          gcmHAL2D(gckOS_SignalUserSignal)
-#define gckOS_UserSignal                gcmHAL2D(gckOS_UserSignal)
-#define gckOS_UserSignal                gcmHAL2D(gckOS_UserSignal)
-#define gckOS_CacheClean                gcmHAL2D(gckOS_CacheClean)
-#define gckOS_CacheFlush                gcmHAL2D(gckOS_CacheFlush)
-#define gckOS_SetDebugLevel             gcmHAL2D(gckOS_SetDebugLevel)
-#define gckOS_SetDebugZone              gcmHAL2D(gckOS_SetDebugZone)
-#define gckOS_SetDebugLevelZone         gcmHAL2D(gckOS_SetDebugLevelZone)
-#define gckOS_SetDebugZones             gcmHAL2D(gckOS_SetDebugZones)
-#define gckOS_SetDebugFile              gcmHAL2D(gckOS_SetDebugFile)
-#define gckOS_Broadcast                 gcmHAL2D(gckOS_Broadcast)
-#define gckOS_SetGPUPower               gcmHAL2D(gckOS_SetGPUPower)
-#define gckOS_CreateSemaphore           gcmHAL2D(gckOS_CreateSemaphore)
-#define gckOS_DestroySemaphore          gcmHAL2D(gckOS_DestroySemaphore)
-#define gckOS_AcquireSemaphore          gcmHAL2D(gckOS_AcquireSemaphore)
-#define gckOS_ReleaseSemaphore          gcmHAL2D(gckOS_ReleaseSemaphore)
-#define gckHEAP_Construct               gcmHAL2D(gckHEAP_Construct)
-#define gckHEAP_Destroy                 gcmHAL2D(gckHEAP_Destroy)
-#define gckHEAP_Allocate                gcmHAL2D(gckHEAP_Allocate)
-#define gckHEAP_Free                    gcmHAL2D(gckHEAP_Free)
-#define gckHEAP_ProfileStart            gcmHAL2D(gckHEAP_ProfileStart)
-#define gckHEAP_ProfileEnd              gcmHAL2D(gckHEAP_ProfileEnd)
-#define gckHEAP_Test                    gcmHAL2D(gckHEAP_Test)
-#define gckVIDMEM_Construct             gcmHAL2D(gckVIDMEM_Construct)
-#define gckVIDMEM_Destroy               gcmHAL2D(gckVIDMEM_Destroy)
-#define gckVIDMEM_Allocate              gcmHAL2D(gckVIDMEM_Allocate)
-#define gckVIDMEM_AllocateLinear        gcmHAL2D(gckVIDMEM_AllocateLinear)
-#define gckVIDMEM_Free                  gcmHAL2D(gckVIDMEM_Free)
-#define gckVIDMEM_Lock                  gcmHAL2D(gckVIDMEM_Lock)
-#define gckVIDMEM_Unlock                gcmHAL2D(gckVIDMEM_Unlock)
-#define gckVIDMEM_ConstructVirtual      gcmHAL2D(gckVIDMEM_ConstructVirtual)
-#define gckVIDMEM_DestroyVirtual        gcmHAL2D(gckVIDMEM_DestroyVirtual)
-#define gckKERNEL_Construct             gcmHAL2D(gckKERNEL_Construct)
-#define gckKERNEL_Destroy               gcmHAL2D(gckKERNEL_Destroy)
-#define gckKERNEL_Dispatch              gcmHAL2D(gckKERNEL_Dispatch)
-#define gckKERNEL_QueryVideoMemory      gcmHAL2D(gckKERNEL_QueryVideoMemory)
-#define gckKERNEL_GetVideoMemoryPool    gcmHAL2D(gckKERNEL_GetVideoMemoryPool)
-#define gckKERNEL_MapVideoMemory        gcmHAL2D(gckKERNEL_MapVideoMemory)
-#define gckKERNEL_UnmapVideoMemory      gcmHAL2D(gckKERNEL_UnmapVideoMemory)
-#define gckKERNEL_MapMemory             gcmHAL2D(gckKERNEL_MapMemory)
-#define gckKERNEL_UnmapMemory           gcmHAL2D(gckKERNEL_UnmapMemory)
-#define gckKERNEL_Notify                gcmHAL2D(gckKERNEL_Notify)
-#define gckKERNEL_QuerySettings         gcmHAL2D(gckKERNEL_QuerySettings)
-#define gckKERNEL_Recovery              gcmHAL2D(gckKERNEL_Recovery)
-#define gckKERNEL_OpenUserData          gcmHAL2D(gckKERNEL_OpenUserData)
-#define gckKERNEL_CloseUserData         gcmHAL2D(gckKERNEL_CloseUserData)
-#define gckHARDWARE_Construct           gcmHAL2D(gckHARDWARE_Construct)
-#define gckHARDWARE_Destroy             gcmHAL2D(gckHARDWARE_Destroy)
-#define gckHARDWARE_QuerySystemMemory   gcmHAL2D(gckHARDWARE_QuerySystemMemory)
-#define gckHARDWARE_BuildVirtualAddress     gcmHAL2D(gckHARDWARE_BuildVirtualAddress)
-#define gckHARDWARE_QueryCommandBuffer      gcmHAL2D(gckHARDWARE_QueryCommandBuffer)
-#define gckHARDWARE_WaitLink            gcmHAL2D(gckHARDWARE_WaitLink)
-#define gckHARDWARE_Execute             gcmHAL2D(gckHARDWARE_Execute)
-#define gckHARDWARE_End                 gcmHAL2D(gckHARDWARE_End)
-#define gckHARDWARE_Nop                 gcmHAL2D(gckHARDWARE_Nop)
-#define gckHARDWARE_PipeSelect          gcmHAL2D(gckHARDWARE_PipeSelect)
-#define gckHARDWARE_Link                gcmHAL2D(gckHARDWARE_Link)
-#define gckHARDWARE_Event               gcmHAL2D(gckHARDWARE_Event)
-#define gckHARDWARE_QueryMemory         gcmHAL2D(gckHARDWARE_QueryMemory)
-#define gckHARDWARE_QueryChipIdentity   gcmHAL2D(gckHARDWARE_QueryChipIdentity)
-#define gckHARDWARE_QueryChipSpecs      gcmHAL2D(gckHARDWARE_QueryChipSpecs)
-#define gckHARDWARE_QueryShaderCaps     gcmHAL2D(gckHARDWARE_QueryShaderCaps)
-#define gckHARDWARE_ConvertFormat       gcmHAL2D(gckHARDWARE_ConvertFormat)
-#define gckHARDWARE_SplitMemory         gcmHAL2D(gckHARDWARE_SplitMemory)
-#define gckHARDWARE_AlignToTile         gcmHAL2D(gckHARDWARE_AlignToTile)
-#define gckHARDWARE_UpdateQueueTail     gcmHAL2D(gckHARDWARE_UpdateQueueTail)
-#define gckHARDWARE_ConvertLogical      gcmHAL2D(gckHARDWARE_ConvertLogical)
-#define gckHARDWARE_Interrupt           gcmHAL2D(gckHARDWARE_Interrupt)
-#define gckHARDWARE_SetMMU              gcmHAL2D(gckHARDWARE_SetMMU)
-#define gckHARDWARE_FlushMMU            gcmHAL2D(gckHARDWARE_FlushMMU)
-#define gckHARDWARE_GetIdle             gcmHAL2D(gckHARDWARE_GetIdle)
-#define gckHARDWARE_Flush               gcmHAL2D(gckHARDWARE_Flush)
-#define gckHARDWARE_SetFastClear        gcmHAL2D(gckHARDWARE_SetFastClear)
-#define gckHARDWARE_ReadInterrupt       gcmHAL2D(gckHARDWARE_ReadInterrupt)
-#define gckHARDWARE_SetPowerManagementState         gcmHAL2D(gckHARDWARE_SetPowerManagementState)
-#define gckHARDWARE_QueryPowerManagementState       gcmHAL2D(gckHARDWARE_QueryPowerManagementState)
-#define gckHARDWARE_ProfileEngine2D     gcmHAL2D(gckHARDWARE_ProfileEngine2D)
-#define gckHARDWARE_InitializeHardware  gcmHAL2D(gckHARDWARE_InitializeHardware)
-#define gckHARDWARE_Reset               gcmHAL2D(gckHARDWARE_Reset)
-#define gckINTERRUPT_Construct          gcmHAL2D(gckINTERRUPT_Construct)
-#define gckINTERRUPT_Destroy            gcmHAL2D(gckINTERRUPT_Destroy)
-#define gckINTERRUPT_SetHandler         gcmHAL2D(gckINTERRUPT_SetHandler)
-#define gckINTERRUPT_Notify             gcmHAL2D(gckINTERRUPT_Notify)
-#define gckEVENT_Construct              gcmHAL2D(gckEVENT_Construct)
-#define gckEVENT_Destroy                gcmHAL2D(gckEVENT_Destroy)
-#define gckEVENT_AddList                gcmHAL2D(gckEVENT_AddList)
-#define gckEVENT_FreeNonPagedMemory     gcmHAL2D(gckEVENT_FreeNonPagedMemory)
-#define gckEVENT_FreeContiguousMemory   gcmHAL2D(gckEVENT_FreeContiguousMemory)
-#define gckEVENT_FreeVideoMemory        gcmHAL2D(gckEVENT_FreeVideoMemory)
-#define gckEVENT_Signal                 gcmHAL2D(gckEVENT_Signal)
-#define gckEVENT_Unlock                 gcmHAL2D(gckEVENT_Unlock)
-#define gckEVENT_Submit                 gcmHAL2D(gckEVENT_Submit)
-#define gckEVENT_Commit                 gcmHAL2D(gckEVENT_Commit)
-#define gckEVENT_Notify                 gcmHAL2D(gckEVENT_Notify)
-#define gckEVENT_Interrupt              gcmHAL2D(gckEVENT_Interrupt)
-#define gckCOMMAND_Construct            gcmHAL2D(gckCOMMAND_Construct)
-#define gckCOMMAND_Destroy              gcmHAL2D(gckCOMMAND_Destroy)
-#define gckCOMMAND_EnterCommit          gcmHAL2D(gckCOMMAND_EnterCommit)
-#define gckCOMMAND_ExitCommit           gcmHAL2D(gckCOMMAND_ExitCommit)
-#define gckCOMMAND_Start                gcmHAL2D(gckCOMMAND_Start)
-#define gckCOMMAND_Stop                 gcmHAL2D(gckCOMMAND_Stop)
-#define gckCOMMAND_Commit               gcmHAL2D(gckCOMMAND_Commit)
-#define gckCOMMAND_Reserve              gcmHAL2D(gckCOMMAND_Reserve)
-#define gckCOMMAND_Execute              gcmHAL2D(gckCOMMAND_Execute)
-#define gckCOMMAND_Stall                gcmHAL2D(gckCOMMAND_Stall)
-#define gckCOMMAND_Attach               gcmHAL2D(gckCOMMAND_Attach)
-#define gckCOMMAND_Detach               gcmHAL2D(gckCOMMAND_Detach)
-#define gckMMU_Construct                gcmHAL2D(gckMMU_Construct)
-#define gckMMU_Destroy                  gcmHAL2D(gckMMU_Destroy)
-#define gckMMU_AllocatePages            gcmHAL2D(gckMMU_AllocatePages)
-#define gckMMU_FreePages                gcmHAL2D(gckMMU_FreePages)
-#define gckMMU_Test                     gcmHAL2D(gckMMU_Test)
-#define gckHARDWARE_QueryProfileRegisters     gcmHAL2D(gckHARDWARE_QueryProfileRegisters)
-
-
-#define FindMdlMap                      gcmHAL2D(FindMdlMap)
-#define OnProcessExit                   gcmHAL2D(OnProcessExit)
-
-#define gckGALDEVICE_Destroy            gcmHAL2D(gckGALDEVICE_Destroy)
-#define gckOS_Print                     gcmHAL2D(gckOS_Print)
-#define gckGALDEVICE_FreeMemory         gcmHAL2D(gckGALDEVICE_FreeMemory)
-#define gckGALDEVICE_AllocateMemory     gcmHAL2D(gckGALDEVICE_AllocateMemory)
-#define gckOS_DebugBreak                gcmHAL2D(gckOS_DebugBreak)
-#define gckGALDEVICE_Release_ISR        gcmHAL2D(gckGALDEVICE_Release_ISR)
-#define gckOS_Verify                    gcmHAL2D(gckOS_Verify)
-#define gckCOMMAND_Release              gcmHAL2D(gckCOMMAND_Release)
-#define gckGALDEVICE_Stop               gcmHAL2D(gckGALDEVICE_Stop)
-#define gckGALDEVICE_Construct          gcmHAL2D(gckGALDEVICE_Construct)
-#define gckOS_DebugFatal                gcmHAL2D(gckOS_DebugFatal)
-#define gckOS_DebugTrace                gcmHAL2D(gckOS_DebugTrace)
-#define gckHARDWARE_GetBaseAddress      gcmHAL2D(gckHARDWARE_GetBaseAddress)
-#define gckGALDEVICE_Setup_ISR          gcmHAL2D(gckGALDEVICE_Setup_ISR)
-#define gckKERNEL_AttachProcess         gcmHAL2D(gckKERNEL_AttachProcess)
-#define gckKERNEL_AttachProcessEx       gcmHAL2D(gckKERNEL_AttachProcessEx)
-#define gckGALDEVICE_Start_Thread       gcmHAL2D(gckGALDEVICE_Start_Thread)
-#define gckHARDWARE_QueryIdle           gcmHAL2D(gckHARDWARE_QueryIdle)
-#define gckGALDEVICE_Start              gcmHAL2D(gckGALDEVICE_Start)
-#define gckOS_GetKernelLogical          gcmHAL2D(gckOS_GetKernelLogical)
-#define gckOS_DebugTraceZone            gcmHAL2D(gckOS_DebugTraceZone)
-#define gckGALDEVICE_Stop_Thread        gcmHAL2D(gckGALDEVICE_Stop_Thread)
-#define gckHARDWARE_NeedBaseAddress     gcmHAL2D(gckHARDWARE_NeedBaseAddress)
-
-#endif
-
-#endif /* __gc_hal_rename_h_ */
-
-
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_resource.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_resource.h
deleted file mode 100644 (file)
index 0164222..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-*
-*    The MIT License (MIT)
-*
-*    Copyright (c) 2014 - 2018 Vivante Corporation
-*
-*    Permission is hereby granted, free of charge, to any person obtaining a
-*    copy of this software and associated documentation files (the "Software"),
-*    to deal in the Software without restriction, including without limitation
-*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
-*    and/or sell copies of the Software, and to permit persons to whom the
-*    Software is furnished to do so, subject to the following conditions:
-*
-*    The above copyright notice and this permission notice shall be included in
-*    all copies or substantial portions of the Software.
-*
-*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-*    DEALINGS IN THE SOFTWARE.
-*
-*****************************************************************************
-*
-*    The GPL License (GPL)
-*
-*    Copyright (C) 2014 - 2018 Vivante Corporation
-*
-*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-*
-*****************************************************************************
-*
-*    Note: This software is released under dual MIT and GPL licenses. A
-*    recipient may use this file under the terms of either the MIT license or
-*    GPL License. If you wish to use only one license not the other, you can
-*    indicate your decision by deleting one of the above license notices in your
-*    version of this file.
-*
-*****************************************************************************/
-
-
-#ifndef __gc_hal_resource_h_
-#define __gc_hal_resource_h_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __gc_hal_resource_h_ */
-
-
index 346dac9..1857b60 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 94a1d3e..415b564 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 996811d..37237e0 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 #   include "linux/types.h"
 #elif defined(UNDER_CE)
 #include <crtdefs.h>
+typedef signed char        int8_t;
+typedef short              int16_t;
+typedef int                int32_t;
+typedef long long          int64_t;
+typedef unsigned char      uint8_t;
+typedef unsigned short     uint16_t;
+typedef unsigned int       uint32_t;
+typedef unsigned long long uint64_t;
 #elif defined(_MSC_VER) && (_MSC_VER <= 1500)
 #include <crtdefs.h>
 #include "vadefs.h"
 #elif defined(__QNXNTO__)
 #define _QNX_SOURCE
-#include <stdlib.h>
 #include <stdint.h>
 #include <stddef.h>
 #else
@@ -244,6 +251,7 @@ typedef gctUINT32               gctTRACE;
 #define gcvMAXUINT64            0xffffffffffffffff
 #define gcvMINUINT64            0x0
 #define gcvMAXUINTPTR_T         (~(gctUINTPTR_T)0)
+#define gcvMAXSIZE_T            ((gctSIZE_T)(-1))
 
 typedef float                   gctFLOAT;
 typedef signed int              gctFIXED_POINT;
@@ -485,7 +493,6 @@ typedef enum _gceSTATUS
     gcvSTATUS_DEVICE                =   -27,
     gcvSTATUS_NOT_MULTI_PIPE_ALIGNED =   -28,
     gcvSTATUS_OUT_OF_SAMPLER         =   -29,
-    gcvSTATUS_CLOCK_ERROR           =   -30,
 
     /* Linker errors. */
     gcvSTATUS_GLOBAL_TYPE_MISMATCH              =   -1000,
@@ -833,6 +840,11 @@ gceSTATUS;
     gcmPTR2INT32(& (((struct s *) 0)->field)) \
 )
 
+#define __gcmOFFSETOF(type, field) \
+(\
+    gcmPTR2INT32(& (((type *) 0)->field)) \
+)
+
 /*******************************************************************************
 **
 **  gcmCONTAINEROF
@@ -847,7 +859,7 @@ gceSTATUS;
 */
 #define gcmCONTAINEROF(Pointer, Type, Member) \
 (\
-    (struct Type *)((gctUINTPTR_T)Pointer - gcmOFFSETOF(Type, Member)) \
+    (Type *)((gctUINTPTR_T)Pointer - __gcmOFFSETOF(Type, Member)) \
 )
 
 /*******************************************************************************
@@ -994,8 +1006,9 @@ typedef enum _gceTRACEMODE
     gcvTRACEMODE_NONE     = 0,
     gcvTRACEMODE_FULL     = 1,
     gcvTRACEMODE_LOGGER   = 2,
-    gcvTRACEMODE_PRE      = 3,
-    gcvTRACEMODE_POST     = 4,
+    gcvTRACEMODE_ALLZONE  = 3,
+    gcvTRACEMODE_PRE      = 4,
+    gcvTRACEMODE_POST     = 5,
 } gceTRACEMODE;
 
 typedef struct _gcsLISTHEAD * gcsLISTHEAD_PTR;
@@ -1006,6 +1019,106 @@ typedef struct _gcsLISTHEAD
 }
 gcsLISTHEAD;
 
+/*
+ * 'Patch' here means a mechanism to let kernel side modify user space reserved
+ * command buffer location, or something the like, during the command buffer
+ * commit.
+ *
+ * Reasons of using 'patch':
+ * 1. Some resources/states are managed globally only in kernel side, such as
+ *    MCFE semaphore, etc.
+ * 2. For the sake of security or optimization, like video memory address.
+ *
+ * Patches are arranged in arrays, each array has the same type. The 'patchArray'
+ * in 'gcsHAL_PATCH_LIST' pointers the concrete patch item array.
+ *
+ * NOTICE:
+ * Be aware of the order and values! Tables in gc_hal_user_buffer.c and
+ * gc_hal_kernel_command.c depend on this.
+ */
+/* The patch types. */
+enum _gceHAL_PATCH_TYPE
+{
+    gcvHAL_PATCH_VIDMEM_ADDRESS = 1,
+    gcvHAL_PATCH_MCFE_SEMAPHORE,
+    gcvHAL_PATCH_VIDMEM_TIMESTAMP,
+
+    /* Must be the last one for counting. */
+    gcvHAL_PATCH_TYPE_COUNT,
+};
+
+/* The patch array. */
+typedef struct _gcsHAL_PATCH_LIST
+{
+    /* Patch type. */
+    gctUINT32           type;
+
+    /* Patch item count. */
+    gctUINT32           count;
+
+    /*
+     * Pointer to the patch items.
+     *
+     * gcsHAL_PATCH_VIDMEM_ADDRESS * patchArray;
+     * gcsHAL_PATCH_MCFE_SEMAPHORE * patchArray;
+     * gcsHAL_PATCH_VIDMEM_TIMESTAMP * patchArray;
+     * ...
+     */
+    gctUINT64           patchArray;
+
+    /* struct _gcsHAL_PATCH_LIST * next; */
+    gctUINT64           next;
+}
+gcsHAL_PATCH_LIST;
+
+/*
+ * Patch a GPU address in the place (gcvHAL_PATCH_VIDMEM_ADDRESS).
+ * Size of a GPU address is always 32 bits.
+ */
+typedef struct _gcsHAL_PATCH_VIDMEM_ADDRESS
+{
+    /* Patch location in the command buffer. */
+    gctUINT32           location;
+
+    /* Handle of the video memory node. */
+    gctUINT32           node;
+
+    /* Address offset in the video memory node. */
+    gctUINT32           offset;
+}
+gcsHAL_PATCH_VIDMEM_ADDRESS;
+
+/*
+ * Patch a MCFE semaphore command in the place (gcvHAL_PATCH_MCFE_SEMAPHORE).
+ * Size of the semaphore command is fixed at _64_ bits!
+ */
+typedef struct _gcsHAL_PATCH_MCFE_SEMAPHORE
+{
+    /* Patch location in the command buffer. */
+    gctUINT32           location;
+
+    /* semaphore direction: 1 = Send, 0 = Wait. */
+    gctUINT32           sendSema;
+
+    /* Handle of the semaphore. */
+    gctUINT32           semaHandle;
+}
+gcsHAL_PATCH_MCFE_SEMAPHORE;
+
+/*
+ * Patch timestamp of given video memory node (gcvHAL_PATCH_VIDMEM_TIMESTAMP).
+ * Pure software-wise, not command relevant.
+ */
+typedef struct _gcsHAL_PATCH_VIDMEM_TIMESTAMP
+{
+    /* Handle of a video memory node. */
+    gctUINT32           handle;
+
+    gctUINT32           flag;
+}
+gcsHAL_PATCH_VIDMEM_TIMESTAMP;
+
+
 /*
     gcvFEATURE_DATABASE_DATE_MASK
 
index 660a8f1..a52915a 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 
 #define gcvVERSION_MAJOR        6
 
-#define gcvVERSION_MINOR        2
+#define gcvVERSION_MINOR        4
 
-#define gcvVERSION_PATCH        4
+#define gcvVERSION_PATCH        0
 
-#define gcvVERSION_BUILD     190076
+#define gcvVERSION_BUILD     203949
 
-#define gcvVERSION_STRING    "6.2.4.p4.190076"
+#define gcvVERSION_STRING    "6.4.0.beta.ea1.203949"
 
 #endif /* __gc_hal_version_h_ */
 
index 12d28b3..3188abd 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -61,7 +61,6 @@ extern "C" {
 #endif
 
 
-#include "gc_hal_rename.h"
 #include "gc_hal_types.h"
 #include "gc_hal_enum.h"
 #include "gc_hal_base.h"
@@ -289,27 +288,6 @@ typedef gctTHREADFUNCRESULT (gctTHREADFUNCTYPE * gctTHREADFUNC) (
     (address)\
 )
 
-/******************************************************************************\
-****************************** Kernel Debug Macro ******************************
-\******************************************************************************/
-
-/* Return the kernel logical pointer for the given physical one. */
-gceSTATUS
-gckOS_GetKernelLogical(
-    IN gckOS Os,
-    IN gctUINT32 Address,
-    OUT gctPOINTER * KernelPointer
-    );
-
-/* Return the kernel logical pointer for the given physical one. */
-gceSTATUS
-gckOS_GetKernelLogicalEx(
-    IN gckOS Os,
-    IN gceCORE Core,
-    IN gctUINT32 Address,
-    OUT gctPOINTER * KernelPointer
-    );
-
 /*----------------------------------------------------------------------------*/
 /*----------------------------- Semaphore Object -----------------------------*/
 
@@ -384,7 +362,6 @@ gckKERNEL_UnmapMemory(
 gceSTATUS
 gckVGKERNEL_Dispatch(
     IN gckKERNEL Kernel,
-    IN gctBOOL FromUser,
     IN OUT struct _gcsHAL_INTERFACE * Interface
     );
 
@@ -483,15 +460,6 @@ gckVGHARDWARE_SplitMemory(
     OUT gctUINT32 * Offset
     );
 
-/* Align size to tile boundary. */
-gceSTATUS
-gckVGHARDWARE_AlignToTile(
-    IN gckVGHARDWARE Hardware,
-    IN gceSURF_TYPE Type,
-    IN OUT gctUINT32_PTR Width,
-    IN OUT gctUINT32_PTR Height
-    );
-
 /* Convert logical address to hardware specific address. */
 gceSTATUS
 gckVGHARDWARE_ConvertLogical(
@@ -545,7 +513,7 @@ gckVGHARDWARE_ReadInterrupt(
 
 /* Power management. */
 gceSTATUS
-gckVGHARDWARE_SetPowerManagementState(
+gckVGHARDWARE_SetPowerState(
     IN gckVGHARDWARE Hardware,
     IN gceCHIPPOWERSTATE State
     );
@@ -557,9 +525,9 @@ gckVGHARDWARE_QueryPowerManagementState(
     );
 
 gceSTATUS
-gckVGHARDWARE_SetPowerManagement(
+gckVGHARDWARE_EnablePowerManagement(
     IN gckVGHARDWARE Hardware,
-    IN gctBOOL PowerManagement
+    IN gctBOOL Enable
     );
 
 gceSTATUS
index 8abb7e5..6bc1e19 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 36bf9c5..9a5bd4c 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -64,7 +64,6 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0)
 #include <linux/dma-direct.h>
 #endif
-
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 
@@ -217,9 +216,9 @@ _DmaGetSGT(
 
     gceSTATUS status = gcvSTATUS_OK;
     gctSIZE_T offset = Offset & ~PAGE_MASK; /* Offset to the first page */
-    gctINT skipPages = Offset >> PAGE_SHIFT;     /* skipped pages */
-    gctINT numPages = (PAGE_ALIGN(Offset + Bytes) >> PAGE_SHIFT) - skipPages;
-    gctINT i;
+    gctSIZE_T skipPages = Offset >> PAGE_SHIFT;     /* skipped pages */
+    gctSIZE_T numPages = (PAGE_ALIGN(Offset + Bytes) >> PAGE_SHIFT) - skipPages;
+    gctSIZE_T i;
 
     gcmkASSERT(Offset + Bytes <= Mdl->numPages << PAGE_SHIFT);
 
@@ -321,7 +320,7 @@ _DmaMmap(
             pgprot_writecombine(vma->vm_page_prot)) < 0)
 #else
     /* map kernel memory to user space.. */
-    if (dma_mmap_writecombine(gcvNULL,
+    if (dma_mmap_writecombine(galcore_device,
             vma,
             (gctINT8_PTR)mdlPriv->kvaddr + (skipPages << PAGE_SHIFT),
             mdlPriv->dmaHandle + (skipPages << PAGE_SHIFT),
@@ -463,11 +462,13 @@ static gceSTATUS
 _DmaMapKernel(
     IN gckALLOCATOR Allocator,
     IN PLINUX_MDL Mdl,
+    IN gctSIZE_T Offset,
+    IN gctSIZE_T Bytes,
     OUT gctPOINTER *Logical
     )
 {
     struct mdl_dma_priv *mdlPriv=(struct mdl_dma_priv *)Mdl->priv;
-    *Logical =mdlPriv->kvaddr;
+    *Logical = (uint8_t *)mdlPriv->kvaddr + Offset;
     return gcvSTATUS_OK;
 }
 
@@ -487,7 +488,7 @@ _DmaCache(
     IN PLINUX_MDL Mdl,
     IN gctSIZE_T Offset,
     IN gctPOINTER Logical,
-    IN gctUINT32 Bytes,
+    IN gctSIZE_T Bytes,
     IN gceCACHEOPERATION Operation
     )
 {
index 6f37daf..97ab698 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -370,7 +370,11 @@ _DmabufMapUser(
     userLogical += buf_desc->sgt->sgl->offset;
 
     /* To make sure the mapping is created. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
+    if (access_ok(userLogical, 4))
+#else
     if (access_ok(VERIFY_READ, userLogical, 4))
+#endif
     {
         uint32_t mem;
         get_user(mem, (uint32_t *)userLogical);
@@ -382,7 +386,7 @@ _DmabufMapUser(
     MdlMap->cacheable = Cacheable;
 
 OnError:
-    if (gcmIS_ERROR(status) && userLogical)
+    if (gcmIS_ERROR(status) && MdlMap->vmaAddr)
     {
         _DmabufUnmapUser(Allocator, Mdl, MdlMap, Mdl->numPages << PAGE_SHIFT);
     }
@@ -393,6 +397,8 @@ static gceSTATUS
 _DmabufMapKernel(
     IN gckALLOCATOR Allocator,
     IN PLINUX_MDL Mdl,
+    IN gctSIZE_T Offset,
+    IN gctSIZE_T Bytes,
     OUT gctPOINTER *Logical
     )
 {
@@ -418,7 +424,7 @@ _DmabufCache(
     IN PLINUX_MDL Mdl,
     IN gctSIZE_T Offset,
     IN gctPOINTER Logical,
-    IN gctUINT32 Bytes,
+    IN gctSIZE_T Bytes,
     IN gceCACHEOPERATION Operation
     )
 {
index d678990..063277c 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -101,6 +101,10 @@ struct gfp_mdl_priv
         {
             /* Pointer to a array of pointers to page. */
             struct page **nonContiguousPages;
+
+            struct page **Pages1M;
+            int numPages1M;
+            int *isExact;
             struct sg_table sgt;
         };
     };
@@ -166,12 +170,12 @@ _GFPAllocatorDebugfsCleanup(
 static void
 _NonContiguousFree(
     IN struct page ** Pages,
-    IN gctUINT32 NumPages
+    IN gctSIZE_T NumPages
     )
 {
-    gctINT i;
+    gctSIZE_T i;
 
-    gcmkHEADER_ARG("Pages=%p, NumPages=%u", Pages, NumPages);
+    gcmkHEADER_ARG("Pages=%p, NumPages=%zx", Pages, NumPages);
 
     gcmkASSERT(Pages != gcvNULL);
 
@@ -194,17 +198,19 @@ _NonContiguousFree(
 
 static struct page **
 _NonContiguousAlloc(
-    IN gctUINT32 NumPages,
+    IN gctSIZE_T NumPages,
     IN gctUINT32 Gfp
     )
 {
     struct page ** pages;
     struct page *p;
-    gctINT i, size;
+    gctSIZE_T i, size;
 
-    gcmkHEADER_ARG("NumPages=%u", NumPages);
+    gcmkHEADER_ARG("NumPages=%zx", NumPages);
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
+    if (NumPages > totalram_pages())
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
     if (NumPages > totalram_pages)
 #else
     if (NumPages > num_physpages)
@@ -271,6 +277,153 @@ _NonContiguousAlloc(
     return pages;
 }
 
+static void
+_NonContiguous1MPagesFree(
+    IN struct gfp_mdl_priv *MdlPriv,
+    IN gctUINT32 NumPages1M
+    )
+{
+    gctINT i;
+
+    for (i = 0; i < NumPages1M && MdlPriv->Pages1M[i]; i++)
+    {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+        if (MdlPriv->isExact[i] == gcvTRUE)
+        {
+            free_pages_exact(page_address(MdlPriv->Pages1M[i]), gcd1M_PAGE_SIZE);
+        }
+        else
+#endif
+        {
+            __free_pages(MdlPriv->Pages1M[i], get_order(gcd1M_PAGE_SIZE));
+        }
+    }
+
+    if (is_vmalloc_addr(MdlPriv->Pages1M))
+    {
+        vfree(MdlPriv->Pages1M);
+    }
+    else
+    {
+        kfree(MdlPriv->Pages1M);
+    }
+
+    if (is_vmalloc_addr(MdlPriv->isExact))
+    {
+        vfree(MdlPriv->isExact);
+    }
+    else
+    {
+        kfree(MdlPriv->isExact);
+    }
+
+    if (is_vmalloc_addr(MdlPriv->nonContiguousPages))
+    {
+        vfree(MdlPriv->nonContiguousPages);
+    }
+    else
+    {
+        kfree(MdlPriv->nonContiguousPages);
+    }
+}
+
+static struct page **
+_NonContiguous1MPagesAlloc(
+    IN struct gfp_mdl_priv *MdlPriv,
+    IN gctSIZE_T *NumPages,
+    IN gctUINT32 Gfp
+    )
+{
+    size_t numPages1M, num, size;
+    struct page **pages;
+    struct page *page;
+    void *addr = NULL;
+    gctINT i, j;
+
+    numPages1M = ((*NumPages << PAGE_SHIFT) + (gcd1M_PAGE_SIZE - 1)) >> gcd1M_PAGE_SHIFT;
+    MdlPriv->numPages1M = numPages1M;
+
+    *NumPages = (numPages1M << gcd1M_PAGE_SHIFT) >> PAGE_SHIFT;
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 32)
+    if (*NumPages > totalram_pages)
+#else
+    if (*NumPages > num_physpages)
+#endif
+    {
+        return gcvNULL;
+    }
+
+    num = gcd1M_PAGE_SIZE / PAGE_SIZE;
+
+    size = numPages1M * sizeof(struct page *);
+    MdlPriv->Pages1M = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+    if (!MdlPriv->Pages1M)
+    {
+        MdlPriv->Pages1M = vmalloc(size);
+
+        if (!MdlPriv->Pages1M)
+        {
+            return gcvNULL;
+        }
+    }
+
+    size = numPages1M * sizeof(int);
+    MdlPriv->isExact = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+    if (!MdlPriv->isExact)
+    {
+        MdlPriv->isExact = vmalloc(size);
+        return gcvNULL;
+    }
+
+    size = *NumPages * sizeof(struct page *);
+    pages = kmalloc(size, GFP_KERNEL | gcdNOWARN);
+    if (!pages)
+    {
+        pages = vmalloc(size);
+        return gcvNULL;
+    }
+
+    for (i = 0; i < numPages1M; i++)
+    {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+        addr = alloc_pages_exact(gcd1M_PAGE_SIZE, (Gfp & ~__GFP_HIGHMEM) | __GFP_NORETRY);
+
+        MdlPriv->Pages1M[i] = addr ? virt_to_page(addr) : gcvNULL;
+        if (MdlPriv->Pages1M[i])
+        {
+            MdlPriv->isExact[i] = gcvTRUE;
+        }
+#endif
+
+        if (MdlPriv->Pages1M[i] == gcvNULL)
+        {
+            int order = get_order(gcd1M_PAGE_SIZE);
+
+            if (order >= MAX_ORDER)
+            {
+                return gcvNULL;
+            }
+
+            MdlPriv->Pages1M[i] = alloc_pages(Gfp, order);
+        }
+
+        if (MdlPriv->Pages1M[i] == gcvNULL)
+        {
+            _NonContiguous1MPagesFree(MdlPriv, i);
+            return gcvNULL;
+        }
+
+        for (j = 0; j < num; j++)
+        {
+            page = nth_page(MdlPriv->Pages1M[i], j);
+            pages[i * num + j] = page;
+        }
+    }
+
+    return pages;
+}
+
 /***************************************************************************\
 ************************ GFP Allocator **********************************
 \***************************************************************************/
@@ -283,7 +436,7 @@ _GFPAlloc(
     )
 {
     gceSTATUS status;
-    gctUINT i;
+    gctSIZE_T i = 0;
     gctBOOL contiguous = Flags & gcvALLOC_FLAG_CONTIGUOUS;
     u32 gfp = (contiguous ? (__GFP_HIGH | __GFP_ATOMIC) : GFP_KERNEL) | __GFP_HIGHMEM | gcdNOWARN;
 
@@ -332,6 +485,15 @@ _GFPAlloc(
 
 #endif
 
+    if ((Flags & gcvALLOC_FLAG_NON_CONTIGUOUS) && (Flags & gcvALLOC_FLAG_1M_PAGES))
+    {
+        Mdl->pageUnit1M = gcvTRUE;
+    }
+    else
+    {
+        Mdl->pageUnit1M = gcvFALSE;
+    }
+
     if (contiguous)
     {
         size_t bytes = NumPages << PAGE_SHIFT;
@@ -360,7 +522,6 @@ _GFPAlloc(
             }
 
             mdlPriv->contiguousPages = alloc_pages(gfp, order);
-
         }
 
         if (mdlPriv->contiguousPages == gcvNULL)
@@ -372,7 +533,7 @@ _GFPAlloc(
                 mdlPriv->contiguousPages, 0, NumPages * PAGE_SIZE,
                 DMA_FROM_DEVICE);
 
-        if (!mdlPriv->dma_addr)
+        if (dma_mapping_error(galcore_device, mdlPriv->dma_addr))
         {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
             if (mdlPriv->exact)
@@ -400,7 +561,14 @@ _GFPAlloc(
     }
     else
     {
-        mdlPriv->nonContiguousPages = _NonContiguousAlloc(NumPages, gfp);
+        if (Mdl->pageUnit1M)
+        {
+            mdlPriv->nonContiguousPages = _NonContiguous1MPagesAlloc(mdlPriv, &NumPages, gfp);
+        }
+        else
+        {
+            mdlPriv->nonContiguousPages = _NonContiguousAlloc(NumPages, gfp);
+        }
 
         if (mdlPriv->nonContiguousPages == gcvNULL)
         {
@@ -422,7 +590,15 @@ _GFPAlloc(
 #endif
         if (result < 0)
         {
-            _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+            if (Mdl->pageUnit1M)
+            {
+                _NonContiguous1MPagesFree(mdlPriv, mdlPriv->numPages1M);
+            }
+            else
+            {
+                _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+            }
+
             gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
         }
 
@@ -431,7 +607,14 @@ _GFPAlloc(
 
         if (result != mdlPriv->sgt.nents)
         {
-            _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+            if (Mdl->pageUnit1M)
+            {
+                _NonContiguous1MPagesFree(mdlPriv, mdlPriv->numPages1M);
+            }
+            else
+            {
+                _NonContiguousFree(mdlPriv->nonContiguousPages, NumPages);
+            }
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
     && (defined (ARCH_HAS_SG_CHAIN) || defined (CONFIG_ARCH_HAS_SG_CHAIN))
@@ -486,6 +669,7 @@ _GFPAlloc(
     atomic_add(high, &priv->high);
 
     Mdl->priv = mdlPriv;
+    Mdl->numPages = NumPages;
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
@@ -517,9 +701,9 @@ _GFPGetSGT(
 
     gceSTATUS status = gcvSTATUS_OK;
     gctSIZE_T offset = Offset & ~PAGE_MASK; /* Offset to the first page */
-    gctINT skipPages = Offset >> PAGE_SHIFT;     /* skipped pages */
-    gctINT numPages = (PAGE_ALIGN(Offset + Bytes) >> PAGE_SHIFT) - skipPages;
-    gctINT i;
+    gctSIZE_T skipPages = Offset >> PAGE_SHIFT;     /* skipped pages */
+    gctSIZE_T numPages = (PAGE_ALIGN(Offset + Bytes) >> PAGE_SHIFT) - skipPages;
+    gctSIZE_T i;
 
     gcmkASSERT(Offset + Bytes <= Mdl->numPages << PAGE_SHIFT);
 
@@ -577,7 +761,7 @@ _GFPFree(
     IN OUT PLINUX_MDL Mdl
     )
 {
-    gctINT i;
+    gctSIZE_T i;
     struct page * page;
     struct gfp_alloc *priv = (struct gfp_alloc *)Allocator->privateData;
     struct gfp_mdl_priv *mdlPriv = Mdl->priv;
@@ -654,7 +838,14 @@ _GFPFree(
         set_pages_array_wb(mdlPriv->nonContiguousPages, Mdl->numPages);
 #endif
 
-        _NonContiguousFree(mdlPriv->nonContiguousPages, Mdl->numPages);
+        if (Mdl->pageUnit1M)
+        {
+            _NonContiguous1MPagesFree(mdlPriv, mdlPriv->numPages1M);
+        }
+        else
+        {
+            _NonContiguousFree(mdlPriv->nonContiguousPages, Mdl->numPages);
+        }
     }
 
     kfree(Mdl->priv);
@@ -716,7 +907,7 @@ _GFPMmap(
     }
     else
     {
-        gctUINT i;
+        gctSIZE_T i;
         unsigned long start = vma->vm_start;
 
         for (i = 0; i < numPages; ++i)
@@ -881,20 +1072,30 @@ static gceSTATUS
 _GFPMapKernel(
     IN gckALLOCATOR Allocator,
     IN PLINUX_MDL Mdl,
+    IN gctSIZE_T Offset,
+    IN gctSIZE_T Bytes,
     OUT gctPOINTER *Logical
     )
 {
     void *addr = 0;
-    gctINT numPages = Mdl->numPages;
+    gctSIZE_T numPages = Mdl->numPages;
     struct gfp_mdl_priv *mdlPriv = Mdl->priv;
-
+    unsigned long pgoff = (Offset >> PAGE_SHIFT);
     struct page ** pages;
     gctBOOL free = gcvFALSE;
     pgprot_t pgprot;
-    gctINT i;
+
+    if (Offset + Bytes > (numPages << PAGE_SHIFT))
+    {
+        return gcvSTATUS_INVALID_ARGUMENT;
+    }
+
+    numPages = ((Offset & ~PAGE_MASK) + Bytes + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 
     if (Mdl->contiguous)
     {
+        gctSIZE_T i;
+
         pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
 
         if (!pages)
@@ -904,14 +1105,14 @@ _GFPMapKernel(
 
         for (i = 0; i < numPages; i++)
         {
-            pages[i] = nth_page(mdlPriv->contiguousPages, i);
+            pages[i] = nth_page(mdlPriv->contiguousPages, i + pgoff);
         }
 
         free = gcvTRUE;
     }
     else
     {
-        pages = mdlPriv->nonContiguousPages;
+        pages = &mdlPriv->nonContiguousPages[pgoff];
     }
 
     /* ioremap() can't work on system memory since 2.6.38. */
@@ -937,7 +1138,8 @@ _GFPMapKernel(
 
     if (addr)
     {
-        *Logical = addr;
+        /* Append offset in page. */
+        *Logical = (uint8_t *)addr + (Offset & ~PAGE_MASK);
         return gcvSTATUS_OK;
     }
     else
@@ -953,7 +1155,7 @@ _GFPUnmapKernel(
     IN gctPOINTER Logical
     )
 {
-    vunmap(Logical);
+    vunmap((void *)((uintptr_t)Logical & PAGE_MASK));
 
     return gcvSTATUS_OK;
 }
@@ -964,12 +1166,13 @@ _GFPCache(
     IN PLINUX_MDL Mdl,
     IN gctSIZE_T Offset,
     IN gctPOINTER Logical,
-    IN gctUINT32 Bytes,
+    IN gctSIZE_T Bytes,
     IN gceCACHEOPERATION Operation
     )
 {
     struct gfp_mdl_priv *mdlPriv = Mdl->priv;
     enum dma_data_direction dir;
+    gctINT numPages = GetPageCount(Bytes, Offset);
 
     switch (Operation)
     {
@@ -979,7 +1182,7 @@ _GFPCache(
         if (mdlPriv->contiguous)
         {
             dma_sync_single_for_device(galcore_device,
-                    mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+                    mdlPriv->dma_addr, numPages << PAGE_SHIFT, dir);
         }
         else
         {
@@ -994,7 +1197,7 @@ _GFPCache(
         if (mdlPriv->contiguous)
         {
             dma_sync_single_for_device(galcore_device,
-                    mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+                    mdlPriv->dma_addr, numPages << PAGE_SHIFT, dir);
         }
         else
         {
@@ -1007,7 +1210,7 @@ _GFPCache(
         if (mdlPriv->contiguous)
         {
             dma_sync_single_for_cpu(galcore_device,
-                    mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+                    mdlPriv->dma_addr, numPages << PAGE_SHIFT, dir);
         }
         else
         {
@@ -1022,7 +1225,7 @@ _GFPCache(
         if (mdlPriv->contiguous)
         {
             dma_sync_single_for_cpu(galcore_device,
-                    mdlPriv->dma_addr, Mdl->numPages << PAGE_SHIFT, dir);
+                    mdlPriv->dma_addr, numPages << PAGE_SHIFT, dir);
         }
         else
         {
@@ -1133,6 +1336,7 @@ _GFPAlloctorInit(
 #if defined(CONFIG_ZONE_DMA32) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
                           | gcvALLOC_FLAG_4GB_ADDR
 #endif
+                          | gcvALLOC_FLAG_1M_PAGES
                           ;
 
 #if defined(gcdEMULATE_SECURE_ALLOCATOR)
index 0b35e3d..5e390db 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -144,6 +144,17 @@ reserved_mem_debugfs_cleanup(
     gckDEBUGFS_DIR_Deinit(&Allocator->debugfsDir);
 }
 
+static gceSTATUS
+reserved_mem_alloc(
+    IN gckALLOCATOR Allocator,
+    INOUT PLINUX_MDL Mdl,
+    IN gctSIZE_T NumPages,
+    IN gctUINT32 Flags
+    )
+{
+    return gcvSTATUS_NOT_SUPPORTED;
+}
+
 static gceSTATUS
 reserved_mem_attach(
     IN gckALLOCATOR Allocator,
@@ -155,6 +166,11 @@ reserved_mem_attach(
     struct reserved_mem *res;
     struct resource *region = NULL;
 
+    if (Desc == gcvNULL)
+    {
+        return gcvSTATUS_INVALID_ARGUMENT;
+    }
+
     res = kzalloc(sizeof(struct reserved_mem), GFP_KERNEL | gcdNOWARN);
 
     if (!res)
@@ -163,7 +179,7 @@ reserved_mem_attach(
     res->start = Desc->reservedMem.start;
     res->size  = Desc->reservedMem.size;
     strncpy(res->name, Desc->reservedMem.name, sizeof(res->name)-1);
-    res->release = 1;
+    res->release = 0;
 
     if (!Desc->reservedMem.requested)
     {
@@ -187,6 +203,11 @@ reserved_mem_attach(
 
     Mdl->priv = res;
 
+    if (res->start < 0xFFFFFFFF)
+    {
+        Allocator->capability |= gcvALLOC_FLAG_4GB_ADDR;
+    }
+
     return gcvSTATUS_OK;
 }
 
@@ -263,7 +284,7 @@ reserved_mem_unmap_user(
     if (unlikely(!current->mm))
         return;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
     if (vm_munmap((unsigned long)MdlMap->vmaAddr, (unsigned long)Size) < 0)
     {
         printk("%s: vm_munmap failed\n", __func__);
@@ -356,19 +377,25 @@ static gceSTATUS
 reserved_mem_map_kernel(
     IN gckALLOCATOR Allocator,
     IN PLINUX_MDL Mdl,
+    IN gctSIZE_T Offset,
+    IN gctSIZE_T Bytes,
     OUT gctPOINTER *Logical
     )
 {
     struct reserved_mem *res = Mdl->priv;
     void *vaddr;
 
-    /* Should never run here now. */
+    if (Offset + Bytes > res->size)
+    {
+        return gcvSTATUS_INVALID_ARGUMENT;
+    }
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)
-    vaddr = memremap(res->start, res->size, MEMREMAP_WC);
+    vaddr = memremap(res->start + Offset, Bytes, MEMREMAP_WC);
 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
-    vaddr = memremap(res->start, res->size, MEMREMAP_WT);
+    vaddr = memremap(res->start + Offset, Bytes, MEMREMAP_WT);
 #else
-    vaddr = ioremap_nocache(res->start, res->size);
+    vaddr = ioremap_nocache(res->start + Offset, Bytes);
 #endif
 
     if (!vaddr)
@@ -401,7 +428,7 @@ reserved_mem_cache_op(
     IN PLINUX_MDL Mdl,
     IN gctSIZE_T Offset,
     IN gctPOINTER Logical,
-    IN gctUINT32 Bytes,
+    IN gctSIZE_T Bytes,
     IN gceCACHEOPERATION Operation
     )
 {
@@ -452,7 +479,7 @@ reserved_mem_dtor(
 
 /* GFP allocator operations. */
 static gcsALLOCATOR_OPERATIONS reserved_mem_ops = {
-    .Alloc              = NULL,
+    .Alloc              = reserved_mem_alloc,
     .Attach             = reserved_mem_attach,
     .Free               = reserved_mem_detach,
     .Mmap               = reserved_mem_mmap,
@@ -495,7 +522,9 @@ _ReservedMemoryAllocatorInit(
 
     reserved_mem_debugfs_init(allocator, Parent);
 
-    allocator->capability = gcvALLOC_FLAG_LINUX_RESERVED_MEM;
+    allocator->capability = gcvALLOC_FLAG_LINUX_RESERVED_MEM
+                          | gcvALLOC_FLAG_CONTIGUOUS
+                          | gcvALLOC_FLAG_CPU_ACCESS;
 
     *Allocator = allocator;
 
index 5759eff..96e3a88 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -59,6 +59,7 @@
 
 #include <linux/slab.h>
 #include <linux/pagemap.h>
+#include <linux/cache.h>
 
 #define _GC_OBJ_ZONE gcvZONE_ALLOCATOR
 
@@ -130,6 +131,12 @@ static int import_page_map(struct um_desc *um,
     int result;
     struct page **pages;
 
+    if ((addr & (cache_line_size() - 1)) || (size & (cache_line_size() - 1)))
+    {
+        /* Not cpu cacheline size aligned, can not support. */
+        return -EINVAL;
+    }
+
     pages = kzalloc(page_count * sizeof(void *), GFP_KERNEL | gcdNOWARN);
     if (!pages)
         return -ENOMEM;
@@ -201,6 +208,8 @@ static int import_page_map(struct um_desc *um,
         goto error;
     }
 
+    dma_sync_sg_for_cpu(galcore_device, um->sgt.sgl, um->sgt.nents, DMA_FROM_DEVICE);
+
     um->type = UM_PAGE_MAP;
     um->pages = pages;
 
@@ -265,7 +274,15 @@ static int import_pfn_map(struct um_desc *um,
         if (pgd_none(*pgd) || pgd_bad(*pgd))
             goto err;
 
+#if (defined(CONFIG_CPU_CSKYV2) || defined(CONFIG_X86)) \
+    && LINUX_VERSION_CODE >= KERNEL_VERSION (4,12,0)
+        pud = pud_offset((p4d_t*)pgd, addr);
+#elif (defined(CONFIG_CPU_CSKYV2)) \
+    && LINUX_VERSION_CODE >= KERNEL_VERSION (4,11,0)
+        pud = pud_offset((p4d_t*)pgd, addr);
+#else
         pud = pud_offset(pgd, addr);
+#endif
         if (pud_none(*pud) || pud_bad(*pud))
             goto err;
 
@@ -330,7 +347,7 @@ static gceSTATUS
 _Import(
     IN gckOS Os,
     IN gctPOINTER Memory,
-    IN gctUINT32 Physical,
+    IN gctPHYS_ADDR_T Physical,
     IN gctSIZE_T Size,
     IN struct um_desc * UserMemory
     )
@@ -344,11 +361,11 @@ _Import(
     gctSIZE_T extraPage;
     gctSIZE_T pageCount, i;
 
-    gcmkHEADER_ARG("Os=0x%p Memory=%p Physical=0x%x Size=%lu", Os, Memory, Physical, Size);
+    gcmkHEADER_ARG("Os=%p Memory=%p Physical=0x%llx Size=%lu", Os, Memory, Physical, Size);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Memory != gcvNULL || Physical != ~0U);
+    gcmkVERIFY_ARGUMENT(Memory != gcvNULL || Physical != ~0ULL);
     gcmkVERIFY_ARGUMENT(Size > 0);
 
     memory = (unsigned long)Memory;
@@ -385,17 +402,11 @@ _Import(
 
         for (i = 0; i < pageCount; i++)
         {
-            u32 data;
+            u32 data = 0;
 
             get_user(data, (u32 *)vaddr);
             put_user(data, (u32 *)vaddr);
             vaddr += PAGE_SIZE;
-
-            /* Fix QM crash with test_buffers */
-            if (vaddr > memory + Size - 4)
-            {
-                vaddr = memory + Size - 4;
-            }
         }
 
         vma = find_vma(current->mm, memory);
@@ -469,7 +480,7 @@ _Import(
 
         if (Physical != gcvINVALID_PHYSICAL_ADDRESS)
         {
-            if(Physical >0xFFFFFFFFu || Physical + Size > 0xFFFFFFFFu )
+            if(Physical > 0xFFFFFFFFu || Physical + Size > 0xFFFFFFFFu )
             {
                 gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
             }
@@ -576,7 +587,7 @@ static void release_page_map(struct um_desc *um)
 {
     int i;
 
-    dma_unmap_sg(galcore_device, um->sgt.sgl, um->sgt.nents, DMA_TO_DEVICE);
+    dma_unmap_sg(galcore_device, um->sgt.sgl, um->sgt.nents, DMA_FROM_DEVICE);
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION (3,6,0) \
     && (defined(ARCH_HAS_SG_CHAIN) || defined(CONFIG_ARCH_HAS_SG_CHAIN))
@@ -687,6 +698,8 @@ static gceSTATUS
 _UserMemoryMapKernel(
     IN gckALLOCATOR Allocator,
     IN PLINUX_MDL Mdl,
+    IN gctSIZE_T Offset,
+    IN gctSIZE_T Bytes,
     OUT gctPOINTER *Logical
     )
 {
@@ -711,7 +724,7 @@ _UserMemoryCache(
     IN PLINUX_MDL Mdl,
     IN gctSIZE_T Offset,
     IN gctPOINTER Logical,
-    IN gctUINT32 Bytes,
+    IN gctSIZE_T Bytes,
     IN gceCACHEOPERATION Operation
     )
 {
@@ -784,13 +797,13 @@ _UserMemoryPhysical(
         switch (userMemory->type)
         {
         case UM_PHYSICAL_MAP:
-            *Physical = userMemory->physical + index * PAGE_SIZE;
+            *Physical = userMemory->physical + (gctPHYS_ADDR_T)index * PAGE_SIZE;
             break;
         case UM_PAGE_MAP:
             *Physical = page_to_phys(userMemory->pages[index]);
             break;
         case UM_PFN_MAP:
-            *Physical = userMemory->pfns[index] << PAGE_SHIFT;
+            *Physical = (gctPHYS_ADDR_T)userMemory->pfns[index] << PAGE_SHIFT;
             break;
         }
     }
index 69d4afd..ab28fa8 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index dfb4325..5a450fe 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -63,7 +63,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,19,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,16,0)
 #include <linux/dma-direct.h>
 #endif
 
@@ -453,11 +453,13 @@ static gceSTATUS
 _CMAMapKernel(
     IN gckALLOCATOR Allocator,
     IN PLINUX_MDL Mdl,
+    IN gctSIZE_T Offset,
+    IN gctSIZE_T Bytes,
     OUT gctPOINTER *Logical
     )
 {
     struct mdl_cma_priv *mdl_priv=(struct mdl_cma_priv *)Mdl->priv;
-    *Logical =mdl_priv->kvaddr;
+    *Logical = (uint8_t *)mdl_priv->kvaddr + Offset;
     return gcvSTATUS_OK;
 }
 
@@ -477,7 +479,7 @@ _CMACache(
     IN PLINUX_MDL Mdl,
     IN gctSIZE_T Offset,
     IN gctPOINTER Logical,
-    IN gctUINT32 Bytes,
+    IN gctSIZE_T Bytes,
     IN gceCACHEOPERATION Operation
     )
 {
@@ -577,7 +579,6 @@ _CMAFSLAlloctorInit(
                           | gcvALLOC_FLAG_4GB_ADDR
 #endif
                           ;
-
 #if defined(CONFIG_ARM64)
     Os->allocatorLimitMarker = (Os->device->baseAddress + totalram_pages * PAGE_SIZE) > 0x100000000;
 #else
index 0eee490..3a1cb1e 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 4d103f1..f0b96f7 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -241,6 +241,8 @@ typedef struct _gcsALLOCATOR_OPERATIONS
     (*MapKernel)(
         IN gckALLOCATOR Allocator,
         IN PLINUX_MDL Mdl,
+        IN gctSIZE_T Offset,
+        IN gctSIZE_T Bytes,
         OUT gctPOINTER *Logical
         );
 
@@ -285,12 +287,12 @@ typedef struct _gcsALLOCATOR_OPERATIONS
     **      PLINUX_MDL Mdl
     **          Pointer to a Mdl object.
     **
-    **      gctSIZE_T Offset
-    **          Offset to this memory block
-    **
     **      gctPOINTER Logical
     **          Logical address, could be user address or kernel address
     **
+    **      gctSIZE_T Offset
+    **          Physical address.
+    **
     **      gctUINT32 Bytes
     **          Size of memory region.
     **
@@ -307,7 +309,7 @@ typedef struct _gcsALLOCATOR_OPERATIONS
         IN PLINUX_MDL Mdl,
         IN gctSIZE_T Offset,
         IN gctPOINTER Logical,
-        IN gctUINT32 Bytes,
+        IN gctSIZE_T Bytes,
         IN gceCACHEOPERATION Operation
         );
 
index ee80046..d607ee2 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -85,13 +85,13 @@ typedef va_list gctARGUMENTS;
     va_arg(Arguments, Type)
 
 #define gcmkDECLARE_MUTEX(__mutex__) \
-    DEFINE_MUTEX(__mutex__); \
+    DEFINE_MUTEX(__mutex__)
 
 #define gcmkMUTEX_LOCK(__mutex__) \
-    mutex_lock(&__mutex__);
+    mutex_lock(&__mutex__)
 
 #define gcmkMUTEX_UNLOCK(__mutex__) \
-    mutex_unlock(&__mutex__);
+    mutex_unlock(&__mutex__)
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
 #   define gcmkGETPROCESSID() \
@@ -110,23 +110,48 @@ typedef va_list gctARGUMENTS;
 #endif
 
 #define gcmkOUTPUT_STRING(String) \
-    if (gckDEBUGFS_IsEnabled()) \
+    printk("%s", String); \
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
+#define gcmkDUMP_STRING(Os, String) \
+    do \
     { \
-        while (-ERESTARTSYS == gckDEBUGFS_Print(String)); \
+        mutex_lock(&Os->dumpFilpMutex); \
+        if (Os->dumpTarget == 0) \
+        { \
+            printk("%s", String); \
+        } \
+        else if (Os->dumpFilp && Os->dumpTarget == 1) \
+        { \
+            kernel_write(Os->dumpFilp, String, strlen(String), &Os->dumpFilp->f_pos); \
+        } \
+        mutex_unlock(&Os->dumpFilpMutex); \
     } \
-    else \
+    while (0)
+#else
+#define gcmkDUMP_STRING(Os, String) \
+    do \
     { \
-        printk(String); \
-    }
-
-#define gcmkSPRINTF(Destination, Size, Message, Value) \
-    snprintf(Destination, Size, Message, Value)
-
-#define gcmkSPRINTF2(Destination, Size, Message, Value1, Value2) \
-    snprintf(Destination, Size, Message, Value1, Value2)
+        mutex_lock(&Os->dumpFilpMutex); \
+        if (Os->dumpTarget == 0) \
+        { \
+            printk("%s", String); \
+        } \
+        else if (Os->dumpFilp && Os->dumpTarget == 1) \
+        { \
+            mm_segment_t oldFs; \
+            oldFs = get_fs(); \
+            set_fs(KERNEL_DS); \
+            vfs_write(Os->dumpFilp, String, strlen(String), &Os->dumpFilp->f_pos); \
+            set_fs(oldFs); \
+        } \
+        mutex_unlock(&Os->dumpFilpMutex); \
+    } \
+    while (0)
+#endif
 
-#define gcmkSPRINTF3(Destination, Size, Message, Value1, Value2, Value3) \
-    snprintf(Destination, Size, Message, Value1, Value2, Value3)
+#define gcmkSPRINTF(Destination, Size, ...) \
+    snprintf(Destination, Size, __VA_ARGS__)
 
 #define gcmkVSPRINTF(Destination, Size, Message, Arguments) \
     vsnprintf(Destination, Size, Message, *((va_list*)Arguments))
index 885eec6..7bc22a3 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 #include "gc_hal_kernel.h"
 #include "gc_hal_kernel_debug.h"
 
-/*
-   Prequsite:
 
-   1) Debugfs feature must be enabled in the kernel.
-       1.a) You can enable this, in the compilation of the uImage, all you have to do is, In the "make menuconfig" part,
-       you have to enable the debugfs in the kernel hacking part of the menu.
-
-   HOW TO USE:
-   1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
-   This gives a circular buffer of 10 MB
-
-   2)Usually after inserting the driver, the debug file system is mounted under /sys/kernel/debug/
-
-        2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
-
-   3) To read what is being printed in the debugfs file system:
-        Ex : cat /sys/kernel/debug/gc/galcore_trace
-
-   4)To write into the debug file system from user side :
-        Ex: echo "hello" > cat /sys/kernel/debug/gc/galcore_trace
-
-   5)To write into debugfs from kernel side, Use the function called gckDEBUGFS_Print
-
-   How to Get Video Memory Usage:
-   1) Select a process whose video memory usage can be dump, no need to reset it until <pid> is needed to be change.
-        echo <pid>  > /sys/kernel/debug/gc/vidmem
-
-   2) Get video memory usage.
-        cat /sys/kernel/debug/gc/vidmem
-
-   USECASE Kernel Dump:
-
-   1) Go to /hal/inc/gc_hal_options.h, and enable the following flags:
-        - #   define gcdDUMP                              1
-        - #   define gcdDUMP_IN_KERNEL          1
-        - #   define gcdDUMP_COMMAND          1
-
-    2) Go to /hal/kernel/gc_hal_kernel_command.c and disable the following flag
-        -#define gcdSIMPLE_COMMAND_DUMP  0
-
-    3) Compile the driver
-    4) insmod it with the logFileSize option
-    5) Run an application
-    6) You can get the dump by cat /sys/kernel/debug/gpu/galcore_trace
-
- */
-
-/**/
-typedef va_list gctDBGARGS ;
-#define gcmkARGS_START(argument, pointer)   va_start(argument, pointer)
-#define gcmkARGS_END(argument)                        va_end(argument)
-
-#define gcmkDEBUGFS_PRINT(ArgumentSize, Message) \
-  { \
-      gctDBGARGS __arguments__; \
-      gcmkARGS_START(__arguments__, Message); \
-      _debugfs_res = _DebugFSPrint(ArgumentSize, Message, &__arguments__);\
-      gcmkARGS_END(__arguments__); \
-  }
-
-
-static DEFINE_SPINLOCK(traceLock);
-
-/* Debug File System Node Struct. */
-struct _gcsDEBUGFS_Node
-{
-    /*wait queues for read and write operations*/
-#if defined(DECLARE_WAIT_QUEUE_HEAD)
-    wait_queue_head_t read_q , write_q ;
-#else
-    struct wait_queue *read_q , *write_q ;
-#endif
-    struct dentry *parent ; /*parent directory*/
-    struct dentry *filen ; /*filename*/
-    struct semaphore sem ; /* mutual exclusion semaphore */
-    char *data ; /* The circular buffer data */
-    int size ; /* Size of the buffer pointed to by 'data' */
-    int refcount ; /* Files that have this buffer open */
-    int read_point ; /* Offset in circ. buffer of oldest data */
-    int write_point ; /* Offset in circ. buffer of newest data */
-    int offset ; /* Byte number of read_point in the stream */
-    struct _gcsDEBUGFS_Node *next ;
-
-    caddr_t temp;
-    int tempSize;
-};
-
-/* amount of data in the queue */
-#define gcmkNODE_QLEN(node) ( (node)->write_point >= (node)->read_point ? \
-         (node)->write_point - (node)->read_point : \
-         (node)->size - (node)->read_point + (node)->write_point)
-
-/* byte number of the last byte in the queue */
-#define gcmkNODE_FIRST_EMPTY_BYTE(node) ((node)->offset + gcmkNODE_QLEN(node))
-
-/*Synchronization primitives*/
-#define gcmkNODE_READQ(node) (&((node)->read_q))
-#define gcmkNODE_WRITEQ(node) (&((node)->write_q))
-#define gcmkNODE_SEM(node) (&((node)->sem))
-
-/*Utilities*/
-#define gcmkMIN(x, y) ((x) < (y) ? (x) : y)
-
-/*Debug File System Struct*/
-typedef struct _gcsDEBUGFS_
-{
-    gcsDEBUGFS_Node* linkedlist ;
-    gcsDEBUGFS_Node* currentNode ;
-    int isInited ;
-} gcsDEBUGFS_ ;
-
-/*debug file system*/
-static gcsDEBUGFS_ gc_dbgfs ;
+#define _GC_OBJ_ZONE    gcvZONE_KERNEL
 
 static int gc_debugfs_open(struct inode *inode, struct file *file)
 {
@@ -259,7 +148,9 @@ gckDEBUGFS_DIR_CreateFiles(
 {
     int i;
     gcsINFO_NODE * node;
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
+
+    gcmkHEADER_ARG("Dir=%p List=%p count=%d Data=%p", Dir, List, count, Data);
 
     for (i = 0; i < count; i++)
     {
@@ -285,10 +176,12 @@ gckDEBUGFS_DIR_CreateFiles(
         list_add(&(node->head), &(Dir->nodeList));
     }
 
-    return gcvSTATUS_OK;
-
 OnError:
-    gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(Dir, List, count));
+    if (gcmIS_ERROR(status))
+    {
+        gcmkVERIFY_OK(gckDEBUGFS_DIR_RemoveFiles(Dir, List, count));
+    }
+    gcmkFOOTER();
     return status;
 }
 
@@ -303,6 +196,8 @@ gckDEBUGFS_DIR_RemoveFiles(
     gcsINFO_NODE * node;
     gcsINFO_NODE * temp;
 
+    gcmkHEADER_ARG("Dir=%p List=%p count=%d", Dir, List, count);
+
     for (i = 0; i < count; i++)
     {
         list_for_each_entry_safe(node, temp, &Dir->nodeList, head)
@@ -316,6 +211,7 @@ gckDEBUGFS_DIR_RemoveFiles(
         }
     }
 
+    gcmkFOOTER_NO();
     return gcvSTATUS_OK;
 }
 
@@ -331,635 +227,3 @@ gckDEBUGFS_DIR_Deinit(
     }
 }
 
-/*******************************************************************************
- **
- **        READ & WRITE FUNCTIONS (START)
- **
- *******************************************************************************/
-
-/*******************************************************************************
- **
- **  _ReadFromNode
- **
- **    1) reading bytes out of a circular buffer with wraparound.
- **    2)returns caddr_t, pointer to data read, which the caller must free.
- **    3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
- **        be the number of bytes actually returned
- **
- *******************************************************************************/
-static caddr_t
-_ReadFromNode (
-                gcsDEBUGFS_Node* Node ,
-                size_t *Length ,
-                loff_t *Offset
-                )
-{
-    caddr_t retval ;
-    int bytes_copied = 0 , n , start_point , remaining ;
-
-    /* find the smaller of the total bytes we have available and what
-     * the user is asking for */
-    *Length = gcmkMIN ( *Length , gcmkNODE_QLEN(Node) ) ;
-
-    remaining = * Length ;
-
-    /* Get start point. */
-    start_point = Node->read_point;
-
-    /* allocate memory to return */
-    if (remaining > Node->tempSize)
-    {
-        kfree(Node->temp);
-
-        if ( ( retval = kmalloc ( sizeof (char ) * remaining , GFP_ATOMIC ) ) == NULL )
-            return NULL;
-
-        Node->temp = retval;
-        Node->tempSize = remaining;
-    }
-    else
-    {
-        retval = Node->temp;
-    }
-
-    /* copy the (possibly noncontiguous) data to our buffer */
-    while ( remaining )
-    {
-        n = gcmkMIN ( remaining , Node->size - start_point ) ;
-        memcpy ( retval + bytes_copied , Node->data + start_point , n ) ;
-        bytes_copied += n ;
-        remaining -= n ;
-        start_point = ( start_point + n ) % Node->size ;
-    }
-
-    /* advance user's file pointer */
-    Node->read_point = (Node->read_point + * Length) % Node->size ;
-
-    return retval ;
-}
-
-/*******************************************************************************
- **
- **  _WriteToNode
- **
- ** 1) writes to a circular buffer with wraparound.
- ** 2)in case of an overflow, it overwrites the oldest unread data.
- **
- *********************************************************************************/
-static void
-_WriteToNode (
-               gcsDEBUGFS_Node* Node ,
-               caddr_t Buf ,
-               int Length
-               )
-{
-    int bytes_copied = 0 ;
-    int overflow = 0 ;
-    int n ;
-
-    if ( Length + gcmkNODE_QLEN ( Node ) >= ( Node->size - 1 ) )
-    {
-        overflow = 1 ;
-    }
-
-    while ( Length )
-    {
-        /* how many contiguous bytes are available from the write point to
-         * the end of the circular buffer? */
-        n = gcmkMIN ( Length , Node->size - Node->write_point ) ;
-        memcpy ( Node->data + Node->write_point , Buf + bytes_copied , n ) ;
-        bytes_copied += n ;
-        Length -= n ;
-        Node->write_point = ( Node->write_point + n ) % Node->size ;
-    }
-
-    /* if there is an overflow, reset the read point to read whatever is
-     * the oldest data that we have, that has not yet been
-     * overwritten. */
-    if ( overflow )
-    {
-        Node->read_point = ( Node->write_point + 1 ) % Node->size ;
-    }
-}
-
-/*******************************************************************************
- **
- **         PRINTING UTILITY (START)
- **
- *******************************************************************************/
-
-/*******************************************************************************
- **
- **  _GetArgumentSize
- **
- **
- *******************************************************************************/
-static gctINT
-_GetArgumentSize (
-                   IN gctCONST_STRING Message
-                   )
-{
-    gctINT i , count ;
-
-    for ( i = 0 , count = 0 ; Message[i] ; i += 1 )
-    {
-        if ( Message[i] == '%' )
-        {
-            count += 1 ;
-        }
-    }
-    return count * sizeof (unsigned int ) ;
-}
-
-/*******************************************************************************
- **
- ** _AppendString
- **
- **
- *******************************************************************************/
-static ssize_t
-_AppendString (
-    IN gcsDEBUGFS_Node* Node,
-    IN gctCONST_STRING String,
-    IN int Length
-    )
-{
-    int n;
-    unsigned long flags;
-
-    /* if the message is longer than the buffer, just take the beginning
-     * of it, in hopes that the reader (if any) will have time to read
-     * before we wrap around and obliterate it */
-    n = gcmkMIN ( Length , Node->size - 1 );
-
-    spin_lock_irqsave(&traceLock, flags);
-
-    /* now copy it into the circular buffer and free our temp copy */
-    _WriteToNode ( Node , (caddr_t)String , n ) ;
-
-    spin_unlock_irqrestore(&traceLock, flags);
-
-    return n ;
-}
-
-/*******************************************************************************
- **
- ** _DebugFSPrint
- **
- **
- *******************************************************************************/
-static ssize_t
-_DebugFSPrint (
-                IN unsigned int ArgumentSize ,
-                IN const char* Message ,
-                IN gctDBGARGS * Arguments
-
-                )
-{
-    char buffer[MAX_LINE_SIZE] ;
-    int len ;
-    ssize_t res = 0;
-
-    if ( gc_dbgfs.currentNode )
-    {
-        len = vsnprintf ( buffer , sizeof (buffer ) , Message , *( va_list * ) Arguments ) ;
-
-        buffer[len] = '\0' ;
-        /* Add end-of-line if missing. */
-        if ( buffer[len - 1] != '\n' )
-        {
-             buffer[len ++] = '\n' ;
-             buffer[len] = '\0' ;
-        }
-
-       res = _AppendString ( gc_dbgfs.currentNode , buffer , len ) ;
-       wake_up_interruptible ( gcmkNODE_READQ ( gc_dbgfs.currentNode ) ) ; /* blocked in read*/
-    }
-
-    return res;
-}
-
-/*******************************************************************************
- **
- **                     LINUX SYSTEM FUNCTIONS (START)
- **
- *******************************************************************************/
-static int
-_DebugFSOpen (
-    struct inode* inode,
-    struct file* filp
-    )
-{
-    filp->private_data = inode->i_private;
-
-    return 0;
-}
-
-/*******************************************************************************
- **
- **   _DebugFSRead
- **
- *******************************************************************************/
-static ssize_t
-_DebugFSRead (
-    struct file *file,
-    char __user * buffer,
-    size_t length,
-    loff_t * offset
-    )
-{
-    int retval;
-    caddr_t data_to_return;
-    unsigned long flags;
-    gcsDEBUGFS_Node* node = file->private_data;
-
-    if (node == NULL)
-    {
-        printk ( "debugfs_read: record not found\n" );
-        return - EIO ;
-    }
-
-    spin_lock_irqsave(&traceLock, flags);
-
-    /* wait until there's data available (unless we do nonblocking reads) */
-    while (!gcmkNODE_QLEN(node))
-    {
-        spin_unlock_irqrestore(&traceLock, flags);
-
-        if (file->f_flags & O_NONBLOCK)
-        {
-            return - EAGAIN ;
-        }
-
-        if (wait_event_interruptible((*(gcmkNODE_READQ(node))) , (*offset < gcmkNODE_FIRST_EMPTY_BYTE(node))))
-        {
-            return - ERESTARTSYS ; /* signal: tell the fs layer to handle it */
-        }
-
-        spin_lock_irqsave(&traceLock, flags);
-    }
-
-    data_to_return = _ReadFromNode(node , &length , offset);
-
-    spin_unlock_irqrestore(&traceLock, flags);
-
-    if (data_to_return == NULL)
-    {
-        retval = 0;
-        goto unlock;
-    }
-
-    if (copy_to_user(buffer, data_to_return, length) > 0)
-    {
-        retval = - EFAULT;
-    }
-    else
-    {
-        retval = length;
-    }
-unlock:
-
-    wake_up_interruptible(gcmkNODE_WRITEQ(node));
-    return retval ;
-}
-
-/*******************************************************************************
- **
- **_DebugFSWrite
- **
- *******************************************************************************/
-static ssize_t
-_DebugFSWrite (
-                struct file *file ,
-                const char __user * buffer ,
-                size_t length ,
-                loff_t * offset
-                )
-{
-    caddr_t message = NULL ;
-    int n ;
-    gcsDEBUGFS_Node* node = file->private_data;
-
-    /* get the metadata about this log */
-    if (node == NULL)
-    {
-        return - EIO ;
-    }
-
-    if ( down_interruptible ( gcmkNODE_SEM ( node ) ) )
-    {
-        return - ERESTARTSYS ;
-    }
-
-    /* if the message is longer than the buffer, just take the beginning
-     * of it, in hopes that the reader (if any) will have time to read
-     * before we wrap around and obliterate it */
-    n = gcmkMIN ( length , node->size - 1 ) ;
-
-    /* make sure we have the memory for it */
-    if ( ( message = kmalloc ( n , GFP_KERNEL ) ) == NULL )
-    {
-        up ( gcmkNODE_SEM ( node ) ) ;
-        return - ENOMEM ;
-    }
-
-
-    /* copy into our temp buffer */
-    if ( copy_from_user ( message , buffer , n ) > 0 )
-    {
-        up ( gcmkNODE_SEM ( node ) ) ;
-        kfree ( message ) ;
-        return - EFAULT ;
-    }
-
-    /* now copy it into the circular buffer and free our temp copy */
-    _WriteToNode ( node , message , n ) ;
-
-    kfree ( message ) ;
-    up ( gcmkNODE_SEM ( node ) ) ;
-
-    /* wake up any readers that might be waiting for the data.  we call
-     * schedule in the vague hope that a reader will run before the
-     * writer's next write, to avoid losing data. */
-    wake_up_interruptible ( gcmkNODE_READQ ( node ) ) ;
-
-    return n ;
-}
-
-/*******************************************************************************
- **
- ** File Operations Table
- **
- *******************************************************************************/
-static const struct file_operations debugfs_operations = {
-                                                          .owner = THIS_MODULE ,
-                                                          .open = _DebugFSOpen ,
-                                                          .read = _DebugFSRead ,
-                                                          .write = _DebugFSWrite ,
-} ;
-
-/*******************************************************************************
- **
- **                             INTERFACE FUNCTIONS (START)
- **
- *******************************************************************************/
-
-/*******************************************************************************
- **
- **  gckDEBUGFS_IsEnabled
- **
- **
- **  INPUT:
- **
- **  OUTPUT:
- **
- *******************************************************************************/
-
-
-gctINT
-gckDEBUGFS_IsEnabled ( void )
-{
-    return gc_dbgfs.isInited ;
-}
-/*******************************************************************************
- **
- **  gckDEBUGFS_Initialize
- **
- **
- **  INPUT:
- **
- **  OUTPUT:
- **
- *******************************************************************************/
-
-gctINT
-gckDEBUGFS_Initialize ( void )
-{
-    if ( ! gc_dbgfs.isInited )
-    {
-        gc_dbgfs.linkedlist = gcvNULL ;
-        gc_dbgfs.currentNode = gcvNULL ;
-        gc_dbgfs.isInited = 1 ;
-    }
-    return gc_dbgfs.isInited ;
-}
-/*******************************************************************************
- **
- **  gckDEBUGFS_Terminate
- **
- **
- **  INPUT:
- **
- **  OUTPUT:
- **
- *******************************************************************************/
-
-gctINT
-gckDEBUGFS_Terminate ( void )
-{
-    gcsDEBUGFS_Node * next = gcvNULL ;
-    gcsDEBUGFS_Node * temp = gcvNULL ;
-    if ( gc_dbgfs.isInited )
-    {
-        temp = gc_dbgfs.linkedlist ;
-        while ( temp != gcvNULL )
-        {
-            next = temp->next ;
-            gckDEBUGFS_FreeNode ( temp ) ;
-            kfree ( temp ) ;
-            temp = next ;
-        }
-        gc_dbgfs.isInited = 0 ;
-    }
-    return 0 ;
-}
-
-
-/*******************************************************************************
- **
- **  gckDEBUGFS_CreateNode
- **
- **
- **  INPUT:
- **
- **  OUTPUT:
- **
- **     gckDEBUGFS_FreeNode * Device
- **          Pointer to a variable receiving the gcsDEBUGFS_Node object pointer on
- **          success.
- *********************************************************************************/
-
-gctINT
-gckDEBUGFS_CreateNode (
-    IN gctPOINTER Device,
-    IN gctINT SizeInKB ,
-    IN struct dentry * Root ,
-    IN gctCONST_STRING NodeName ,
-    OUT gcsDEBUGFS_Node **Node
-    )
-{
-    gcsDEBUGFS_Node*node ;
-    /* allocate space for our metadata and initialize it */
-    if ( ( node = kmalloc ( sizeof (gcsDEBUGFS_Node ) , GFP_KERNEL ) ) == NULL )
-        goto struct_malloc_failed ;
-
-    /*Zero it out*/
-    memset ( node , 0 , sizeof (gcsDEBUGFS_Node ) ) ;
-
-    /*Init the sync primitives*/
-#if defined(DECLARE_WAIT_QUEUE_HEAD)
-    init_waitqueue_head ( gcmkNODE_READQ ( node ) ) ;
-#else
-    init_waitqueue ( gcmkNODE_READQ ( node ) ) ;
-#endif
-
-#if defined(DECLARE_WAIT_QUEUE_HEAD)
-    init_waitqueue_head ( gcmkNODE_WRITEQ ( node ) ) ;
-#else
-    init_waitqueue ( gcmkNODE_WRITEQ ( node ) ) ;
-#endif
-    sema_init ( gcmkNODE_SEM ( node ) , 1 ) ;
-    /*End the sync primitives*/
-
-    /*creating the debug file system*/
-    node->parent = Root;
-
-    if (SizeInKB)
-    {
-        /* figure out how much of a buffer this should be and allocate the buffer */
-        node->size = 1024 * SizeInKB ;
-        if ( ( node->data = ( char * ) vmalloc ( sizeof (char ) * node->size ) ) == NULL )
-            goto data_malloc_failed ;
-
-        node->tempSize = 0;
-        node->temp = NULL;
-
-        /*creating the file*/
-        node->filen = debugfs_create_file(NodeName, S_IRUGO|S_IWUSR, node->parent, node,
-                                          &debugfs_operations);
-    }
-
-    /* add it to our linked list */
-    node->next = gc_dbgfs.linkedlist ;
-    gc_dbgfs.linkedlist = node ;
-
-
-    /* pass the struct back */
-    *Node = node ;
-    return 0 ;
-
-
-data_malloc_failed:
-    kfree ( node ) ;
-struct_malloc_failed:
-    return - ENOMEM ;
-}
-
-/*******************************************************************************
- **
- **  gckDEBUGFS_FreeNode
- **
- **
- **  INPUT:
- **
- **  OUTPUT:
- **
- *******************************************************************************/
-void
-gckDEBUGFS_FreeNode (
-                             IN gcsDEBUGFS_Node * Node
-                             )
-{
-
-    gcsDEBUGFS_Node **ptr ;
-
-    if ( Node == NULL )
-    {
-        printk ( "null passed to free_vinfo\n" ) ;
-        return ;
-    }
-
-    down ( gcmkNODE_SEM ( Node ) ) ;
-    /*free data*/
-    vfree ( Node->data ) ;
-
-    kfree(Node->temp);
-
-    /*Close Debug fs*/
-    if ( Node->filen )
-    {
-        debugfs_remove ( Node->filen ) ;
-    }
-
-    /* now delete the node from the linked list */
-    ptr = & ( gc_dbgfs.linkedlist ) ;
-    while ( *ptr != Node )
-    {
-        if ( ! *ptr )
-        {
-            printk ( "corrupt info list!\n" ) ;
-            break ;
-        }
-        else
-            ptr = & ( ( **ptr ).next ) ;
-    }
-    *ptr = Node->next ;
-    up ( gcmkNODE_SEM ( Node ) ) ;
-}
-
-/*******************************************************************************
- **
- **   gckDEBUGFS_SetCurrentNode
- **
- **
- **  INPUT:
- **
- **  OUTPUT:
- **
- *******************************************************************************/
-void
-gckDEBUGFS_SetCurrentNode (
-                                   IN gcsDEBUGFS_Node * Node
-                                   )
-{
-    gc_dbgfs.currentNode = Node ;
-}
-
-/*******************************************************************************
- **
- **   gckDEBUGFS_GetCurrentNode
- **
- **
- **  INPUT:
- **
- **  OUTPUT:
- **
- *******************************************************************************/
-void
-gckDEBUGFS_GetCurrentNode (
-                                   OUT gcsDEBUGFS_Node ** Node
-                                   )
-{
-    *Node = gc_dbgfs.currentNode ;
-}
-
-/*******************************************************************************
- **
- **   gckDEBUGFS_Print
- **
- **
- **  INPUT:
- **
- **  OUTPUT:
- **
- *******************************************************************************/
-ssize_t
-gckDEBUGFS_Print (
-                          IN gctCONST_STRING Message ,
-                          ...
-                          )
-{
-    ssize_t _debugfs_res = 0;
-    gcmkDEBUGFS_PRINT ( _GetArgumentSize ( Message ) , Message ) ;
-    return _debugfs_res;
-}
index 14a3324..6a5809e 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -60,9 +60,6 @@
 
  #define MAX_LINE_SIZE 768           /* Max bytes for a line of debug info */
 
-
- typedef struct _gcsDEBUGFS_Node gcsDEBUGFS_Node;
-
 typedef struct _gcsDEBUGFS_DIR *gckDEBUGFS_DIR;
 typedef struct _gcsDEBUGFS_DIR
 {
@@ -115,56 +112,4 @@ gckDEBUGFS_DIR_Deinit(
     IN gckDEBUGFS_DIR Dir
     );
 
-/*******************************************************************************
- **
- **                             System Related
- **
- *******************************************************************************/
-
-gctINT gckDEBUGFS_IsEnabled(void);
-
-gctINT gckDEBUGFS_Initialize(void);
-
-gctINT gckDEBUGFS_Terminate(void);
-
-
-/*******************************************************************************
- **
- **                             Node Related
- **
- *******************************************************************************/
-
-gctINT
-gckDEBUGFS_CreateNode(
-    IN gctPOINTER Device,
-    IN gctINT SizeInKB,
-    IN struct dentry * Root,
-    IN gctCONST_STRING NodeName,
-    OUT gcsDEBUGFS_Node **Node
-    );
-
-void gckDEBUGFS_FreeNode(
-            IN gcsDEBUGFS_Node  * Node
-            );
-
-
-
-void gckDEBUGFS_SetCurrentNode(
-            IN gcsDEBUGFS_Node  * Node
-            );
-
-
-
-void gckDEBUGFS_GetCurrentNode(
-            OUT gcsDEBUGFS_Node  ** Node
-            );
-
-
-ssize_t gckDEBUGFS_Print(
-                IN gctCONST_STRING  Message,
-                ...
-                );
-
 #endif
-
-
index 773db23..86639d3 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -54,6 +54,7 @@
 
 
 #include "gc_hal_kernel_linux.h"
+#include "gc_hal_kernel_allocator.h"
 #include <linux/pagemap.h>
 #include <linux/seq_file.h>
 #include <linux/mman.h>
@@ -83,8 +84,8 @@ int gc_info_show(struct seq_file* m, void* data)
     gcsINFO_NODE *node = m->private;
     gckGALDEVICE device = node->device;
     int i = 0;
-    gceCHIPMODEL chipModel;
-    gctUINT32 chipRevision;
+    gceCHIPMODEL chipModel = 0;
+    gctUINT32 chipRevision = 0;
     gctUINT32 productID = 0;
     gctUINT32 ecoID = 0;
 
@@ -93,16 +94,16 @@ int gc_info_show(struct seq_file* m, void* data)
 
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
-        if (device->irqLines[i] != -1)
+        if (device->kernels[i])
         {
-#if gcdENABLE_VG
             if (i == gcvCORE_VG)
             {
+#if gcdENABLE_VG
                 chipModel = device->kernels[i]->vg->hardware->chipModel;
                 chipRevision = device->kernels[i]->vg->hardware->chipRevision;
+#endif
             }
             else
-#endif
             {
                 chipModel = device->kernels[i]->hardware->identity.chipModel;
                 chipRevision = device->kernels[i]->hardware->identity.chipRevision;
@@ -165,28 +166,6 @@ int gc_clients_show(struct seq_file* m, void* data)
     return 0;
 }
 
-static void
-_CounterAdd(
-    gcsDATABASE_COUNTERS * Dest,
-    gcsDATABASE_COUNTERS * Src
-    )
-{
-    Dest->bytes += Src->bytes;
-    Dest->maxBytes += Src->maxBytes;
-    Dest->totalBytes += Src->totalBytes;
-}
-
-static void
-_CounterPrint(
-    gcsDATABASE_COUNTERS * Counter,
-    gctCONST_STRING Name,
-    struct seq_file* m
-    )
-{
-    seq_printf(m, "    %s:\n", Name);
-    seq_printf(m, "        Used  : %10llu B\n", Counter->bytes);
-}
-
 int gc_meminfo_show(struct seq_file* m, void* data)
 {
     gcsINFO_NODE *node = m->private;
@@ -199,7 +178,6 @@ int gc_meminfo_show(struct seq_file* m, void* data)
 
     gctUINT32 free = 0, used = 0, total = 0, minFree = 0, maxUsed = 0;
 
-    gcsDATABASE_COUNTERS contiguousCounter = {0, 0, 0};
     gcsDATABASE_COUNTERS virtualCounter = {0, 0, 0};
     gcsDATABASE_COUNTERS nonPagedCounter = {0, 0, 0};
 
@@ -223,12 +201,12 @@ int gc_meminfo_show(struct seq_file* m, void* data)
     }
 
     seq_printf(m, "VIDEO MEMORY:\n");
-    seq_printf(m, "    gcvPOOL_SYSTEM:\n");
-    seq_printf(m, "        Free  : %10u B\n", free);
-    seq_printf(m, "        Used  : %10u B\n", used);
-    seq_printf(m, "        MinFree  : %10u B\n", minFree);
-    seq_printf(m, "        MaxUsed  : %10u B\n", maxUsed);
-    seq_printf(m, "        Total : %10u B\n", total);
+    seq_printf(m, "  POOL SYSTEM:\n");
+    seq_printf(m, "    Free :    %10u B\n", free);
+    seq_printf(m, "    Used :    %10u B\n", used);
+    seq_printf(m, "    MinFree : %10u B\n", minFree);
+    seq_printf(m, "    MaxUsed : %10u B\n", maxUsed);
+    seq_printf(m, "    Total :   %10u B\n", total);
 
     /* Acquire the database mutex. */
     gcmkVERIFY_OK(
@@ -241,201 +219,364 @@ int gc_meminfo_show(struct seq_file* m, void* data)
              database != gcvNULL;
              database = database->next)
         {
-            gcsDATABASE_COUNTERS * counter = &database->vidMemPool[gcvPOOL_CONTIGUOUS];
-            _CounterAdd(&contiguousCounter, counter);
-
+            gcsDATABASE_COUNTERS * counter;
             counter = &database->vidMemPool[gcvPOOL_VIRTUAL];
-            _CounterAdd(&virtualCounter, counter);
-
+            virtualCounter.bytes += counter->bytes;
+            virtualCounter.maxBytes += counter->maxBytes;
 
             counter = &database->nonPaged;
-            _CounterAdd(&nonPagedCounter, counter);
+            nonPagedCounter.bytes += counter->bytes;
+            nonPagedCounter.bytes += counter->maxBytes;
         }
     }
 
     /* Release the database mutex. */
     gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
 
-    _CounterPrint(&contiguousCounter, "gcvPOOL_CONTIGUOUS", m);
-    _CounterPrint(&virtualCounter, "gcvPOOL_VIRTUAL", m);
-
-    seq_printf(m, "\n");
-
-    seq_printf(m, "NON PAGED MEMORY:\n");
-    seq_printf(m, "    Used  : %10llu B\n", nonPagedCounter.bytes);
+    seq_printf(m, "  POOL VIRTUAL:\n");
+    seq_printf(m, "    Used :    %10llu B\n", virtualCounter.bytes);
+    seq_printf(m, "    MaxUsed : %10llu B\n", virtualCounter.bytes);
 
     return 0;
 }
 
-static int
-_ShowRecord(
+static const char * vidmemTypeStr[gcvVIDMEM_TYPE_COUNT] =
+{
+    "Generic",
+    "Index",
+    "Vertex",
+    "Texture",
+    "RenderTarget",
+    "Depth",
+    "Bitmap",
+    "TileStatus",
+    "Image",
+    "Mask",
+    "Scissor",
+    "HZ",
+    "ICache",
+    "TxDesc",
+    "Fence",
+    "TFBHeader",
+    "Command",
+};
+
+static const char * poolStr[gcvPOOL_NUMBER_OF_POOLS] =
+{
+    "Unknown",
+    "Default",
+    "Local",
+    "Internal",
+    "External",
+    "Unified",
+    "System",
+    "Virtual",
+    "User",
+};
+
+static void
+_ShowDummyRecord(
     IN struct seq_file *File,
-    IN gcsDATABASE_RECORD_PTR Record
+    IN gcsDATABASE_PTR Database
     )
 {
-    static const char * recordTypes[gcvDB_NUM_TYPES] = {
-        "Unknown",
-        "VideoMemory",
-        "CommandBuffer",
-        "NonPaged",
-        "Contiguous",
-        "Signal",
-        "VidMemLock",
-        "Context",
-        "Idel",
-        "MapMemory",
-        "MapUserMemory",
-        "ShBuf",
-    };
+}
 
-    seq_printf(File, "%-14s %3d %16p %16zu %16zu\n",
-        recordTypes[Record->type],
-        Record->kernel->core,
-        Record->data,
-        (size_t) Record->physical,
-        Record->bytes
-        );
+static void
+_ShowVideoMemoryRecord(
+    IN struct seq_file *m,
+    IN gcsDATABASE_PTR Database
+    )
+{
+    gctUINT i;
+    gctUINT32 handle;
+    gckVIDMEM_NODE nodeObject;
+    gctPHYS_ADDR_T physical;
+    gctINT32 refCount = 0;
+    gctINT32 lockCount = 0;
+    gceSTATUS status;
 
-    return 0;
+    seq_printf(m, "Video Memory Node:\n");
+    seq_printf(m, "  handle         nodeObject       size         type     pool     physical  ref lock\n");
+
+    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
+    {
+        gcsDATABASE_RECORD_PTR r = Database->list[i];
+
+        while (r != NULL)
+        {
+            gcsDATABASE_RECORD_PTR record = r;
+            r = r->next;
+
+            if (record->type != gcvDB_VIDEO_MEMORY)
+            {
+                continue;
+            }
+
+            handle = gcmPTR2INT32(record->data);
+
+            status = gckVIDMEM_HANDLE_Lookup2(
+                record->kernel,
+                Database,
+                handle,
+                &nodeObject
+                );
+
+            if (gcmIS_ERROR(status))
+            {
+                seq_printf(m, "%6u Invalid Node\n", handle);
+                continue;
+            }
+
+            gckVIDMEM_NODE_GetPhysical(record->kernel, nodeObject, 0, &physical);
+            gckVIDMEM_NODE_GetReference(record->kernel, nodeObject, &refCount);
+            gckVIDMEM_NODE_GetLockCount(record->kernel, nodeObject, &lockCount);
+
+            seq_printf(m, "%#8x %#18lx %10lu %12s %8s %#12llx %4d %4d\n",
+                handle,
+                (unsigned long)nodeObject,
+                (unsigned long)record->bytes,
+                vidmemTypeStr[nodeObject->type],
+                poolStr[nodeObject->pool],
+                physical,
+                refCount,
+                lockCount
+                );
+        }
+    }
 }
 
-static int
-_ShowRecords(
-    IN struct seq_file *File,
+static void
+_ShowNonPagedRecord(
+    IN struct seq_file *m,
     IN gcsDATABASE_PTR Database
     )
 {
     gctUINT i;
 
-    seq_printf(File, "Records:\n");
-
-    seq_printf(File, "%14s %3s %16s %16s %16s\n",
-               "Type", "GPU", "Data/Node", "Physical/Node", "Bytes");
+    seq_printf(m, "NonPaged Memory:\n");
+    seq_printf(m, "  name              vaddr       size\n");
 
     for (i = 0; i < gcmCOUNTOF(Database->list); i++)
     {
-        gcsDATABASE_RECORD_PTR record = Database->list[i];
+        gcsDATABASE_RECORD_PTR r = Database->list[i];
 
-        while (record != NULL)
+        while (r != NULL)
         {
-            _ShowRecord(File, record);
-            record = record->next;
+            gcsDATABASE_RECORD_PTR record = r;
+            r = r->next;
+
+            if (record->type != gcvDB_NON_PAGED)
+            {
+                continue;
+            }
+
+            seq_printf(m, "%6u %#18lx %10lu\n",
+                gcmPTR2INT32(record->physical),
+                (unsigned long)record->data,
+                (unsigned long)record->bytes
+                );
         }
     }
+}
 
-    return 0;
+static void
+_ShowSignalRecord(
+    IN struct seq_file *m,
+    IN gcsDATABASE_PTR Database
+    )
+{
+    gctUINT i;
+
+    seq_printf(m, "User signal:\n");
+
+    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
+    {
+        gcsDATABASE_RECORD_PTR r = Database->list[i];
+
+        while (r != NULL)
+        {
+            gcsDATABASE_RECORD_PTR record = r;
+            r = r->next;
+
+            if (record->type != gcvDB_SIGNAL)
+            {
+                continue;
+            }
+
+            seq_printf(m, "%#10x\n", gcmPTR2INT32(record->data));
+        }
+    }
 }
 
 static void
-_ShowCounters(
-    struct seq_file *File,
-    gcsDATABASE_PTR Database
+_ShowLockRecord(
+    IN struct seq_file *m,
+    IN gcsDATABASE_PTR Database
     )
 {
-    gctUINT i = 0;
+    gctUINT i;
+    gceSTATUS status;
+    gctUINT32 handle;
+    gckVIDMEM_NODE nodeObject;
 
-    static const char * surfaceTypes[gcvSURF_NUM_TYPES] = {
-        "Unknown",
-        "Index",
-        "Vertex",
-        "Texture",
-        "RenderTarget",
-        "Depth",
-        "Bitmap",
-        "TileStatus",
-        "Image",
-        "Mask",
-        "Scissor",
-        "HZ",
-        "ICache",
-        "TxDesc",
-        "Fence",
-        "TFBHeader",
-    };
+    seq_printf(m, "Video Memory Lock:\n");
+    seq_printf(m, "  handle         nodeObject              vaddr\n");
 
-    static const char * poolTypes[gcvPOOL_NUMBER_OF_POOLS] = {
-        "Unknown",
-        "Default",
-        "Local",
-        "Internal",
-        "External",
-        "Unified",
-        "System",
-        "Virtual",
-        "User",
-        "Contiguous",
-    };
+    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
+    {
+        gcsDATABASE_RECORD_PTR r = Database->list[i];
 
-    static const char * otherCounterNames[] = {
-        "AllocNonPaged",
-        "AllocContiguous",
-        "MapUserMemory",
-        "MapMemory",
-    };
+        while (r != NULL)
+        {
+            gcsDATABASE_RECORD_PTR record = r;
+            r = r->next;
 
-    gcsDATABASE_COUNTERS * otherCounters[] = {
-        &Database->nonPaged,
-        &Database->contiguous,
-        &Database->mapUserMemory,
-        &Database->mapMemory,
-    };
+            if (record->type != gcvDB_VIDEO_MEMORY_LOCKED)
+            {
+                continue;
+            }
 
-    seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");
+            handle = gcmPTR2INT32(record->data);
 
-    /* Print surface type counters. */
-    seq_printf(File, "%-16s %16lld %16lld %16lld\n",
-               "All-Types",
-               Database->vidMem.bytes,
-               Database->vidMem.maxBytes,
-               Database->vidMem.totalBytes);
+            status = gckVIDMEM_HANDLE_Lookup2(
+                record->kernel,
+                Database,
+                handle,
+                &nodeObject
+                );
+
+            if (gcmIS_ERROR(status))
+            {
+                nodeObject = gcvNULL;
+            }
+
+            seq_printf(m, "%#8x %#18lx %#18lx\n",
+                handle,
+                (unsigned long)nodeObject,
+                (unsigned long)record->physical
+                );
+        }
+    }
+}
+
+static void
+_ShowContextRecord(
+    IN struct seq_file *m,
+    IN gcsDATABASE_PTR Database
+    )
+{
+    gctUINT i;
 
-    for (i = 1; i < gcvSURF_NUM_TYPES; i++)
+    seq_printf(m, "Context:\n");
+
+    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
     {
-        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
-                   surfaceTypes[i],
-                   Database->vidMemType[i].bytes,
-                   Database->vidMemType[i].maxBytes,
-                   Database->vidMemType[i].totalBytes);
+        gcsDATABASE_RECORD_PTR r = Database->list[i];
+
+        while (r != NULL)
+        {
+            gcsDATABASE_RECORD_PTR record = r;
+            r = r->next;
+
+            if (record->type != gcvDB_CONTEXT)
+            {
+                continue;
+            }
+
+            seq_printf(m, "%6u\n", gcmPTR2INT32(record->data));
+        }
     }
-    seq_puts(File, "\n");
+}
 
-    /* Print surface pool counters. */
-    seq_printf(File, "%-16s %16lld %16lld %16lld\n",
-               "All-Pools",
-               Database->vidMem.bytes,
-               Database->vidMem.maxBytes,
-               Database->vidMem.totalBytes);
+static void
+_ShowMapMemoryRecord(
+    IN struct seq_file *m,
+    IN gcsDATABASE_PTR Database
+    )
+{
+    gctUINT i;
 
-    for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+    seq_printf(m, "Map Memory:\n");
+    seq_printf(m, "  name              vaddr       size\n");
+
+    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
     {
-        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
-                   poolTypes[i],
-                   Database->vidMemPool[i].bytes,
-                   Database->vidMemPool[i].maxBytes,
-                   Database->vidMemPool[i].totalBytes);
+        gcsDATABASE_RECORD_PTR r = Database->list[i];
+
+        while (r != NULL)
+        {
+            gcsDATABASE_RECORD_PTR record = r;
+            r = r->next;
+
+            if (record->type != gcvDB_MAP_MEMORY)
+            {
+                continue;
+            }
+
+            seq_printf(m, "%#6lx %#18lx %10lu\n",
+                (unsigned long)record->physical,
+                (unsigned long)record->data,
+                (unsigned long)record->bytes
+                );
+        }
     }
-    seq_puts(File, "\n");
+}
 
-    /* Print other counters. */
-    for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
+static void
+_ShowShbufRecord(
+    IN struct seq_file *m,
+    IN gcsDATABASE_PTR Database
+    )
+{
+    gctUINT i;
+
+    seq_printf(m, "ShBuf:\n");
+
+    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
     {
-        seq_printf(File, "%-16s %16lld %16lld %16lld\n",
-                   otherCounterNames[i],
-                   otherCounters[i]->bytes,
-                   otherCounters[i]->maxBytes,
-                   otherCounters[i]->totalBytes);
+        gcsDATABASE_RECORD_PTR r = Database->list[i];
+
+        while (r != NULL)
+        {
+            gcsDATABASE_RECORD_PTR record = r;
+            r = r->next;
+
+            if (record->type != gcvDB_SHBUF)
+            {
+                continue;
+            }
+
+            seq_printf(m, "%#8x\n", gcmPTR2INT32(record->data));
+        }
     }
-    seq_puts(File, "\n");
 }
 
 static void
-_ShowProcess(
+_ShowDatabase(
     IN struct seq_file *File,
     IN gcsDATABASE_PTR Database
     )
 {
     gctINT pid;
+    gctUINT i;
     char name[24];
+    gctBOOL hasType[gcvDB_NUM_TYPES] = {0,};
+    void (* showFuncs[])(struct seq_file *, gcsDATABASE_PTR) =
+    {
+        _ShowDummyRecord,
+        _ShowVideoMemoryRecord,
+        _ShowNonPagedRecord,
+        _ShowSignalRecord,
+        _ShowLockRecord,
+        _ShowContextRecord,
+        _ShowDummyRecord,
+        _ShowMapMemoryRecord,
+        _ShowShbufRecord,
+    };
+
+    gcmSTATIC_ASSERT(gcmCOUNTOF(showFuncs) == gcvDB_NUM_TYPES,
+                     "DB type mismatch");
 
     /* Process ID and name */
     pid = Database->processID;
@@ -444,64 +585,67 @@ _ShowProcess(
     seq_printf(File, "--------------------------------------------------------------------------------\n");
     seq_printf(File, "Process: %-8d %s\n", pid, name);
 
-    /* Detailed records */
-    _ShowRecords(File, Database);
+    for (i = 0; i < gcmCOUNTOF(Database->list); i++)
+    {
+        gcsDATABASE_RECORD_PTR record = Database->list[i];
 
-    seq_printf(File, "Counters:\n");
+        while (record != NULL)
+        {
+            hasType[record->type] = gcvTRUE;
+            record = record->next;
+        }
+    }
 
-    _ShowCounters(File, Database);
+    for (i = 0; i < gcvDB_NUM_TYPES; i++)
+    {
+        if (hasType[i])
+        {
+            showFuncs[i](File, Database);
+        }
+    }
 }
 
-static void
-_ShowProcesses(
-    IN struct seq_file * File,
-    IN gckKERNEL Kernel
-    )
+static int
+gc_db_show(struct seq_file *m, void *data)
 {
     gcsDATABASE_PTR database;
     gctINT i;
     static gctUINT64 idleTime = 0;
+    gcsINFO_NODE *node = m->private;
+    gckGALDEVICE device = node->device;
+    gckKERNEL kernel = _GetValidKernel(device);
+
+    if (!kernel)
+        return -ENXIO;
 
     /* Acquire the database mutex. */
     gcmkVERIFY_OK(
-        gckOS_AcquireMutex(Kernel->os, Kernel->db->dbMutex, gcvINFINITE));
+        gckOS_AcquireMutex(kernel->os, kernel->db->dbMutex, gcvINFINITE));
 
-    if (Kernel->db->idleTime)
+    if (kernel->db->idleTime)
     {
         /* Record idle time if DB upated. */
-        idleTime = Kernel->db->idleTime;
-        Kernel->db->idleTime = 0;
+        idleTime = kernel->db->idleTime;
+        kernel->db->idleTime = 0;
     }
 
     /* Idle time since last call */
-    seq_printf(File, "GPU Idle: %llu ns\n",  idleTime);
+    seq_printf(m, "GPU Idle: %llu ns\n",  idleTime);
 
     /* Walk the databases. */
-    for (i = 0; i < gcmCOUNTOF(Kernel->db->db); ++i)
+    for (i = 0; i < gcmCOUNTOF(kernel->db->db); ++i)
     {
-        for (database = Kernel->db->db[i];
+        for (database = kernel->db->db[i];
              database != gcvNULL;
              database = database->next)
         {
-            _ShowProcess(File, database);
+            _ShowDatabase(m, database);
         }
     }
 
     /* Release the database mutex. */
-    gcmkVERIFY_OK(gckOS_ReleaseMutex(Kernel->os, Kernel->db->dbMutex));
-}
-
-static int
-gc_db_show(struct seq_file *m, void *data)
-{
-    gcsINFO_NODE *node = m->private;
-    gckGALDEVICE device = node->device;
-    gckKERNEL kernel = _GetValidKernel(device);
-
-    if (!kernel)
-        return -ENXIO;
+    gcmkVERIFY_OK(gckOS_ReleaseMutex(kernel->os, kernel->db->dbMutex));
 
-    _ShowProcesses(m, kernel);
     return 0 ;
 }
 
@@ -510,16 +654,11 @@ gc_version_show(struct seq_file *m, void *data)
 {
     gcsINFO_NODE *node = m->private;
     gckGALDEVICE device = node->device;
-    gcsPLATFORM * platform = gcvNULL;
+    gcsPLATFORM * platform = device->platform;
 
     if (!device)
         return -ENXIO;
 
-    platform = device->platform;
-
-    if (!platform)
-        return -ENXIO;
-
     seq_printf(m, "%s built at %s\n",  gcvVERSION_STRING, HOST);
 
     if (platform->name)
@@ -534,15 +673,40 @@ gc_version_show(struct seq_file *m, void *data)
     return 0 ;
 }
 
-/*******************************************************************************
-**
-** Show PM state timer.
-**
-** Entry is called as 'idle' for compatible reason, it shows more information
-** than idle actually.
-**
-**  Start: Start time of this counting period.
-**  End: End time of this counting peroid.
+static void print_ull(char dest[32], unsigned long long u)
+{
+    unsigned t[7];
+    int i;
+
+    if (u < 1000)
+    {
+        sprintf(dest, "%27llu", u);
+        return;
+    }
+
+    for (i = 0; i < 7 && u; i++)
+    {
+        t[i] = do_div(u, 1000);
+    }
+
+    dest += sprintf(dest, "%*s", (7 - i) * 4, "");
+    dest += sprintf(dest, "%3u", t[--i]);
+
+    for (i--; i >= 0; i--)
+    {
+        dest += sprintf(dest, ",%03u", t[i]);
+    }
+}
+
+/*******************************************************************************
+**
+** Show PM state timer.
+**
+** Entry is called as 'idle' for compatible reason, it shows more information
+** than idle actually.
+**
+**  Start: Start time of this counting period.
+**  End: End time of this counting peroid.
 **  On: Time GPU stays in gcvPOWER_0N.
 **  Off: Time GPU stays in gcvPOWER_0FF.
 **  Idle: Time GPU stays in gcvPOWER_IDLE.
@@ -554,9 +718,8 @@ gc_idle_show(struct seq_file *m, void *data)
     gcsINFO_NODE *node = m->private;
     gckGALDEVICE device = node->device;
     gckKERNEL kernel = _GetValidKernel(device);
+    char str[32];
 
-    gctUINT64 start;
-    gctUINT64 end;
     gctUINT64 on;
     gctUINT64 off;
     gctUINT64 idle;
@@ -565,15 +728,17 @@ gc_idle_show(struct seq_file *m, void *data)
     if (!kernel)
         return -ENXIO;
 
-    gckHARDWARE_QueryStateTimer(kernel->hardware, &start, &end, &on, &off, &idle, &suspend);
+    gckHARDWARE_QueryStateTimer(kernel->hardware, &on, &off, &idle, &suspend);
 
     /* Idle time since last call */
-    seq_printf(m, "Start:   %llu ns\n",  start);
-    seq_printf(m, "End:     %llu ns\n",  end);
-    seq_printf(m, "On:      %llu ns\n",  on);
-    seq_printf(m, "Off:     %llu ns\n",  off);
-    seq_printf(m, "Idle:    %llu ns\n",  idle);
-    seq_printf(m, "Suspend: %llu ns\n",  suspend);
+    print_ull(str, on);
+    seq_printf(m, "On:      %s ns\n",  str);
+    print_ull(str, off);
+    seq_printf(m, "Off:     %s ns\n",  str);
+    print_ull(str, idle);
+    seq_printf(m, "Idle:    %s ns\n",  str);
+    print_ull(str, suspend);
+    seq_printf(m, "Suspend: %s ns\n",  str);
 
     return 0 ;
 }
@@ -634,6 +799,71 @@ gc_dump_trigger_show(struct seq_file *m, void *data)
 
 static int dumpProcess = 0;
 
+static void
+_ShowVideoMemory(
+    struct seq_file *File,
+    gcsDATABASE_PTR Database
+    )
+{
+    gctUINT i = 0;
+
+    static const char * otherCounterNames[] = {
+        "AllocNonPaged",
+        "MapMemory",
+    };
+
+    gcsDATABASE_COUNTERS * otherCounters[] = {
+        &Database->nonPaged,
+        &Database->mapMemory,
+    };
+
+    seq_printf(File, "%-16s %16s %16s %16s\n", "", "Current", "Maximum", "Total");
+
+    /* Print surface type counters. */
+    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
+               "All-Types",
+               Database->vidMem.bytes,
+               Database->vidMem.maxBytes,
+               Database->vidMem.totalBytes);
+
+    for (i = 1; i < gcvVIDMEM_TYPE_COUNT; i++)
+    {
+        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
+                   vidmemTypeStr[i],
+                   Database->vidMemType[i].bytes,
+                   Database->vidMemType[i].maxBytes,
+                   Database->vidMemType[i].totalBytes);
+    }
+    seq_puts(File, "\n");
+
+    /* Print surface pool counters. */
+    seq_printf(File, "%-16s %16llu %16llu %16llu\n",
+               "All-Pools",
+               Database->vidMem.bytes,
+               Database->vidMem.maxBytes,
+               Database->vidMem.totalBytes);
+
+    for (i = 1; i < gcvPOOL_NUMBER_OF_POOLS; i++)
+    {
+        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
+                   poolStr[i],
+                   Database->vidMemPool[i].bytes,
+                   Database->vidMemPool[i].maxBytes,
+                   Database->vidMemPool[i].totalBytes);
+    }
+    seq_puts(File, "\n");
+
+    /* Print other counters. */
+    for (i = 0; i < gcmCOUNTOF(otherCounterNames); i++)
+    {
+        seq_printf(File, "%-16s %16llu %16llu %16llu\n",
+                   otherCounterNames[i],
+                   otherCounters[i]->bytes,
+                   otherCounters[i]->maxBytes,
+                   otherCounters[i]->totalBytes);
+    }
+    seq_puts(File, "\n");
+}
 
 static int gc_vidmem_show(struct seq_file *m, void *unused)
 {
@@ -662,8 +892,8 @@ static int gc_vidmem_show(struct seq_file *m, void *unused)
                  database = database->next)
             {
                 gckOS_GetProcessNameByPid(database->processID, gcmSIZEOF(name), name);
-                seq_printf(m, "VidMem Usage (Process %d: %s):\n", database->processID, name);
-                _ShowCounters(m, database);
+                seq_printf(m, "Memory Usage (Process %u: %s):\n", database->processID, name);
+                _ShowVideoMemory(m, database);
                 seq_puts(m, "\n");
             }
         }
@@ -683,8 +913,8 @@ static int gc_vidmem_show(struct seq_file *m, void *unused)
         }
 
         gckOS_GetProcessNameByPid(dumpProcess, gcmSIZEOF(name), name);
-        seq_printf(m, "VidMem Usage (Process %d: %s):\n", dumpProcess, name);
-        _ShowCounters(m, database);
+        seq_printf(m, "Memory Usage (Process %d: %s):\n", dumpProcess, name);
+        _ShowVideoMemory(m, database);
     }
 
     return 0;
@@ -730,18 +960,19 @@ static int gc_clk_show(struct seq_file* m, void* data)
     gctUINT i;
     gceSTATUS status;
 
+    if (!device)
+        return -ENXIO;
+
     for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
     {
         if (device->kernels[i])
         {
             gckHARDWARE hardware = device->kernels[i]->hardware;
 
-#if gcdENABLE_VG
             if (i == gcvCORE_VG)
             {
                 continue;
             }
-#endif
 
             status = gckHARDWARE_QueryFrequency(hardware);
             if (gcmIS_ERROR(status))
@@ -783,16 +1014,12 @@ _DebugfsInit(
     IN gckGALDEVICE Device
     )
 {
-    gceSTATUS status;
-
+    gceSTATUS status = gcvSTATUS_OK;
     gckDEBUGFS_DIR dir = &Device->debugfsDir;
 
     gcmkONERROR(gckDEBUGFS_DIR_Init(dir, gcvNULL, "gc"));
-
     gcmkONERROR(gckDEBUGFS_DIR_CreateFiles(dir, InfoList, gcmCOUNTOF(InfoList), Device));
 
-    return gcvSTATUS_OK;
-
 OnError:
     return status;
 }
@@ -823,39 +1050,35 @@ _AllocateMemory(
     IN gctSIZE_T Bytes,
     OUT gctPOINTER *Logical,
     OUT gctPHYS_ADDR *Physical,
-    OUT gctUINT32 *PhysAddr
+    OUT gctUINT64 *PhysAddr
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     gctPHYS_ADDR_T physAddr;
 
-    gcmkHEADER_ARG("Device=0x%x Bytes=%lu", Device, Bytes);
+    gcmkHEADER_ARG("Device=%p Bytes=0x%zx", Device, Bytes);
 
     gcmkVERIFY_ARGUMENT(Device != NULL);
     gcmkVERIFY_ARGUMENT(Logical != NULL);
     gcmkVERIFY_ARGUMENT(Physical != NULL);
     gcmkVERIFY_ARGUMENT(PhysAddr != NULL);
 
-    gcmkONERROR(gckOS_AllocateContiguous(
-        Device->os, gcvFALSE, &Bytes, Physical, Logical
+    gcmkONERROR(gckOS_AllocateNonPagedMemory(
+        Device->os, gcvFALSE, gcvALLOC_FLAG_CONTIGUOUS, &Bytes, Physical, Logical
         ));
 
-    gcmkONERROR(gckOS_GetPhysicalAddress(
-        Device->os, *Logical, &physAddr
+    gcmkONERROR(gckOS_GetPhysicalFromHandle(
+        Device->os, *Physical, 0, &physAddr
         ));
 
-    gcmkSAFECASTPHYSADDRT(*PhysAddr, physAddr);
+    *PhysAddr = physAddr;
 
-    /* Success. */
+OnError:
     gcmkFOOTER_ARG(
-        "*Logical=0x%x *Physical=0x%x *PhysAddr=0x%08x",
-        *Logical, *Physical, *PhysAddr
+        "*Logical=%p *Physical=%p *PhysAddr=0x%llx",
+        gcmOPT_POINTER(Logical), gcmOPT_POINTER(Physical), gcmOPT_VALUE(PhysAddr)
         );
 
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
     return status;
 }
 
@@ -863,16 +1086,17 @@ static gceSTATUS
 _FreeMemory(
     IN gckGALDEVICE Device,
     IN gctPOINTER Logical,
-    IN gctPHYS_ADDR Physical)
+    IN gctPHYS_ADDR Physical
+    )
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Device=0x%x Logical=0x%x Physical=0x%x",
+    gcmkHEADER_ARG("Device=%p Logical=%p Physical=%p",
                    Device, Logical, Physical);
 
     gcmkVERIFY_ARGUMENT(Device != NULL);
 
-    status = gckOS_FreeContiguous(
+    status = gckOS_FreeNonPagedMemory(
         Device->os, Physical, Logical,
         ((PLINUX_MDL) Physical)->numPages * PAGE_SIZE
         );
@@ -882,140 +1106,130 @@ _FreeMemory(
 }
 
 static gceSTATUS
-_SetupVidMem(
+_SetupContiguousVidMem(
     IN gckGALDEVICE Device,
-    IN gctUINT32 ContiguousBase,
-    IN gctSIZE_T ContiguousSize,
-    IN gctSIZE_T BankSize,
-    IN gcsDEVICE_CONSTRUCT_ARGS * Args
+    IN const gcsMODULE_PARAMETERS * Args
     )
 {
-    gceSTATUS status;
-    gctUINT32 physAddr = ~0U;
+    gceSTATUS status = gcvSTATUS_OK;
+    gctUINT64 physAddr = ~0ULL;
     gckGALDEVICE device = Device;
 
+    gcmkHEADER_ARG("Device=%p Args=%p", Device, Args);
+
     /* set up the contiguous memory */
-    device->contiguousBase = ContiguousBase;
-    device->contiguousSize = ContiguousSize;
+    device->contiguousBase = Args->contiguousBase;
+    device->contiguousSize = Args->contiguousSize;
+
+    if (Args->contiguousSize == 0)
+    {
+        gcmkFOOTER_NO();
+        return gcvSTATUS_OK;
+    }
 
-    if (ContiguousSize > 0)
+    if (Args->contiguousBase == 0)
     {
-        if (ContiguousBase == 0)
+        while (device->contiguousSize > 0)
         {
-            while (device->contiguousSize > 0)
+            /* Allocate contiguous memory. */
+            status = _AllocateMemory(
+                device,
+                device->contiguousSize,
+                &device->contiguousLogical,
+                &device->contiguousPhysical,
+                &physAddr
+                );
+
+            if (gcmIS_SUCCESS(status))
             {
-                /* Allocate contiguous memory. */
-                status = _AllocateMemory(
-                    device,
+                status = gckVIDMEM_Construct(
+                    device->os,
+                    physAddr,
                     device->contiguousSize,
-                    &device->contiguousLogical,
-                    &device->contiguousPhysical,
-                    &physAddr
+                    64,
+                    Args->bankSize,
+                    &device->contiguousVidMem
                     );
 
                 if (gcmIS_SUCCESS(status))
                 {
-                    status = gckVIDMEM_Construct(
-                        device->os,
-                        physAddr | device->systemMemoryBaseAddress,
-                        device->contiguousSize,
-                        64,
-                        BankSize,
-                        &device->contiguousVidMem
-                        );
-
-                    if (gcmIS_SUCCESS(status))
+                    gckALLOCATOR allocator = ((PLINUX_MDL)device->contiguousPhysical)->allocator;
+                    device->contiguousVidMem->capability = allocator->capability | gcvALLOC_FLAG_MEMLIMIT;
+                    device->contiguousVidMem->physical = device->contiguousPhysical;
+                    device->contiguousBase = physAddr;
+                    if (device->contiguousBase > 0xFFFFFFFFULL)
                     {
-                        device->contiguousVidMem->physical = device->contiguousPhysical;
-                        device->contiguousBase = physAddr;
-                        break;
+                        device->contiguousVidMem->capability &= ~gcvALLOC_FLAG_4GB_ADDR;
                     }
-
-                    gcmkONERROR(_FreeMemory(
-                        device,
-                        device->contiguousLogical,
-                        device->contiguousPhysical
-                        ));
-
-                    device->contiguousLogical  = gcvNULL;
-                    device->contiguousPhysical = gcvNULL;
+                    break;
                 }
 
-                if (device->contiguousSize <= (4 << 20))
-                {
-                    device->contiguousSize = 0;
-                }
-                else
-                {
-                    device->contiguousSize -= (4 << 20);
-                }
+                gcmkONERROR(_FreeMemory(
+                    device,
+                    device->contiguousLogical,
+                    device->contiguousPhysical
+                    ));
+
+                device->contiguousLogical  = gcvNULL;
+                device->contiguousPhysical = gcvNULL;
             }
-        }
-        else
-        {
-            /* Create the contiguous memory heap. */
-            status = gckVIDMEM_Construct(
-                device->os,
-                ContiguousBase | device->systemMemoryBaseAddress,
-                ContiguousSize,
-                64, BankSize,
-                &device->contiguousVidMem
-                );
 
-            if (gcmIS_ERROR(status))
+            if (device->contiguousSize <= (4 << 20))
             {
-                /* Error, disable contiguous memory pool. */
-                device->contiguousVidMem = gcvNULL;
-                device->contiguousSize   = 0;
+                device->contiguousSize = 0;
             }
             else
             {
-                gcmkONERROR(gckOS_RequestReservedMemory(
-                    device->os, ContiguousBase, ContiguousSize,
-                    "galcore contiguous memory",
-                    Args->contiguousRequested,
-                    &device->contiguousPhysical
-                    ));
-
-                device->contiguousVidMem->physical = device->contiguousPhysical;
-                device->requestedContiguousBase = ContiguousBase;
-                device->requestedContiguousSize = ContiguousSize;
-
-                device->contiguousPhysicalName = 0;
-                device->contiguousSize = ContiguousSize;
+                device->contiguousSize -= (4 << 20);
             }
         }
     }
+    else
+    {
+        /* Create the contiguous memory heap. */
+        status = gckVIDMEM_Construct(
+            device->os,
+            Args->contiguousBase,
+            Args->contiguousSize,
+            64,
+            Args->bankSize,
+            &device->contiguousVidMem
+            );
 
-    return gcvSTATUS_OK;
-OnError:
-    return status;
-}
+        if (gcmIS_ERROR(status))
+        {
+            /* Error, disable contiguous memory pool. */
+            device->contiguousVidMem = gcvNULL;
+            device->contiguousSize   = 0;
+        }
+        else
+        {
+            gckALLOCATOR allocator;
 
-void
-_SetupRegisterPhysical(
-    IN gckGALDEVICE Device,
-    IN gcsDEVICE_CONSTRUCT_ARGS * Args
-    )
-{
-    gctINT *irqs = Args->irqs;
-    gctUINT *registerBases = Args->registerBases;
-    gctUINT *registerSizes = Args->registerSizes;
+            gcmkONERROR(gckOS_RequestReservedMemory(
+                device->os, Args->contiguousBase, Args->contiguousSize,
+                "galcore contiguous memory",
+                Args->contiguousRequested,
+                &device->contiguousPhysical
+                ));
 
-    gctINT i = 0;
+            allocator = ((PLINUX_MDL)device->contiguousPhysical)->allocator;
 
-    for (i = 0; i < gcvCORE_COUNT; i++)
-    {
-        if (irqs[i] != -1)
-        {
-            Device->requestedRegisterMemBases[i] = registerBases[i];
-            Device->requestedRegisterMemSizes[i] = registerSizes[i];
+            device->contiguousVidMem->capability = allocator->capability | gcvALLOC_FLAG_MEMLIMIT;
+            device->contiguousVidMem->physical = device->contiguousPhysical;
+            device->requestedContiguousBase = Args->contiguousBase;
+            device->requestedContiguousSize = Args->contiguousSize;
 
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE,
-                           "Get register base %llx of core %d",
-                           registerBases[i], i);
+            device->contiguousPhysName = 0;
+            device->contiguousSize = Args->contiguousSize;
         }
     }
+
+    printk(KERN_INFO "Galcore ContiguousBase=0x%llx ContiguousSize=0x%x\n", device->contiguousBase, (gctUINT32)device->contiguousSize);
+
+OnError:
+    gcmkFOOTER();
+    return status;
 }
 
 /******************************************************************************\
@@ -1030,7 +1244,7 @@ static irqreturn_t isrRoutine(int irq, void *ctxt)
     device = galDevice;
 
     /* Call kernel interrupt notification. */
-    status = gckKERNEL_Notify(device->kernels[core], gcvNOTIFY_INTERRUPT, gcvTRUE);
+    status = gckHARDWARE_Interrupt(device->kernels[core]->hardware);
 
     if (gcmIS_SUCCESS(status))
     {
@@ -1041,58 +1255,13 @@ static irqreturn_t isrRoutine(int irq, void *ctxt)
     return IRQ_NONE;
 }
 
-static int threadRoutine(void *ctxt)
-{
-    gckGALDEVICE device = galDevice;
-    gceCORE core = (gceCORE) gcmPTR2INT32(ctxt);
-    gctUINT i;
-
-    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
-                   "Starting isr Thread with extension=%p",
-                   device);
-
-    if (core != gcvCORE_VG)
-    {
-        /* Make kernel update page table of this thread to include entry related to command buffer.*/
-        for (i = 0; i < gcdCOMMAND_QUEUES; i++)
-        {
-            gctUINT32 data = *(gctUINT32_PTR)device->kernels[core]->command->queues[i].logical;
-
-            data = 0;
-        }
-    }
-
-    for (;;)
-    {
-        static int down;
-
-        down = down_interruptible(&device->semas[core]);
-        if (down); /*To make gcc 4.6 happye*/
-
-        if (device->killThread == gcvTRUE)
-        {
-            /* The daemon exits. */
-            while (!kthread_should_stop())
-            {
-                gckOS_Delay(device->os, 1);
-            }
-
-            return 0;
-        }
-
-        gckKERNEL_Notify(device->kernels[core],
-                         gcvNOTIFY_INTERRUPT,
-                         gcvFALSE);
-    }
-}
-
 static irqreturn_t isrRoutineVG(int irq, void *ctxt)
 {
 #if gcdENABLE_VG
     gceSTATUS status;
     gckGALDEVICE device;
 
-    device = (gckGALDEVICE) ctxt;
+    device = galDevice;
 
     /* Serve the interrupt. */
     status = gckVGINTERRUPT_Enque(device->kernels[gcvCORE_VG]->vg->interrupt);
@@ -1106,58 +1275,195 @@ static irqreturn_t isrRoutineVG(int irq, void *ctxt)
 #endif
 }
 
-/******************************************************************************\
-******************************* gckGALDEVICE Code ******************************
-\******************************************************************************/
+static const char *isrNames[] =
+{
+    "galcore:0",
+    "galcore:3d-1",
+    "galcore:3d-2",
+    "galcore:3d-3",
+    "galcore:3d-4",
+    "galcore:3d-5",
+    "galcore:3d-6",
+    "galcore:3d-7",
+    "galcore:2d",
+    "galcore:vg",
+#if gcdDEC_ENABLE_AHB
+    "galcore:dec"
+#endif
+};
 
 static gceSTATUS
-_StartThread(
-    IN int (*ThreadRoutine)(void *data),
+_SetupIsr(
     IN gceCORE Core
     )
 {
-    gceSTATUS status;
-    gckGALDEVICE device = galDevice;
-    struct task_struct * task;
+    gctINT ret = 0;
+    gceSTATUS status = gcvSTATUS_OK;
+    gckGALDEVICE Device = galDevice;
+    irq_handler_t handler;
 
-    if (device->kernels[Core] != gcvNULL)
+    gcmkHEADER_ARG("Device=%p Core=%d", Device, Core);
+
+    gcmkVERIFY_ARGUMENT(Device != NULL);
+
+    if (Device->irqLines[Core] < 0)
     {
-        /* Start the kernel thread. */
-        task = kthread_run(ThreadRoutine, (void *)Core, "galcore deamon thread for core[%d]", Core);
+        gcmkONERROR(gcvSTATUS_GENERIC_IO);
+    }
 
-        if (IS_ERR(task))
-        {
-            gcmkTRACE_ZONE(
-                gcvLEVEL_ERROR, gcvZONE_DRIVER,
-                "%s(%d): Could not start the kernel thread.\n",
-                __FUNCTION__, __LINE__
-                );
+    gcmSTATIC_ASSERT(gcvCORE_COUNT == gcmCOUNTOF(isrNames),
+                     "isrNames array does not match core types");
 
-            gcmkONERROR(gcvSTATUS_GENERIC_IO);
-        }
+    handler = (Core == gcvCORE_VG) ? isrRoutineVG : isrRoutine;
 
-        device->threadCtxts[Core]         = task;
-        device->threadInitializeds[Core]  = gcvTRUE;
-    }
-    else
+    /*
+     * Hook up the isr based on the irq line.
+     * For shared irq, device-id can not be 0, but CORE_MAJOR value is.
+     * Add by 1 here and subtract by 1 in isr to fix the issue.
+     */
+    ret = request_irq(
+        Device->irqLines[Core], handler, gcdIRQF_FLAG,
+        isrNames[Core], (void *)(uintptr_t)(Core + 1)
+        );
+
+    if (ret != 0)
     {
-        device->threadInitializeds[Core]  = gcvFALSE;
+        gcmkTRACE_ZONE(
+            gcvLEVEL_ERROR, gcvZONE_DRIVER,
+            "%s(%d): Could not register irq line %d (error=%d)\n",
+            __FUNCTION__, __LINE__,
+            Device->irqLines[Core], ret
+            );
+
+        gcmkONERROR(gcvSTATUS_GENERIC_IO);
     }
 
-    return gcvSTATUS_OK;
+    /* Mark ISR as initialized. */
+    Device->isrInitializeds[Core] = gcvTRUE;
 
 OnError:
+    gcmkFOOTER();
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckGALDEVICE_Construct
-**
-**  Constructor.
-**
-**  INPUT:
-**
+static gceSTATUS
+_ReleaseIsr(
+    IN gceCORE Core
+    )
+{
+    gckGALDEVICE Device = galDevice;
+
+    gcmkHEADER_ARG("Device=%p Core=%d", Device, Core);
+
+    gcmkVERIFY_ARGUMENT(Device != NULL);
+
+    /* release the irq */
+    if (Device->isrInitializeds[Core])
+    {
+        free_irq(Device->irqLines[Core], (void *)(uintptr_t)(Core + 1));
+        Device->isrInitializeds[Core] = gcvFALSE;
+    }
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+}
+
+static int threadRoutine(void *ctxt)
+{
+    gckGALDEVICE device = galDevice;
+    gceCORE core = (gceCORE) gcmPTR2INT32(ctxt);
+
+    gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DRIVER,
+                   "Starting isr Thread with extension=%p",
+                   device);
+
+
+    for (;;)
+    {
+        int down;
+
+        down = down_interruptible(&device->semas[core]);
+        if (down) {} /* To make gcc 4.6 happy. */
+
+        if (unlikely(device->killThread))
+        {
+            /* The daemon exits. */
+            while (!kthread_should_stop())
+            {
+                gckOS_Delay(device->os, 1);
+            }
+
+            return 0;
+        }
+
+        gckKERNEL_Notify(device->kernels[core], gcvNOTIFY_INTERRUPT);
+    }
+}
+
+static gceSTATUS
+_StartThread(
+    IN gckGALDEVICE Device,
+    IN gceCORE Core
+    )
+{
+    gceSTATUS status = gcvSTATUS_OK;
+    gckGALDEVICE device = galDevice;
+    struct task_struct * task;
+
+    if (device->kernels[Core] != gcvNULL)
+    {
+        /* Start the kernel thread. */
+        task = kthread_run(threadRoutine, (void *)Core,
+                "galcore_deamon/%d", Core);
+
+        if (IS_ERR(task))
+        {
+            gcmkTRACE_ZONE(
+                gcvLEVEL_ERROR, gcvZONE_DRIVER,
+                "%s(%d): Could not start the kernel thread.\n",
+                __FUNCTION__, __LINE__
+                );
+
+            gcmkONERROR(gcvSTATUS_GENERIC_IO);
+        }
+
+        device->threadCtxts[Core]         = task;
+        device->threadInitializeds[Core]  = gcvTRUE;
+    }
+    else
+    {
+        device->threadInitializeds[Core]  = gcvFALSE;
+    }
+
+OnError:
+    return status;
+}
+
+static void
+_StopThread(
+    gckGALDEVICE Device,
+    gceCORE Core
+    )
+{
+    if (Device->threadInitializeds[Core])
+    {
+        Device->killThread = gcvTRUE;
+        up(&Device->semas[Core]);
+
+        kthread_stop(Device->threadCtxts[Core]);
+        Device->threadCtxts[Core]        = gcvNULL;
+        Device->threadInitializeds[Core] = gcvFALSE;
+    }
+}
+
+/*******************************************************************************
+**
+**  gckGALDEVICE_Construct
+**
+**  Constructor.
+**
+**  INPUT:
+**
 **  OUTPUT:
 **
 **      gckGALDEVICE * Device
@@ -1166,61 +1472,22 @@ OnError:
 */
 gceSTATUS
 gckGALDEVICE_Construct(
-    IN gctINT IrqLine,
-    IN gctUINT32 RegisterMemBase,
-    IN gctSIZE_T RegisterMemSize,
-    IN gctINT IrqLine2D,
-    IN gctUINT32 RegisterMemBase2D,
-    IN gctSIZE_T RegisterMemSize2D,
-    IN gctINT IrqLineVG,
-    IN gctUINT32 RegisterMemBaseVG,
-    IN gctSIZE_T RegisterMemSizeVG,
-    IN gctUINT32 ContiguousBase,
-    IN gctSIZE_T ContiguousSize,
-    IN gctUINT32 ExternalBase,
-    IN gctSIZE_T ExternalSize,
-    IN gctSIZE_T BankSize,
-    IN gctINT FastClear,
-    IN gctINT Compression,
-    IN gctUINT32 PhysBaseAddr,
-    IN gctUINT32 PhysSize,
-    IN gctINT Signal,
-    IN gctUINT LogFileSize,
-    IN gctINT PowerManagement,
-    IN gctINT GpuProfiler,
-    IN gcsDEVICE_CONSTRUCT_ARGS * Args,
+    IN gcsPLATFORM * Platform,
+    IN const gcsMODULE_PARAMETERS * Args,
     OUT gckGALDEVICE *Device
     )
 {
-    gctUINT32 internalBaseAddress = 0, internalAlignment = 0;
-    gctUINT32 externalAlignment = 0;
-    gctUINT32 physical;
+    gckKERNEL kernel = gcvNULL;
     gckGALDEVICE device;
-    gceSTATUS status;
     gctINT32 i;
     gceHARDWARE_TYPE type;
-    gckKERNEL kernel = gcvNULL;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("IrqLine=%d RegisterMemBase=0x%08x RegisterMemSize=%u "
-                   "IrqLine2D=%d RegisterMemBase2D=0x%08x RegisterMemSize2D=%u "
-                   "IrqLineVG=%d RegisterMemBaseVG=0x%08x RegisterMemSizeVG=%u "
-                   "ContiguousBase=0x%08x ContiguousSize=%lu BankSize=%lu "
-                   "FastClear=%d Compression=%d PhysBaseAddr=0x%x PhysSize=%d Signal=%d",
-                   IrqLine, RegisterMemBase, RegisterMemSize,
-                   IrqLine2D, RegisterMemBase2D, RegisterMemSize2D,
-                   IrqLineVG, RegisterMemBaseVG, RegisterMemSizeVG,
-                   ContiguousBase, ContiguousSize, BankSize, FastClear, Compression,
-                   PhysBaseAddr, PhysSize, Signal);
-
-#if !gcdENABLE_3D
-    IrqLine = -1;
-#endif
+    gcmkHEADER_ARG("Platform=%p Args=%p", Platform, Args);
 
-#if !gcdENABLE_2D
-    IrqLine2D = -1;
-#endif
     /* Allocate device structure. */
     device = kmalloc(sizeof(struct _gckGALDEVICE), GFP_KERNEL | __GFP_NOWARN);
+
     if (!device)
     {
         gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
@@ -1228,74 +1495,29 @@ gckGALDEVICE_Construct(
 
     memset(device, 0, sizeof(struct _gckGALDEVICE));
 
-    device->dbgNode = gcvNULL;
-
-    device->platform = Args->platform;
-
+    device->platform = Platform;
     device->args = *Args;
 
-    /* set up the contiguous memory */
-    device->contiguousSize = ContiguousSize;
-
     /* Clear irq lines. */
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
         device->irqLines[i] = -1;
-    }
-
-    _SetupRegisterPhysical(device, Args);
-
-    if (IrqLine != -1)
-    {
-        device->requestedRegisterMemBases[gcvCORE_MAJOR] = RegisterMemBase;
-        device->requestedRegisterMemSizes[gcvCORE_MAJOR] = RegisterMemSize;
-    }
-
-    if (IrqLine2D != -1)
-    {
-        device->requestedRegisterMemBases[gcvCORE_2D] = RegisterMemBase2D;
-        device->requestedRegisterMemSizes[gcvCORE_2D] = RegisterMemSize2D;
-    }
-
-    if (IrqLineVG != -1)
-    {
-        device->requestedRegisterMemBases[gcvCORE_VG] = RegisterMemBaseVG;
-        device->requestedRegisterMemSizes[gcvCORE_VG] = RegisterMemSizeVG;
-    }
-#if gcdDEC_ENABLE_AHB
-    {
-        device->requestedRegisterMemBases[gcvCORE_DEC] = Args->registerMemBaseDEC300;
-        device->requestedRegisterMemSizes[gcvCORE_DEC] = Args->registerMemSizeDEC300;
-    }
+#if USE_LINUX_PCIE
+        device->bars[i] = -1;
 #endif
-
-
-    for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
-    {
-        if (Args->irqs[i] != -1)
-        {
-            device->requestedRegisterMemBases[i] = Args->registerBases[i];
-            device->requestedRegisterMemSizes[i] = Args->registerSizes[i];
-
-            gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_DEVICE,
-                           "%s(%d): Core = %d, RegiseterBase = %x",
-                           __FUNCTION__, __LINE__,
-                           i, Args->registerBases[i]
-                           );
-        }
     }
 
-    /* Initialize the ISR. */
-    device->irqLines[gcvCORE_MAJOR] = IrqLine;
-    device->irqLines[gcvCORE_2D] = IrqLine2D;
-    device->irqLines[gcvCORE_VG] = IrqLineVG;
-
-    for (i = gcvCORE_MAJOR; i < gcvCORE_COUNT; i++)
+    for (i = 0; i < gcvCORE_COUNT; i++)
     {
-        if (Args->irqs[i] != -1)
-        {
-            device->irqLines[i] = Args->irqs[i];
-        }
+        device->irqLines[i]                  = Args->irqs[i];
+        device->requestedRegisterMemBases[i] = Args->registerBases[i];
+        device->requestedRegisterMemSizes[i] = Args->registerSizes[i];
+#if USE_LINUX_PCIE
+        device->bars[i]                      = Args->bars[i];
+#endif
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, _GC_OBJ_ZONE,
+                       "Get register base %llx of core %d",
+                       Args->registerBases[i], i);
     }
 
     device->requestedContiguousBase  = 0;
@@ -1303,58 +1525,57 @@ gckGALDEVICE_Construct(
 
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
-        physical = device->requestedRegisterMemBases[i];
+        unsigned long physical;
+        physical = (unsigned long)device->requestedRegisterMemBases[i];
 
         /* Set up register memory region. */
         if (physical != 0)
         {
-            if (Args->registerMemMapped)
+            if (Args->registerBasesMapped[i])
             {
-                device->registerBases[i] = Args->registerMemAddress;
+                device->registerBases[i] = Args->registerBasesMapped[i];
                 device->requestedRegisterMemBases[i] = 0;
-
             }
             else
             {
 #if USE_LINUX_PCIE
-                device->registerBases[i] = (gctPOINTER) pci_iomap(device->platform->device, 1,
-                        device->requestedRegisterMemSizes[i]);
-#else
-                if (!request_mem_region(physical, device->requestedRegisterMemSizes[i], "galcore register region"))
+                gcmkPRINT("register should be mapped in platform layer");
+#endif
+                if (!request_mem_region(physical,
+                        device->requestedRegisterMemSizes[i],
+                        "galcore register region"))
                 {
                     gcmkTRACE_ZONE(
                             gcvLEVEL_ERROR, gcvZONE_DRIVER,
-                            "%s(%d): Failed to claim %lu bytes @ 0x%zx\n",
+                            "%s(%d): Failed to claim %lu bytes @ 0x%llx\n",
                             __FUNCTION__, __LINE__,
-                            physical, device->requestedRegisterMemSizes[i]
-                     );
+                            device->requestedRegisterMemSizes[i], physical
+                            );
 
                     gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
                 }
+
                 device->registerBases[i] = (gctPOINTER)ioremap_nocache(
                         physical, device->requestedRegisterMemSizes[i]);
-#endif
 
                 if (device->registerBases[i] == gcvNULL)
                 {
                     gcmkTRACE_ZONE(
                             gcvLEVEL_ERROR, gcvZONE_DRIVER,
-                            "%s(%d): Unable to map %ld bytes @ 0x%08X\n",
+                            "%s(%d): Unable to map %ld bytes @ 0x%zx\n",
                             __FUNCTION__, __LINE__,
                             physical, device->requestedRegisterMemSizes[i]
-                    );
+                            );
 
                     gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
                 }
             }
-
-            physical += device->requestedRegisterMemSizes[i];
         }
     }
 
     /* Set the base address */
-    device->baseAddress = device->physBase = PhysBaseAddr;
-    device->physSize = PhysSize;
+    device->baseAddress = device->physBase = Args->baseAddress;
+    device->physSize = Args->physSize;
 
     /* Construct the gckOS object. */
     gcmkONERROR(gckOS_Construct(device, &device->os));
@@ -1367,34 +1588,50 @@ gckGALDEVICE_Construct(
         gcmkONERROR(gctaOS_ConstructOS(device->os, &device->taos));
     }
 
-    gcmkONERROR(_SetupVidMem(device, ContiguousBase, ContiguousSize, BankSize, Args));
+    /* Setup contiguous video memory pool. */
+    gcmkONERROR(_SetupContiguousVidMem(device, Args));
 
     /* Set external base and size */
-    device->externalBase = ExternalBase;
-    device->externalSize = ExternalSize;
+    device->externalBase = Args->externalBase;
+    device->externalSize = Args->externalSize;
 
     if (device->irqLines[gcvCORE_MAJOR] != -1)
     {
-        gcmkONERROR(gcTA_Construct(device->taos, gcvCORE_MAJOR, &globalTA[gcvCORE_MAJOR]));
+        gcmkONERROR(gcTA_Construct(
+            device->taos,
+            gcvCORE_MAJOR,
+            &globalTA[gcvCORE_MAJOR]
+            ));
 
-        gcmkONERROR(gckDEVICE_AddCore(device->device, gcvCORE_MAJOR, Args->chipIDs[gcvCORE_MAJOR], device, &device->kernels[gcvCORE_MAJOR]));
+        gcmkONERROR(gckDEVICE_AddCore(
+            device->device,
+            gcvCORE_MAJOR,
+            Args->chipIDs[gcvCORE_MAJOR],
+            device,
+            &device->kernels[gcvCORE_MAJOR]
+            ));
 
         gcmkONERROR(gckHARDWARE_SetFastClear(
-            device->kernels[gcvCORE_MAJOR]->hardware, FastClear, Compression
+            device->kernels[gcvCORE_MAJOR]->hardware,
+            Args->fastClear,
+            Args->compression
             ));
 
-        gcmkONERROR(gckHARDWARE_SetPowerManagement(
-            device->kernels[gcvCORE_MAJOR]->hardware, PowerManagement
+        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
+            device->kernels[gcvCORE_MAJOR]->hardware,
+            Args->powerManagement
             ));
 
 #if gcdENABLE_FSCALE_VAL_ADJUST
         gcmkONERROR(gckHARDWARE_SetMinFscaleValue(
-            device->kernels[gcvCORE_MAJOR]->hardware, Args->gpu3DMinClock
+            device->kernels[gcvCORE_MAJOR]->hardware,
+            Args->gpu3DMinClock
             ));
 #endif
 
         gcmkONERROR(gckHARDWARE_SetGpuProfiler(
-            device->kernels[gcvCORE_MAJOR]->hardware, GpuProfiler
+            device->kernels[gcvCORE_MAJOR]->hardware,
+            Args->gpuProfiler
             ));
     }
     else
@@ -1404,10 +1641,19 @@ gckGALDEVICE_Construct(
 
     if (device->irqLines[gcvCORE_2D] != -1)
     {
-        gcmkONERROR(gckDEVICE_AddCore(device->device, gcvCORE_2D, gcvCHIP_ID_DEFAULT, device, &device->kernels[gcvCORE_2D]));
+        gcmkONERROR(gckDEVICE_AddCore(
+            device->device,
+            gcvCORE_2D,
+            gcvCHIP_ID_DEFAULT,
+            device,
+            &device->kernels[gcvCORE_2D]
+            ));
 
         /* Verify the hardware type */
-        gcmkONERROR(gckHARDWARE_GetType(device->kernels[gcvCORE_2D]->hardware, &type));
+        gcmkONERROR(gckHARDWARE_GetType(
+            device->kernels[gcvCORE_2D]->hardware,
+            &type
+            ));
 
         if (type != gcvHARDWARE_2D)
         {
@@ -1421,8 +1667,9 @@ gckGALDEVICE_Construct(
             gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
         }
 
-        gcmkONERROR(gckHARDWARE_SetPowerManagement(
-            device->kernels[gcvCORE_2D]->hardware, PowerManagement
+        gcmkONERROR(gckHARDWARE_EnablePowerManagement(
+            device->kernels[gcvCORE_2D]->hardware,
+            Args->powerManagement
             ));
 
 #if gcdENABLE_FSCALE_VAL_ADJUST
@@ -1439,11 +1686,17 @@ gckGALDEVICE_Construct(
     if (device->irqLines[gcvCORE_VG] != -1)
     {
 #if gcdENABLE_VG
-        gcmkONERROR(gckDEVICE_AddCore(device->device, gcvCORE_VG, gcvCHIP_ID_DEFAULT, device, &device->kernels[gcvCORE_VG]));
+        gcmkONERROR(gckDEVICE_AddCore(
+            device->device,
+            gcvCORE_VG,
+            gcvCHIP_ID_DEFAULT,
+            device,
+            &device->kernels[gcvCORE_VG]
+            ));
 
-        gcmkONERROR(gckVGHARDWARE_SetPowerManagement(
+        gcmkONERROR(gckVGHARDWARE_EnablePowerManagement(
             device->kernels[gcvCORE_VG]->vg->hardware,
-            PowerManagement
+            Args->powerManagement
             ));
 #endif
     }
@@ -1455,22 +1708,36 @@ gckGALDEVICE_Construct(
     /* Add core for multiple core. */
     for (i = gcvCORE_3D1; i <= gcvCORE_3D_MAX; i++)
     {
-        if (Args->irqs[i] != -1)
+        if (device->irqLines[i] != -1)
         {
-            gcmkONERROR(gcTA_Construct(device->taos, (gceCORE)i, &globalTA[i]));
-            gckDEVICE_AddCore(device->device, i, Args->chipIDs[i], device, &device->kernels[i]);
+            gcmkONERROR(gcTA_Construct(
+                device->taos,
+                (gceCORE)i,
+                &globalTA[i]
+                ));
+
+            gckDEVICE_AddCore(
+                device->device,
+                i,
+                Args->chipIDs[i],
+                device,
+                &device->kernels[i]
+                );
 
-            gcmkONERROR(
-            gckHARDWARE_SetFastClear(device->kernels[i]->hardware,
-                 FastClear,
-                Compression));
+            gcmkONERROR(gckHARDWARE_SetFastClear(
+                device->kernels[i]->hardware,
+                Args->fastClear,
+                Args->compression
+                ));
 
-            gcmkONERROR(gckHARDWARE_SetPowerManagement(
-                device->kernels[i]->hardware, PowerManagement
+            gcmkONERROR(gckHARDWARE_EnablePowerManagement(
+                device->kernels[i]->hardware,
+                Args->powerManagement
                 ));
 
             gcmkONERROR(gckHARDWARE_SetGpuProfiler(
-                device->kernels[i]->hardware, GpuProfiler
+                device->kernels[i]->hardware,
+                Args->gpuProfiler
                 ));
         }
     }
@@ -1478,89 +1745,38 @@ gckGALDEVICE_Construct(
     /* Initialize the kernel thread semaphores. */
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
-        if (device->irqLines[i] != -1) sema_init(&device->semas[i], 0);
-    }
-
-    device->signal = Signal;
-
-    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
-    {
-        if (device->kernels[i] != gcvNULL) break;
-    }
-
-    if (i == gcdMAX_GPU_COUNT)
-    {
-        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-    }
-
-#if gcdENABLE_VG
-    if (i == gcvCORE_VG)
-    {
-        /* Query the ceiling of the system memory. */
-        gcmkONERROR(gckVGHARDWARE_QuerySystemMemory(
-                device->kernels[i]->vg->hardware,
-                &device->systemMemorySize,
-                &device->systemMemoryBaseAddress
-                ));
-    }
-    else
-#endif
-    {
-        /* Query the ceiling of the system memory. */
-        gcmkONERROR(gckHARDWARE_QuerySystemMemory(
-                device->kernels[i]->hardware,
-                &device->systemMemorySize,
-                &device->systemMemoryBaseAddress
-                ));
+        if (device->irqLines[i] != -1 && device->kernels[i])
+        {
+            sema_init(&device->semas[i], 0);
+        }
     }
 
-    /* Grab the first availiable kernel */
+    /* Grab the first valid kernel. */
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
-        if (device->irqLines[i] != -1)
+        if (device->kernels[i] != gcvNULL)
         {
             kernel = device->kernels[i];
             break;
         }
     }
 
-    /* Set up the internal memory region. */
-    if (device->internalSize > 0)
+    if (!kernel)
     {
-        status = gckVIDMEM_Construct(
-            device->os,
-            internalBaseAddress, device->internalSize, internalAlignment,
-            0, &device->internalVidMem
-            );
-
-        if (gcmIS_ERROR(status))
-        {
-            /* Error, disable internal heap. */
-            device->internalSize = 0;
-        }
-        else
-        {
-            /* Map internal memory. */
-            device->internalLogical
-                = (gctPOINTER) ioremap_nocache(physical, device->internalSize);
-
-            if (device->internalLogical == gcvNULL)
-            {
-                gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
-            }
-
-            device->internalPhysical = (gctPHYS_ADDR)(gctUINTPTR_T) physical;
-            physical += device->internalSize;
-        }
+        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
     }
 
+
     if (device->externalSize > 0)
     {
         /* create the external memory heap */
         status = gckVIDMEM_Construct(
             device->os,
-            device->externalBase, device->externalSize, externalAlignment,
-            0, &device->externalVidMem
+            device->externalBase,
+            device->externalSize,
+            64,
+            0,
+            &device->externalVidMem
             );
 
         if (gcmIS_ERROR(status))
@@ -1578,52 +1794,38 @@ gckGALDEVICE_Construct(
                     gcvTRUE,
                     &device->externalPhysical
                     ));
+
             device->externalVidMem->physical = device->externalPhysical;
         }
     }
 
     if (device->internalPhysical)
     {
-        device->internalPhysicalName = gcmPTR_TO_NAME(device->internalPhysical);
+        device->internalPhysName = gcmPTR_TO_NAME(device->internalPhysical);
     }
 
     if (device->externalPhysical)
     {
-        device->externalPhysicalName = gcmPTR_TO_NAME(device->externalPhysical);
+        device->externalPhysName = gcmPTR_TO_NAME(device->externalPhysical);
     }
 
     if (device->contiguousPhysical)
     {
-        device->contiguousPhysicalName = gcmPTR_TO_NAME(device->contiguousPhysical);
+        device->contiguousPhysName = gcmPTR_TO_NAME(device->contiguousPhysical);
     }
 
+    gcmkONERROR(_DebugfsInit(device));
+
     /* Return pointer to the device. */
     *Device = galDevice = device;
 
-    gcmkONERROR(_DebugfsInit(device));
-
-    if (gckDEBUGFS_CreateNode(
-            device, LogFileSize, device->debugfsDir.root ,DEBUG_FILE, &(device->dbgNode)))
-    {
-        gcmkTRACE_ZONE(
-            gcvLEVEL_ERROR, gcvZONE_DRIVER,
-            "%s(%d): Failed to create  the debug file system  %s/%s \n",
-            __FUNCTION__, __LINE__,
-            PARENT_FILE, DEBUG_FILE
-        );
-    }
-    else if (LogFileSize)
+OnError:
+    if (gcmIS_ERROR(status))
     {
-        gckDEBUGFS_SetCurrentNode(device->dbgNode);
+        /* Roll back. */
+        gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
     }
 
-    gcmkFOOTER_ARG("*Device=0x%x", * Device);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Roll back. */
-    gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
-
     gcmkFOOTER();
     return status;
 }
@@ -1650,37 +1852,73 @@ gceSTATUS
 gckGALDEVICE_Destroy(
     gckGALDEVICE Device)
 {
-    gctINT i;
+    gctINT i, j = 0;
     gckKERNEL kernel = gcvNULL;
 
-    gcmkHEADER_ARG("Device=0x%x", Device);
+    gcmkHEADER_ARG("Device=%p", Device);
 
     if (Device != gcvNULL)
     {
-        /* Grab the first availiable kernel */
+        /* Grab the first available kernel */
         for (i = 0; i < gcdMAX_GPU_COUNT; i++)
         {
-            if (Device->irqLines[i] != -1)
+            if (Device->kernels[i])
             {
                 kernel = Device->kernels[i];
                 break;
             }
         }
 
-        if (Device->internalPhysicalName != 0)
+        if (kernel)
         {
-            gcmRELEASE_NAME(Device->internalPhysicalName);
-            Device->internalPhysicalName = 0;
-        }
-        if (Device->externalPhysicalName != 0)
-        {
-            gcmRELEASE_NAME(Device->externalPhysicalName);
-            Device->externalPhysicalName = 0;
+            if (Device->internalPhysName != 0)
+            {
+                gcmRELEASE_NAME(Device->internalPhysName);
+                Device->internalPhysName = 0;
+            }
+            if (Device->externalPhysName != 0)
+            {
+                gcmRELEASE_NAME(Device->externalPhysName);
+                Device->externalPhysName = 0;
+            }
+            if (Device->contiguousPhysName != 0)
+            {
+                gcmRELEASE_NAME(Device->contiguousPhysName);
+                Device->contiguousPhysName = 0;
+            }
         }
-        if (Device->contiguousPhysicalName != 0)
+
+        /* Destroy per-core SRAM heap. */
+        if (Device->args.sRAMMode)
         {
-            gcmRELEASE_NAME(Device->contiguousPhysicalName);
-            Device->contiguousPhysicalName = 0;
+            for (i = 0; i <= gcvCORE_3D_MAX; i++)
+            {
+                kernel = Device->kernels[i];
+
+                if (kernel && kernel->sRAMNonExclusive)
+                {
+                    for (j = gcvSRAM_EXTERNAL0; j < gcvSRAM_COUNT; j++)
+                    {
+                        if (kernel->sRAMPhysical[j] != gcvNULL)
+                        {
+                            /* Release reserved SRAM memory. */
+                            gckOS_ReleaseReservedMemory(
+                                Device->os,
+                                kernel->sRAMPhysical[j]
+                                );
+
+                            kernel->sRAMPhysical[j] = gcvNULL;
+                        }
+
+                        if (kernel->sRAMVideoMem[j] != gcvNULL)
+                        {
+                            /* Destroy the SRAM contiguous heap. */
+                            gcmkVERIFY_OK(gckVIDMEM_Destroy(kernel->sRAMVideoMem[j]));
+                            kernel->sRAMVideoMem[j] = gcvNULL;
+                        }
+                    }
+                }
+            }
         }
 
         for (i = 0; i < gcdMAX_GPU_COUNT; i++)
@@ -1725,6 +1963,26 @@ gckGALDEVICE_Destroy(
             Device->externalVidMem = gcvNULL;
         }
 
+        if (Device->device)
+        {
+            gcmkVERIFY_OK(gckDEVICE_Destroy(Device->os, Device->device));
+
+            for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+            {
+                if (globalTA[i])
+                {
+                    gcTA_Destroy(globalTA[i]);
+                    globalTA[i] = gcvNULL;
+                }
+            }
+
+            Device->device = gcvNULL;
+        }
+
+        /*
+         * Destroy contiguous memory pool after gckDEVICE destroyed. gckDEVICE
+         * may allocates GPU memory types from SYSTEM pool.
+         */
         if (Device->contiguousPhysical != gcvNULL)
         {
             if (Device->requestedContiguousBase == 0)
@@ -1764,14 +2022,9 @@ gckGALDEVICE_Destroy(
                 /* Unmap register memory. */
                 if (Device->requestedRegisterMemBases[i] != 0)
                 {
-#if USE_LINUX_PCIE
-                    pci_iounmap(Device->platform->device, Device->registerBases[i]);
-#else
-
                     iounmap(Device->registerBases[i]);
                     release_mem_region(Device->requestedRegisterMemBases[i],
                             Device->requestedRegisterMemSizes[i]);
-#endif
                 }
 
                 Device->registerBases[i] = gcvNULL;
@@ -1780,21 +2033,6 @@ gckGALDEVICE_Destroy(
             }
         }
 
-        if (Device->device)
-        {
-            gcmkVERIFY_OK(gckDEVICE_Destroy(Device->os, Device->device));
-
-            for (i = 0; i < gcdMAX_GPU_COUNT; i++)
-            {
-                if (globalTA[i])
-                {
-                    gcTA_Destroy(globalTA[i]);
-                    globalTA[i] = gcvNULL;
-                }
-            }
-
-            Device->device = gcvNULL;
-        }
 
         if (Device->taos)
         {
@@ -1809,17 +2047,6 @@ gckGALDEVICE_Destroy(
             Device->os = gcvNULL;
         }
 
-        if (Device->dbgNode)
-        {
-            gckDEBUGFS_FreeNode(Device->dbgNode);
-
-            if(Device->dbgNode != gcvNULL)
-            {
-                kfree(Device->dbgNode);
-                Device->dbgNode = gcvNULL;
-            }
-        }
-
         _DebugfsCleanup(Device);
 
         /* Free the device. */
@@ -1830,306 +2057,6 @@ gckGALDEVICE_Destroy(
     return gcvSTATUS_OK;
 }
 
-static const char *isrNames[] =
-{
-    "galcore:0",
-    "galcore:3d-1",
-    "galcore:3d-2",
-    "galcore:3d-3",
-    "galcore:3d-4",
-    "galcore:3d-5",
-    "galcore:3d-6",
-    "galcore:3d-7",
-    "galcore:2d",
-    "galcore:vg",
-#if gcdDEC_ENABLE_AHB
-    "galcore:dec"
-#endif
-};
-
-/*******************************************************************************
-**
-**  gckGALDEVICE_Setup_ISR
-**
-**  Start the ISR routine.
-**
-**  INPUT:
-**
-**      gckGALDEVICE Device
-**          Pointer to an gckGALDEVICE object.
-**
-**  OUTPUT:
-**
-**      Nothing.
-**
-**  RETURNS:
-**
-**      gcvSTATUS_OK
-**          Setup successfully.
-**      gcvSTATUS_GENERIC_IO
-**          Setup failed.
-*/
-gceSTATUS
-gckGALDEVICE_Setup_ISR(
-    IN gceCORE Core
-    )
-{
-    gceSTATUS status;
-    gctINT ret = 0;
-    gckGALDEVICE Device = galDevice;
-
-    gcmkHEADER_ARG("Device=0x%x Core=%d", Device, Core);
-
-    gcmkVERIFY_ARGUMENT(Device != NULL);
-
-    if (Device->irqLines[Core] < 0)
-    {
-        gcmkONERROR(gcvSTATUS_GENERIC_IO);
-    }
-
-#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || (__GNUC__ > 4))
-    {
-        _Static_assert(gcvCORE_COUNT == gcmCOUNTOF(isrNames),
-                       "Core count is lager than isrNames size");
-    }
-#endif
-
-    /* Hook up the isr based on the irq line. */
-    ret = request_irq(
-        Device->irqLines[Core], isrRoutine, gcdIRQF_FLAG,
-        isrNames[Core], (void *)(uintptr_t)(Core + 1)
-        );
-
-    if (ret != 0)
-    {
-        gcmkTRACE_ZONE(
-            gcvLEVEL_ERROR, gcvZONE_DRIVER,
-            "%s(%d): Could not register irq line %d (error=%d)\n",
-            __FUNCTION__, __LINE__,
-            Device->irqLines[Core], ret
-            );
-
-        gcmkONERROR(gcvSTATUS_GENERIC_IO);
-    }
-
-    /* Mark ISR as initialized. */
-    Device->isrInitializeds[Core] = gcvTRUE;
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckGALDEVICE_Setup_ISR_VG(
-    IN gckGALDEVICE Device
-    )
-{
-    gceSTATUS status;
-    gctINT ret;
-
-    gcmkHEADER_ARG("Device=0x%x", Device);
-
-    gcmkVERIFY_ARGUMENT(Device != NULL);
-
-    if (Device->irqLines[gcvCORE_VG] < 0)
-    {
-        gcmkONERROR(gcvSTATUS_GENERIC_IO);
-    }
-
-    /* Hook up the isr based on the irq line. */
-    ret = request_irq(
-        Device->irqLines[gcvCORE_VG], isrRoutineVG, gcdIRQF_FLAG,
-        isrNames[gcvCORE_VG], Device
-        );
-
-    if (ret != 0)
-    {
-        gcmkTRACE_ZONE(
-            gcvLEVEL_ERROR, gcvZONE_DRIVER,
-            "%s(%d): Could not register irq line %d (error=%d)\n",
-            __FUNCTION__, __LINE__,
-            Device->irqLines[gcvCORE_VG], ret
-            );
-
-        gcmkONERROR(gcvSTATUS_GENERIC_IO);
-    }
-
-    /* Mark ISR as initialized. */
-    Device->isrInitializeds[gcvCORE_VG] = gcvTRUE;
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gckGALDEVICE_Release_ISR
-**
-**  Release the irq line.
-**
-**  INPUT:
-**
-**      gckGALDEVICE Device
-**          Pointer to an gckGALDEVICE object.
-**
-**  OUTPUT:
-**
-**      Nothing.
-**
-**  RETURNS:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckGALDEVICE_Release_ISR(
-    IN gceCORE Core
-    )
-{
-    gckGALDEVICE Device = galDevice;
-    gcmkHEADER_ARG("Device=0x%x", Device);
-
-    gcmkVERIFY_ARGUMENT(Device != NULL);
-
-    /* release the irq */
-    if (Device->isrInitializeds[Core])
-    {
-        free_irq(Device->irqLines[Core], (void *)(uintptr_t)(Core + 1));
-        Device->isrInitializeds[Core] = gcvFALSE;
-    }
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckGALDEVICE_Release_ISR_VG(
-    IN gckGALDEVICE Device
-    )
-{
-    gcmkHEADER_ARG("Device=0x%x", Device);
-
-    gcmkVERIFY_ARGUMENT(Device != NULL);
-
-    /* release the irq */
-    if (Device->isrInitializeds[gcvCORE_VG])
-    {
-        free_irq(Device->irqLines[gcvCORE_VG], Device);
-        Device->isrInitializeds[gcvCORE_VG] = gcvFALSE;
-    }
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gckGALDEVICE_Start_Threads
-**
-**  Start the daemon threads.
-**
-**  INPUT:
-**
-**      gckGALDEVICE Device
-**          Pointer to an gckGALDEVICE object.
-**
-**  OUTPUT:
-**
-**      Nothing.
-**
-**  RETURNS:
-**
-**      gcvSTATUS_OK
-**          Start successfully.
-**      gcvSTATUS_GENERIC_IO
-**          Start failed.
-*/
-gceSTATUS
-gckGALDEVICE_Start_Threads(
-    IN gckGALDEVICE Device
-    )
-{
-    gceSTATUS status;
-    gctUINT i;
-
-    gcmkHEADER_ARG("Device=0x%x", Device);
-
-    gcmkVERIFY_ARGUMENT(Device != NULL);
-
-    gcmkONERROR(_StartThread(threadRoutine, gcvCORE_MAJOR));
-    gcmkONERROR(_StartThread(threadRoutine, gcvCORE_2D));
-
-    gcmkONERROR(_StartThread(threadRoutine, gcvCORE_VG));
-
-    for (i = gcvCORE_3D1; i <= gcvCORE_3D_MAX; i++)
-    {
-        gcmkONERROR(_StartThread(threadRoutine, i));
-    }
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gckGALDEVICE_Stop_Threads
-**
-**  Stop the gal device, including the following actions: stop the daemon
-**  thread, release the irq.
-**
-**  INPUT:
-**
-**      gckGALDEVICE Device
-**          Pointer to an gckGALDEVICE object.
-**
-**  OUTPUT:
-**
-**      Nothing.
-**
-**  RETURNS:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckGALDEVICE_Stop_Threads(
-    gckGALDEVICE Device
-    )
-{
-    gctINT i;
-
-    gcmkHEADER_ARG("Device=0x%x", Device);
-
-    gcmkVERIFY_ARGUMENT(Device != NULL);
-
-    for (i = 0; i < gcdMAX_GPU_COUNT; i++)
-    {
-        /* Stop the kernel threads. */
-        if (Device->threadInitializeds[i])
-        {
-            Device->killThread = gcvTRUE;
-            up(&Device->semas[i]);
-
-            kthread_stop(Device->threadCtxts[i]);
-            Device->threadCtxts[i]        = gcvNULL;
-            Device->threadInitializeds[i] = gcvFALSE;
-        }
-    }
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
 /*******************************************************************************
 **
 **  gckGALDEVICE_Start
@@ -2156,49 +2083,50 @@ gckGALDEVICE_Start(
     IN gckGALDEVICE Device
     )
 {
-    gceSTATUS status;
     gctUINT i;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Device=0x%x", Device);
-
-    /* Start the kernel thread. */
-    gcmkONERROR(gckGALDEVICE_Start_Threads(Device));
+    gcmkHEADER_ARG("Device=%p", Device);
 
-    for (i = 0; i < gcvCORE_COUNT; i++)
+    /* Start the kernel threads. */
+    for (i = 0; i < gcvCORE_COUNT; ++i)
     {
         if (i == gcvCORE_VG)
         {
             continue;
         }
 
-        if (Device->kernels[i] != gcvNULL)
-        {
-            /* Setup the ISR routine. */
-            gcmkONERROR(gckGALDEVICE_Setup_ISR(i));
-
-            /* Switch to SUSPEND power state. */
-            gcmkONERROR(gckHARDWARE_SetPowerManagementState(
-                Device->kernels[i]->hardware, gcvPOWER_OFF_BROADCAST
-                ));
-        }
+        gcmkONERROR(_StartThread(Device, i));
     }
 
-    if (Device->kernels[gcvCORE_VG] != gcvNULL)
+    for (i = 0; i < gcvCORE_COUNT; i++)
     {
+        if (Device->kernels[i] == gcvNULL)
+        {
+            continue;
+        }
+
         /* Setup the ISR routine. */
-        gcmkONERROR(gckGALDEVICE_Setup_ISR_VG(Device));
+        gcmkONERROR(_SetupIsr(i));
 
+        if (i == gcvCORE_VG)
+        {
 #if gcdENABLE_VG
-        /* Switch to SUSPEND power state. */
-        gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
-            Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF_BROADCAST
-            ));
+            /* Switch to SUSPEND power state. */
+            gcmkONERROR(gckVGHARDWARE_SetPowerState(
+                Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF_BROADCAST
+                ));
 #endif
+        }
+        else
+        {
+            /* Switch to SUSPEND power state. */
+            gcmkONERROR(gckHARDWARE_SetPowerState(
+                Device->kernels[i]->hardware, gcvPOWER_OFF_BROADCAST
+                ));
+        }
     }
 
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     gcmkFOOTER();
     return status;
@@ -2229,134 +2157,54 @@ gckGALDEVICE_Stop(
     gckGALDEVICE Device
     )
 {
-    gceSTATUS status;
     gctUINT i;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Device=0x%x", Device);
+    gcmkHEADER_ARG("Device=%p", Device);
 
     gcmkVERIFY_ARGUMENT(Device != NULL);
 
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
-        if (i == gcvCORE_VG)
+        if (Device->kernels[i] == gcvNULL)
         {
             continue;
         }
 
-        if (Device->kernels[i] != gcvNULL)
+        if (i == gcvCORE_VG)
+        {
+#if gcdENABLE_VG
+            /* Switch to OFF power state. */
+            gcmkONERROR(gckVGHARDWARE_SetPowerState(
+                Device->kernels[i]->vg->hardware, gcvPOWER_OFF
+                ));
+#endif
+        }
+        else
         {
-            gcmkONERROR(gckHARDWARE_SetPowerManagement(
+            gcmkONERROR(gckHARDWARE_EnablePowerManagement(
                 Device->kernels[i]->hardware, gcvTRUE
                 ));
 
             /* Switch to OFF power state. */
-            gcmkONERROR(gckHARDWARE_SetPowerManagementState(
+            gcmkONERROR(gckHARDWARE_SetPowerState(
                 Device->kernels[i]->hardware, gcvPOWER_OFF
                 ));
-
-            /* Remove the ISR routine. */
-            gcmkONERROR(gckGALDEVICE_Release_ISR(i));
         }
-    }
 
-    if (Device->kernels[gcvCORE_VG] != gcvNULL)
-    {
-        /* Setup the ISR routine. */
-        gcmkONERROR(gckGALDEVICE_Release_ISR_VG(Device));
+        /* Stop the ISR routine. */
+        gcmkONERROR(_ReleaseIsr(i));
 
-#if gcdENABLE_VG
-        /* Switch to OFF power state. */
-        gcmkONERROR(gckVGHARDWARE_SetPowerManagementState(
-            Device->kernels[gcvCORE_VG]->vg->hardware, gcvPOWER_OFF
-            ));
-#endif
     }
 
     /* Stop the kernel thread. */
-    gcmkONERROR(gckGALDEVICE_Stop_Threads(Device));
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gckGALDEVICE_AddCore
-**
-**  Add a core after gckGALDevice is constructed.
-**
-**  INPUT:
-**
-**  OUTPUT:
-**
-*/
-gceSTATUS
-gckGALDEVICE_AddCore(
-    IN gckGALDEVICE Device,
-    IN gcsDEVICE_CONSTRUCT_ARGS * Args
-    )
-{
-    gceSTATUS status;
-    gceCORE core = gcvCORE_COUNT;
-    gctUINT i = 0;
-
-    gcmkHEADER();
-    gcmkVERIFY_ARGUMENT(Device != gcvNULL);
-
-    /* Find which core is added. */
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
-        if (Args->irqs[i] != -1)
-        {
-            core = i;
-            break;
-        }
+        _StopThread(Device, i);
     }
 
-    if (i == gcvCORE_COUNT)
-    {
-        gcmkPRINT("[galcore]: No valid core information found");
-        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-    }
-
-
-    gcmkPRINT("[galcore]: add core[%d]", core);
-
-    /* Record irq, registerBase, registerSize. */
-    Device->irqLines[core] = Args->irqs[core];
-    _SetupRegisterPhysical(Device, Args);
-
-    /* Map register memory.*/
-
-    /* Add a platform indepedent framework. */
-    gcmkONERROR(gckDEVICE_AddCore(
-        Device->device,
-        core,
-        Args->chipIDs[core],
-        Device,
-        &Device->kernels[core]
-        ));
-
-    /* Start thread routine. */
-    _StartThread(threadRoutine, core);
-
-    /* Register ISR. */
-    gckGALDEVICE_Setup_ISR(core);
-
-    /* Set default power management state. */
-    gcmkONERROR(gckHARDWARE_SetPowerManagementState(
-        Device->kernels[core]->hardware, gcvPOWER_OFF_BROADCAST
-        ));
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     gcmkFOOTER();
-    return gcvSTATUS_OK;
+    return status;
 }
 
index 4232200..e54fbcd 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 #include "gc_hal_kernel_debugfs.h"
 #include "gc_hal_ta.h"
 
-typedef struct _gcsDEVICE_CONSTRUCT_ARGS
-{
-    gctBOOL             recovery;
-    gctUINT             stuckDump;
-    gctUINT             gpu3DMinClock;
-
-    gctBOOL             contiguousRequested;
-    gcsPLATFORM*        platform;
-    gctBOOL             mmu;
-    gctBOOL             registerMemMapped;
-    gctPOINTER             registerMemAddress;
-#if gcdDEC_ENABLE_AHB
-    gctUINT32           registerMemBaseDEC300;
-    gctSIZE_T           registerMemSizeDEC300;
-#endif
-    gctINT              irqs[gcvCORE_COUNT];
-    gctUINT             registerBases[gcvCORE_COUNT];
-    gctUINT             registerSizes[gcvCORE_COUNT];
-    gctBOOL             powerManagement;
-    gctBOOL             gpuProfiler;
-    gctUINT             chipIDs[gcvCORE_COUNT];
-}
-gcsDEVICE_CONSTRUCT_ARGS;
-
 /******************************************************************************\
 ************************** gckGALDEVICE Structure ******************************
 \******************************************************************************/
@@ -96,74 +72,71 @@ typedef struct _gckGALDEVICE
     gcsPLATFORM*        platform;
 
     /* Attributes. */
+    gctPHYS_ADDR_T      internalBase;
     gctSIZE_T           internalSize;
     gctPHYS_ADDR        internalPhysical;
-    gctUINT32           internalPhysicalName;
+    gctUINT32           internalPhysName;
     gctPOINTER          internalLogical;
     gckVIDMEM           internalVidMem;
 
-    gctUINT32           externalBase;
+    gctPHYS_ADDR_T      externalBase;
     gctSIZE_T           externalSize;
     gctPHYS_ADDR        externalPhysical;
-    gctUINT32           externalPhysicalName;
+    gctUINT32           externalPhysName;
     gctPOINTER          externalLogical;
     gckVIDMEM           externalVidMem;
 
     gctPHYS_ADDR_T      contiguousBase;
     gctSIZE_T           contiguousSize;
-
-    gckVIDMEM           contiguousVidMem;
-    gctPOINTER          contiguousLogical;
     gctPHYS_ADDR        contiguousPhysical;
-    gctUINT32           contiguousPhysicalName;
+    gctUINT32           contiguousPhysName;
+    gctPOINTER          contiguousLogical;
+    gckVIDMEM           contiguousVidMem;
 
-    gctSIZE_T           systemMemorySize;
-    gctUINT32           systemMemoryBaseAddress;
+    /* By request_mem_region. */
+    gctUINT64           requestedContiguousBase;
+    gctSIZE_T           requestedContiguousSize;
+
+    /* IRQ management. */
+    gctINT              irqLines[gcdMAX_GPU_COUNT];
+    gctBOOL             isrInitializeds[gcdMAX_GPU_COUNT];
+
+    /* Register memory. */
     gctPOINTER          registerBases[gcdMAX_GPU_COUNT];
     gctSIZE_T           registerSizes[gcdMAX_GPU_COUNT];
 
+    /* By request_mem_region. */
+    gctUINT64           requestedRegisterMemBases[gcdMAX_GPU_COUNT];
+    gctSIZE_T           requestedRegisterMemSizes[gcdMAX_GPU_COUNT];
+
     gctUINT32           baseAddress;
     gctUINT32           physBase;
     gctUINT32           physSize;
 
-    /* By request_mem_region. */
-    gctUINT32           requestedRegisterMemBases[gcdMAX_GPU_COUNT];
-    gctSIZE_T           requestedRegisterMemSizes[gcdMAX_GPU_COUNT];
 
-    /* By request_mem_region. */
-    gctUINT32           requestedContiguousBase;
-    gctSIZE_T           requestedContiguousSize;
-
-    /* IRQ management. */
-    gctINT              irqLines[gcdMAX_GPU_COUNT];
-    gctBOOL             isrInitializeds[gcdMAX_GPU_COUNT];
+    /* PCIE Bar */
+    gctINT              bars[gcdMAX_GPU_COUNT];
 
     /* Thread management. */
-    struct task_struct  *threadCtxts[gcdMAX_GPU_COUNT];
+    struct task_struct *threadCtxts[gcdMAX_GPU_COUNT];
     struct semaphore    semas[gcdMAX_GPU_COUNT];
     gctBOOL             threadInitializeds[gcdMAX_GPU_COUNT];
     gctBOOL             killThread;
 
-    /* Signal management. */
-    gctINT              signal;
-
     /* States before suspend. */
     gceCHIPPOWERSTATE   statesStored[gcdMAX_GPU_COUNT];
 
-    /* Device Debug File System Entry in kernel. */
-    struct _gcsDEBUGFS_Node * dbgNode;
-
     gcsDEBUGFS_DIR      debugfsDir;
 
     gckDEVICE           device;
 
-    gcsDEVICE_CONSTRUCT_ARGS args;
+    gcsMODULE_PARAMETERS args;
 
     /* gctsOs object for trust application. */
     gctaOS              taos;
 
 #if gcdENABLE_DRM
-    void              drm;
+    void *              drm;
 #endif
 }
 * gckGALDEVICE;
@@ -181,66 +154,25 @@ typedef struct _gcsHAL_PRIVATE_DATA
 }
 gcsHAL_PRIVATE_DATA, * gcsHAL_PRIVATE_DATA_PTR;
 
-gceSTATUS gckGALDEVICE_Setup_ISR(
-    IN gceCORE Core
-    );
-
-gceSTATUS gckGALDEVICE_Setup_ISR_VG(
-    IN gckGALDEVICE Device
-    );
-
-gceSTATUS gckGALDEVICE_Release_ISR(
-    IN gceCORE Core
-    );
-
-gceSTATUS gckGALDEVICE_Release_ISR_VG(
-    IN gckGALDEVICE Device
-    );
-
-gceSTATUS gckGALDEVICE_Start_Threads(
-    IN gckGALDEVICE Device
-    );
-
-gceSTATUS gckGALDEVICE_Stop_Threads(
-    gckGALDEVICE Device
-    );
-
-gceSTATUS gckGALDEVICE_Start(
+gceSTATUS
+gckGALDEVICE_Start(
     IN gckGALDEVICE Device
     );
 
-gceSTATUS gckGALDEVICE_Stop(
+gceSTATUS
+gckGALDEVICE_Stop(
     gckGALDEVICE Device
     );
 
-gceSTATUS gckGALDEVICE_Construct(
-    IN gctINT IrqLine,
-    IN gctUINT32 RegisterMemBase,
-    IN gctSIZE_T RegisterMemSize,
-    IN gctINT IrqLine2D,
-    IN gctUINT32 RegisterMemBase2D,
-    IN gctSIZE_T RegisterMemSize2D,
-    IN gctINT IrqLineVG,
-    IN gctUINT32 RegisterMemBaseVG,
-    IN gctSIZE_T RegisterMemSizeVG,
-    IN gctUINT32 ContiguousBase,
-    IN gctSIZE_T ContiguousSize,
-    IN gctUINT32 ExternalBase,
-    IN gctSIZE_T ExternalSize,
-    IN gctSIZE_T BankSize,
-    IN gctINT FastClear,
-    IN gctINT Compression,
-    IN gctUINT32 PhysBaseAddr,
-    IN gctUINT32 PhysSize,
-    IN gctINT Signal,
-    IN gctUINT LogFileSize,
-    IN gctINT PowerManagement,
-    IN gctINT GpuProfiler,
-    IN gcsDEVICE_CONSTRUCT_ARGS * Args,
+gceSTATUS
+gckGALDEVICE_Construct(
+    IN gcsPLATFORM * Platform,
+    IN const gcsMODULE_PARAMETERS * Args,
     OUT gckGALDEVICE *Device
     );
 
-gceSTATUS gckGALDEVICE_Destroy(
+gceSTATUS
+gckGALDEVICE_Destroy(
     IN gckGALDEVICE Device
     );
 
@@ -253,13 +185,11 @@ _GetValidKernel(
     {
         return Device->kernels[gcvCORE_MAJOR];
     }
-    else
-    if (Device->kernels[gcvCORE_2D])
+    else if (Device->kernels[gcvCORE_2D])
     {
         return Device->kernels[gcvCORE_2D];
     }
-    else
-    if (Device->kernels[gcvCORE_VG])
+    else if (Device->kernels[gcvCORE_VG])
     {
         return Device->kernels[gcvCORE_VG];
     }
index 87f26e7..03e3620 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 MODULE_DESCRIPTION("Vivante Graphics Driver");
 MODULE_LICENSE("Dual MIT/GPL");
 
-/* Disable MSI for internal FPGA build except PPC */
-#if gcdFPGA_BUILD && !defined(CONFIG_PPC)
-#define USE_MSI     0
-#else
-#define USE_MSI     1
-#endif
 
 static struct class* gpuClass = NULL;
 
@@ -94,7 +88,7 @@ static ulong registerMemBase = 0x80000000;
 module_param(registerMemBase, ulong, 0644);
 MODULE_PARM_DESC(registerMemBase, "Base of bus address of GC core AHB register");
 
-static ulong registerMemSize = 2 << 10;
+static ulong registerMemSize = 2 << 16;
 module_param(registerMemSize, ulong, 0644);
 MODULE_PARM_DESC(registerMemSize, "Size of bus address range of GC core AHB register");
 
@@ -106,7 +100,7 @@ static ulong registerMemBase2D = 0x00000000;
 module_param(registerMemBase2D, ulong, 0644);
 MODULE_PARM_DESC(registerMemBase2D, "Base of bus address of G2D core if registerMemBase2D is used for a G3D core");
 
-static ulong registerMemSize2D = 2 << 10;
+static ulong registerMemSize2D = 2 << 16;
 module_param(registerMemSize2D, ulong, 0644);
 MODULE_PARM_DESC(registerMemSize2D, "Size of bus address range of G2D core if registerMemSize is used for a G3D core");
 
@@ -159,7 +153,7 @@ MODULE_PARM_DESC(compression, "Disable compression if set it to 0, enabled by de
 
 static int powerManagement = 1;
 module_param(powerManagement, int, 0644);
-MODULE_PARM_DESC(powerManagement, "Disable auto power saving if set it to 1, enabled by default");
+MODULE_PARM_DESC(powerManagement, "Disable auto power saving if set it to 0, enabled by default");
 
 static int gpuProfiler = 0;
 module_param(gpuProfiler, int, 0644);
@@ -173,10 +167,6 @@ static ulong physSize = 0;
 module_param(physSize, ulong, 0644);
 MODULE_PARM_DESC(physSize, "Obsolete");
 
-static uint logFileSize = 0;
-module_param(logFileSize,uint, 0644);
-MODULE_PARM_DESC(logFileSize, "Size of buffer to store GC driver output messsage, if it is not 0, message is read from /sys/kernel/debug/gc/galcore_trace, default value is 0");
-
 static uint recovery = 0;
 module_param(recovery, uint, 0644);
 MODULE_PARM_DESC(recovery, "Recover GPU from stuck (1: Enable, 0: Disable)");
@@ -186,13 +176,13 @@ static uint stuckDump = 0;
 module_param(stuckDump, uint, 0644);
 MODULE_PARM_DESC(stuckDump, "Level of stuck dump content (1: Minimal, 2: Middle, 3: Maximal)");
 
-static int showArgs = 0;
+static int showArgs = 1;
 module_param(showArgs, int, 0644);
 MODULE_PARM_DESC(showArgs, "Display parameters value when driver loaded");
 
 static int mmu = 1;
 module_param(mmu, int, 0644);
-MODULE_PARM_DESC(mmu, "Disable MMU if set it to 0, enabled by default");
+MODULE_PARM_DESC(mmu, "Disable MMU if set it to 0, enabled by default [Obsolete]");
 
 static int irqs[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = -1};
 module_param_array(irqs, int, NULL, 0644);
@@ -202,7 +192,7 @@ static uint registerBases[gcvCORE_COUNT];
 module_param_array(registerBases, uint, NULL, 0644);
 MODULE_PARM_DESC(registerBases, "Array of bases of bus address of register of multi-GPU");
 
-static uint registerSizes[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = 2 << 10};
+static uint registerSizes[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = 2 << 16};
 module_param_array(registerSizes, uint, NULL, 0644);
 MODULE_PARM_DESC(registerSizes, "Array of sizes of bus address range of register of multi-GPU");
 
@@ -214,56 +204,252 @@ static uint type = 0;
 module_param(type, uint, 0664);
 MODULE_PARM_DESC(type, "0 - Char Driver (Default), 1 - Misc Driver");
 
-static int gpu3DMinClock = 1;
+static int userClusterMask = 0;
+module_param(userClusterMask, int, 0644);
+MODULE_PARM_DESC(userClusterMask, "User defined cluster enable mask");
 
-static int contiguousRequested = 0;
+static int smallBatch = 1;
+module_param(smallBatch, int, 0644);
+MODULE_PARM_DESC(smallBatch, "Enable/disable small batch");
+
+static gctPHYS_ADDR_T sRAMBases[gcvSRAM_COUNT * gcvCORE_COUNT] = {[0 ... gcvSRAM_COUNT * gcvCORE_COUNT - 1] = gcvINVALID_PHYSICAL_ADDRESS};
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+module_param_array(sRAMBases, ullong, NULL, 0644);
+MODULE_PARM_DESC(sRAMBases, "Array of base of bus address of SRAM,INTERNAL, EXTERNAL0, EXTERNAL1..., gcvINVALID_PHYSICAL_ADDRESS means no bus address");
+#endif
+
+static uint sRAMSizes[gcvSRAM_COUNT * gcvCORE_COUNT] = {[0 ... gcvSRAM_COUNT * gcvCORE_COUNT - 1] = 0};
+module_param_array(sRAMSizes, uint, NULL, 0644);
+MODULE_PARM_DESC(sRAMSizes, "Array of size of SRAM,INTERNAL, EXTERNAL0, EXTERNAL1..., 0 means no SRAM");
+
+static uint sRAMMode = 0;
+module_param(sRAMMode, uint, 0644);
+MODULE_PARM_DESC(sRAMMode, "Default 0 means SRAM is exclusive mode usage, 1 means contiguous memory heap usage.");
 
-static gctBOOL registerMemMapped = gcvFALSE;
-static gctPOINTER registerMemAddress = gcvNULL;
+#if USE_LINUX_PCIE
+static int bar = 1;
+module_param(bar, int, 0644);
+MODULE_PARM_DESC(bar, "PCIE Bar index of GC core");
+
+static int bars[gcvCORE_COUNT] = {[0 ... gcvCORE_COUNT - 1] = -1};
+module_param_array(bars, int, NULL, 0644);
+MODULE_PARM_DESC(bars, "Array of bar index of PCIE platform for multi-GPU");
+#endif
+
+
+static int gpu3DMinClock = 1;
+static int contiguousRequested = 0;
 static ulong bankSize = 0;
-static int signal = 48;
 
-void
-_UpdateModuleParam(
-    gcsMODULE_PARAMETERS *Param
+
+static gcsMODULE_PARAMETERS moduleParam;
+
+static void
+_InitModuleParam(
+    gcsMODULE_PARAMETERS * ModuleParam
     )
 {
-    irqLine           = Param->irqLine ;
-    registerMemBase   = Param->registerMemBase;
-    registerMemSize   = Param->registerMemSize;
-    irqLine2D         = Param->irqLine2D      ;
-    registerMemBase2D = Param->registerMemBase2D;
-    registerMemSize2D = Param->registerMemSize2D;
-#if gcdENABLE_VG
-    irqLineVG         = Param->irqLineVG;
-    registerMemBaseVG = Param->registerMemBaseVG;
-    registerMemSizeVG = Param->registerMemSizeVG;
+    gctUINT i, j;
+    gcsMODULE_PARAMETERS *p = ModuleParam;
+
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        p->irqs[i] = irqs[i];
+
+        if (irqs[i] != -1)
+        {
+            p->registerBases[i] = registerBases[i];
+            p->registerSizes[i] = registerSizes[i];
+        }
+#if USE_LINUX_PCIE
+        p->bars[i] = bars[i];
+#endif
+    }
+
+    /* Check legacy style. */
+#if USE_LINUX_PCIE
+    if (bar != -1)
+    {
+        p->bars[gcvCORE_MAJOR]         = bar;
+    }
+#endif
+
+    if (irqLine != -1)
+    {
+        p->irqs[gcvCORE_MAJOR]          = irqLine;
+        p->registerBases[gcvCORE_MAJOR] = registerMemBase;
+        p->registerSizes[gcvCORE_MAJOR] = registerMemSize;
+    }
+
+    if (irqLine2D != -1)
+    {
+        p->irqs[gcvCORE_2D]          = irqLine2D;
+        p->registerBases[gcvCORE_2D] = registerMemBase2D;
+        p->registerSizes[gcvCORE_2D] = registerMemSize2D;
+    }
+
+    if (irqLineVG != -1)
+    {
+        p->irqs[gcvCORE_VG]          = irqLineVG;
+        p->registerBases[gcvCORE_VG] = registerMemBaseVG;
+        p->registerSizes[gcvCORE_VG] = registerMemSizeVG;
+    }
+
+#if gcdDEC_ENABLE_AHB
+    if (registerMemBaseDEC300 && registerMemSizeDEC300)
+    {
+        p->registerBases[gcvCORE_DEC] = registerMemBaseDEC300;
+        p->registerSizes[gcvCORE_DEC] = registerMemSizeDEC300;
+    }
+#endif
+
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        /* Not a module param. */
+        p->registerBasesMapped[i] = gcvNULL;
+    }
+
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        p->chipIDs[i] = chipIDs[i];
+    }
+
+    p->contiguousBase      = contiguousBase;
+    p->contiguousSize      = contiguousSize;
+    p->contiguousRequested = contiguousRequested;   /* not a module param. */
+
+    p->externalBase = externalBase;
+    p->externalSize = externalSize;
+
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        for (j = 0; j < gcvSRAM_COUNT; j++)
+        {
+            p->sRAMBases[i][j] = sRAMBases[i * gcvSRAM_COUNT + j];
+            p->sRAMSizes[i][j] = sRAMSizes[i * gcvSRAM_COUNT + j];
+        }
+    }
+
+    p->sRAMMode = sRAMMode;
+
+    p->baseAddress = baseAddress;
+    p->physSize    = physSize;
+    p->bankSize    = bankSize;  /* not a module param. */
+
+    p->recovery        = recovery;
+    p->powerManagement = powerManagement;
+
+    p->enableMmu = mmu;
+    p->fastClear = fastClear;
+
+    p->compression = (compression == -1) ? gcvCOMPRESSION_OPTION_DEFAULT
+                   : (gceCOMPRESSION_OPTION)compression;
+    p->gpu3DMinClock   = gpu3DMinClock; /* not a module param. */
+    p->userClusterMask = userClusterMask;
+    p->smallBatch      = smallBatch;
+
+    p->stuckDump   = stuckDump;
+    p->gpuProfiler = gpuProfiler;
+
+    p->deviceType  = type;
+    p->showArgs    = showArgs;
+
+#if !gcdENABLE_3D
+    p->irqs[gcvCORE_MAJOR]          = irqLine = -1;
+    p->registerBases[gcvCORE_MAJOR] = registerMemBase = 0;
+    p->registerSizes[gcvCORE_MAJOR] = registerMemSize = 0;
 #endif
-    contiguousSize    = Param->contiguousSize;
-    contiguousBase    = Param->contiguousBase;
-    externalSize      = Param->externalSize;
-    externalBase      = Param->externalBase;
-    bankSize          = Param->bankSize;
-    fastClear         = Param->fastClear;
-    compression       = (gctINT)Param->compression;
-    powerManagement   = Param->powerManagement;
-    gpuProfiler       = Param->gpuProfiler;
-    signal            = Param->signal;
-    baseAddress       = Param->baseAddress;
-    physSize          = Param->physSize;
-    logFileSize       = Param->logFileSize;
-    recovery          = Param->recovery;
-    stuckDump         = Param->stuckDump;
-    showArgs          = Param->showArgs;
-    contiguousRequested = Param->contiguousRequested;
-    gpu3DMinClock     = Param->gpu3DMinClock;
-    registerMemMapped    = Param->registerMemMapped;
-    registerMemAddress    = Param->registerMemAddress;
-
-    memcpy(irqs, Param->irqs, gcmSIZEOF(gctINT) * gcvCORE_COUNT);
-    memcpy(registerBases, Param->registerBases, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
-    memcpy(registerSizes, Param->registerSizes, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
-    memcpy(chipIDs, Param->chipIDs, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
+
+#if !gcdENABLE_2D
+    p->irqs[gcvCORE_2D]          = irqLine2D = -1;
+    p->registerBases[gcvCORE_2D] = registerMemBase2D = 0;
+    p->registerSizes[gcvCORE_2D] = registerMemSize2D = 0;
+#endif
+
+#if !gcdENABLE_VG
+    p->irqs[gcvCORE_VG]          = irqLineVG = -1;
+    p->registerBases[gcvCORE_VG] = registerMemBaseVG = 0;
+    p->registerSizes[gcvCORE_VG] = registerMemSizeVG = 0;
+#endif
+}
+
+static void
+_SyncModuleParam(
+    const gcsMODULE_PARAMETERS * ModuleParam
+    )
+{
+    gctUINT i, j;
+    gcsMODULE_PARAMETERS *p = &moduleParam;
+
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        irqs[i]          = p->irqs[i];
+        registerBases[i] = (ulong)p->registerBases[i];
+        registerSizes[i] = (ulong)p->registerSizes[i];
+ #if USE_LINUX_PCIE
+        bars[i]          = p->bars[i];
+ #endif
+    }
+
+    /* Sync to legacy style. */
+
+#if USE_LINUX_PCIE
+    bar               = p->bars[gcvCORE_MAJOR];
+#endif
+    irqLine           = p->irqs[gcvCORE_MAJOR];
+    registerMemBase   = (ulong)p->registerBases[gcvCORE_MAJOR];
+    registerMemSize   = (ulong)p->registerSizes[gcvCORE_MAJOR];
+
+    irqLine2D         = p->irqs[gcvCORE_2D];
+    registerMemBase2D = (ulong)p->registerBases[gcvCORE_2D];
+    registerMemSize2D = (ulong)p->registerSizes[gcvCORE_2D];
+
+    irqLineVG         = p->irqs[gcvCORE_VG];
+    registerMemBaseVG = (ulong)p->registerBases[gcvCORE_VG];
+    registerMemSizeVG = (ulong)p->registerSizes[gcvCORE_VG];
+
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        p->chipIDs[i] = chipIDs[i];
+    }
+
+    contiguousBase      = (ulong)p->contiguousBase;
+    contiguousSize      = (ulong)p->contiguousSize;
+    contiguousRequested = p->contiguousRequested;   /* not a module param. */
+
+    externalBase = p->externalBase;
+    externalSize = p->externalSize;
+
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        for (j = 0; j < gcvSRAM_COUNT; j++)
+        {
+            sRAMBases[i * gcvSRAM_COUNT + j] = p->sRAMBases[i][j];
+            sRAMSizes[i * gcvSRAM_COUNT + j] = p->sRAMSizes[i][j];
+        }
+    }
+
+    sRAMMode = p->sRAMMode;
+
+    baseAddress = (ulong)p->baseAddress;
+    physSize    = p->physSize;
+    bankSize    = p->bankSize;  /* not a module param. */
+
+    recovery        = p->recovery;
+    powerManagement = p->powerManagement;
+
+    mmu             = p->enableMmu;
+    fastClear       = p->fastClear;
+    compression     = p->compression;
+    gpu3DMinClock   = p->gpu3DMinClock; /* not a module param. */
+    userClusterMask = p->userClusterMask;
+    smallBatch      = p->smallBatch;
+
+    stuckDump   = p->stuckDump;
+    gpuProfiler = p->gpuProfiler;
+
+    type        = p->deviceType;
+    showArgs    = p->showArgs;
 }
 
 void
@@ -271,7 +457,7 @@ gckOS_DumpParam(
     void
     )
 {
-    gctINT i;
+    gctINT i, j;
 
     printk("Galcore options:\n");
     if (irqLine != -1)
@@ -294,7 +480,12 @@ gckOS_DumpParam(
         printk("  registerMemBaseVG = 0x%08lX\n", registerMemBaseVG);
         printk("  registerMemSizeVG = 0x%08lX\n", registerMemSizeVG);
     }
-
+#if USE_LINUX_PCIE
+    if (bar != -1)
+    {
+        printk("  bar               = %d\n",      bar);
+    }
+#endif
 #if gcdDEC_ENABLE_AHB
     printk("  registerMemBaseDEC300 = 0x%08lX\n", registerMemBaseDEC300);
     printk("  registerMemSizeDEC300 = 0x%08lX\n", registerMemSizeDEC300);
@@ -307,14 +498,14 @@ gckOS_DumpParam(
     printk("  bankSize          = 0x%08lX\n", bankSize);
     printk("  fastClear         = %d\n",      fastClear);
     printk("  compression       = %d\n",      compression);
-    printk("  signal            = %d\n",      signal);
     printk("  powerManagement   = %d\n",      powerManagement);
     printk("  baseAddress       = 0x%08lX\n", baseAddress);
     printk("  physSize          = 0x%08lX\n", physSize);
-    printk("  logFileSize       = %d KB \n",  logFileSize);
     printk("  recovery          = %d\n",      recovery);
     printk("  stuckDump         = %d\n",      stuckDump);
     printk("  gpuProfiler       = %d\n",      gpuProfiler);
+    printk("  userClusterMask   = 0x%x\n",    userClusterMask);
+    printk("  smallBatch        = %d\n",      smallBatch);
 
     printk("  irqs              = ");
     for (i = 0; i < gcvCORE_COUNT; i++)
@@ -323,6 +514,14 @@ gckOS_DumpParam(
     }
     printk("\n");
 
+#if USE_LINUX_PCIE
+    printk("  bars              = ");
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        printk("%d, ", bars[i]);
+    }
+    printk("\n");
+#endif
     printk("  registerBases     = ");
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
@@ -337,13 +536,24 @@ gckOS_DumpParam(
     }
     printk("\n");
 
-    printk("  chipIDs     = ");
+    printk("  chipIDs           = ");
     for (i = 0; i < gcvCORE_COUNT; i++)
     {
         printk("0x%08X, ", chipIDs[i]);
     }
     printk("\n");
 
+    for (i = 0; i < gcvCORE_COUNT; i++)
+    {
+        printk("  core %d sRAMBases = ", i);
+
+        for (j = 0; j < gcvSRAM_COUNT; j++)
+        {
+            printk("0x%llX, ", sRAMBases[i * gcvSRAM_COUNT + j]);
+        }
+        printk("\n");
+    }
+
     printk("Build options:\n");
     printk("  gcdGPU_TIMEOUT    = %d\n", gcdGPU_TIMEOUT);
     printk("  gcdGPU_2D_TIMEOUT = %d\n", gcdGPU_2D_TIMEOUT);
@@ -355,76 +565,61 @@ static int drv_open(
     struct file* filp
     )
 {
-    gceSTATUS status;
-    gctBOOL attached = gcvFALSE;
+    gceSTATUS status = gcvSTATUS_OK;
     gcsHAL_PRIVATE_DATA_PTR data = gcvNULL;
     gctINT i;
+    gctINT attached = 0;
 
-    gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
-
-    if (filp == gcvNULL)
-    {
-        gcmkTRACE_ZONE(
-            gcvLEVEL_ERROR, gcvZONE_DRIVER,
-            "%s(%d): filp is NULL\n",
-            __FUNCTION__, __LINE__
-            );
-
-        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-    }
+    gcmkHEADER_ARG("inode=%p filp=%p", inode, filp);
 
     data = kmalloc(sizeof(gcsHAL_PRIVATE_DATA), GFP_KERNEL | __GFP_NOWARN);
 
     if (data == gcvNULL)
     {
-        gcmkTRACE_ZONE(
-            gcvLEVEL_ERROR, gcvZONE_DRIVER,
-            "%s(%d): private_data is NULL\n",
-            __FUNCTION__, __LINE__
-            );
-
-        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+        gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
+        return -ENOMEM;
     }
 
-    data->device             = galDevice;
-    data->pidOpen            = _GetProcessID();
-    data->isLocked           = gcvFALSE;
+    data->isLocked = gcvFALSE;
+    data->device   = galDevice;
+    data->pidOpen  = _GetProcessID();
 
     /* Attached the process. */
     for (i = 0; i < gcdMAX_GPU_COUNT; i++)
     {
         if (galDevice->kernels[i] != gcvNULL)
         {
-            gcmkONERROR(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvTRUE));
-        }
-    }
-    attached = gcvTRUE;
+            status = gckKERNEL_AttachProcess(galDevice->kernels[i], gcvTRUE);
 
-    filp->private_data = data;
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return 0;
+            if (gcmIS_ERROR(status))
+            {
+                break;
+            }
 
-OnError:
-    if (data != gcvNULL)
-    {
-        kfree(data);
+            attached = i;
+        }
     }
 
-    if (attached)
+    if (gcmIS_ERROR(status))
     {
-        for (i = 0; i < gcdMAX_GPU_COUNT; i++)
+        /* Error. */
+        for (i = 0; i < attached; i++)
         {
             if (galDevice->kernels[i] != gcvNULL)
             {
                 gcmkVERIFY_OK(gckKERNEL_AttachProcess(galDevice->kernels[i], gcvFALSE));
             }
         }
+
+        gcmkFOOTER_ARG("status=%d", status);
+        return -ENOTTY;
     }
 
-    gcmkFOOTER();
-    return -ENOTTY;
+    filp->private_data = data;
+
+    /* Success. */
+    gcmkFOOTER_NO();
+    return 0;
 }
 
 static int drv_release(
@@ -432,23 +627,13 @@ static int drv_release(
     struct file* filp
     )
 {
-    gceSTATUS status;
+    int ret = -ENOTTY;
+    gceSTATUS status = gcvSTATUS_OK;
     gcsHAL_PRIVATE_DATA_PTR data;
     gckGALDEVICE device;
     gctINT i;
 
-    gcmkHEADER_ARG("inode=0x%08X filp=0x%08X", inode, filp);
-
-    if (filp == gcvNULL)
-    {
-        gcmkTRACE_ZONE(
-            gcvLEVEL_ERROR, gcvZONE_DRIVER,
-            "%s(%d): filp is NULL\n",
-            __FUNCTION__, __LINE__
-            );
-
-        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-    }
+    gcmkHEADER_ARG("inode=%p filp=%p", inode, filp);
 
     data = filp->private_data;
 
@@ -488,7 +673,11 @@ static int drv_release(
     {
         if (galDevice->kernels[i] != gcvNULL)
         {
-            gcmkONERROR(gckKERNEL_AttachProcessEx(galDevice->kernels[i], gcvFALSE, data->pidOpen));
+            gcmkVERIFY_OK(gckKERNEL_AttachProcessEx(
+                galDevice->kernels[i],
+                gcvFALSE,
+                data->pidOpen
+                ));
         }
     }
 
@@ -496,12 +685,11 @@ static int drv_release(
     filp->private_data = NULL;
 
     /* Success. */
-    gcmkFOOTER_NO();
-    return 0;
+    ret = 0;
 
 OnError:
     gcmkFOOTER();
-    return -ENOTTY;
+    return ret;
 }
 
 static long drv_ioctl(
@@ -510,28 +698,15 @@ static long drv_ioctl(
     unsigned long arg
     )
 {
-    gceSTATUS status;
+    long ret = -ENOTTY;
+    gceSTATUS status = gcvSTATUS_OK;
     gcsHAL_INTERFACE iface;
     gctUINT32 copyLen;
     DRIVER_ARGS drvArgs;
     gckGALDEVICE device;
     gcsHAL_PRIVATE_DATA_PTR data;
 
-    gcmkHEADER_ARG(
-        "filp=0x%08X ioctlCode=0x%08X arg=0x%08X",
-        filp, ioctlCode, arg
-        );
-
-    if (filp == gcvNULL)
-    {
-        gcmkTRACE_ZONE(
-            gcvLEVEL_ERROR, gcvZONE_DRIVER,
-            "%s(%d): filp is NULL\n",
-            __FUNCTION__, __LINE__
-            );
-
-        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
-    }
+    gcmkHEADER_ARG("filp=%p ioctlCode=%u arg=%lu",filp, ioctlCode, arg);
 
     data = filp->private_data;
 
@@ -635,8 +810,8 @@ static long drv_ioctl(
     /* Redo system call after pending signal is handled. */
     if (status == gcvSTATUS_INTERRUPTED)
     {
-        gcmkFOOTER();
-        return -ERESTARTSYS;
+        ret = -ERESTARTSYS;
+        gcmkONERROR(status);
     }
 
     /* Copy data back to the user. */
@@ -656,12 +831,11 @@ static long drv_ioctl(
     }
 
     /* Success. */
-    gcmkFOOTER_NO();
-    return 0;
+    ret = 0;
 
 OnError:
     gcmkFOOTER();
-    return -ENOTTY;
+    return ret;
 }
 
 static struct file_operations driver_fops =
@@ -683,67 +857,23 @@ static struct miscdevice gal_device = {
 
 static int drv_init(void)
 {
-    int ret;
-    int result = -EINVAL;
+    int ret = -EINVAL;
     gceSTATUS status;
     gckGALDEVICE device = gcvNULL;
     struct class* device_class = gcvNULL;
 
-    gcsDEVICE_CONSTRUCT_ARGS args = {
-        .recovery           = recovery,
-        .stuckDump          = stuckDump,
-        .gpu3DMinClock      = gpu3DMinClock,
-        .contiguousRequested = contiguousRequested,
-        .platform           = platform,
-        .mmu                = mmu,
-        .registerMemMapped = registerMemMapped,
-        .registerMemAddress = registerMemAddress,
-#if gcdDEC_ENABLE_AHB
-        .registerMemBaseDEC300 = registerMemBaseDEC300,
-        .registerMemSizeDEC300 = registerMemSizeDEC300,
-#endif
-    };
-
     gcmkHEADER();
 
-    memcpy(args.irqs, irqs, gcmSIZEOF(gctINT) * gcvCORE_COUNT);
-    memcpy(args.registerBases, registerBases, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
-    memcpy(args.registerSizes, registerSizes, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
-    memcpy(args.chipIDs, chipIDs, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
-
     printk(KERN_INFO "Galcore version %d.%d.%d.%d\n",
         gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH, gcvVERSION_BUILD);
 
-    args.powerManagement = powerManagement;
-    args.gpuProfiler = gpuProfiler;
-
     if (showArgs)
     {
         gckOS_DumpParam();
     }
 
-    if (logFileSize != 0)
-    {
-        gckDEBUGFS_Initialize();
-    }
-
     /* Create the GAL device. */
-    status = gckGALDEVICE_Construct(
-        irqLine,
-        registerMemBase, registerMemSize,
-        irqLine2D,
-        registerMemBase2D, registerMemSize2D,
-        irqLineVG,
-        registerMemBaseVG, registerMemSizeVG,
-        contiguousBase, contiguousSize,
-        externalBase, externalSize,
-        bankSize, fastClear, compression, baseAddress, physSize, signal,
-        logFileSize,
-        powerManagement,
-        gpuProfiler,
-        &args,
-        &device
-    );
+    status = gckGALDEVICE_Construct(platform, &moduleParam, &device);
 
     if (gcmIS_ERROR(status))
     {
@@ -771,9 +901,7 @@ static int drv_init(void)
     if (type == 1)
     {
         /* Register as misc driver. */
-        ret = misc_register(&gal_device);
-
-        if (ret < 0)
+        if (misc_register(&gal_device) < 0)
         {
             gcmkTRACE_ZONE(
                 gcvLEVEL_ERROR, gcvZONE_DRIVER,
@@ -787,9 +915,9 @@ static int drv_init(void)
     else
     {
         /* Register the character device. */
-        ret = register_chrdev(major, DEVICE_NAME, &driver_fops);
+        int result = register_chrdev(major, DEVICE_NAME, &driver_fops);
 
-        if (ret < 0)
+        if (result < 0)
         {
             gcmkTRACE_ZONE(
                 gcvLEVEL_ERROR, gcvZONE_DRIVER,
@@ -802,7 +930,7 @@ static int drv_init(void)
 
         if (major == 0)
         {
-            major = ret;
+            major = result;
         }
 
         /* Create the device class. */
@@ -836,25 +964,27 @@ static int drv_init(void)
         );
 
     /* Success. */
-    gcmkFOOTER_NO();
-    return 0;
+    ret = 0;
 
 OnError:
-    /* Roll back. */
-    if (device_class != gcvNULL)
+    if (ret)
     {
-        device_destroy(device_class, MKDEV(major, 0));
-        class_destroy(device_class);
-    }
+        /* Roll back. */
+        if (device_class)
+        {
+            device_destroy(device_class, MKDEV(major, 0));
+            class_destroy(device_class);
+        }
 
-    if (device != gcvNULL)
-    {
-        gcmkVERIFY_OK(gckGALDEVICE_Stop(device));
-        gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
+        if (device)
+        {
+            gcmkVERIFY_OK(gckGALDEVICE_Stop(device));
+            gcmkVERIFY_OK(gckGALDEVICE_Destroy(device));
+        }
     }
 
     gcmkFOOTER();
-    return result;
+    return ret;
 }
 
 static void drv_exit(void)
@@ -877,11 +1007,6 @@ static void drv_exit(void)
     gcmkVERIFY_OK(gckGALDEVICE_Stop(galDevice));
     gcmkVERIFY_OK(gckGALDEVICE_Destroy(galDevice));
 
-    if(gckDEBUGFS_IsEnabled())
-    {
-        gckDEBUGFS_Terminate();
-    }
-
     gcmkFOOTER_NO();
 }
 
@@ -892,15 +1017,11 @@ int viv_drm_remove(struct device *dev);
 
 struct device *galcore_device = NULL;
 
-#if USE_LINUX_PCIE
-static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
-#else /* USE_LINUX_PCIE */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
-    static int gpu_probe(struct platform_device *pdev)
+static int gpu_probe(struct platform_device *pdev)
 #else
-    static int __devinit gpu_probe(struct platform_device *pdev)
+static int __devinit gpu_probe(struct platform_device *pdev)
 #endif
-#endif /* USE_LINUX_PCIE */
 {
     int ret = -ENODEV;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
@@ -909,68 +1030,15 @@ static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
     static u64 dma_mask = DMA_40BIT_MASK;
 #endif
 
-    gcsMODULE_PARAMETERS moduleParam = {
-        .irqLine            = irqLine,
-        .registerMemBase    = registerMemBase,
-        .registerMemSize    = registerMemSize,
-        .irqLine2D          = irqLine2D,
-        .registerMemBase2D  = registerMemBase2D,
-        .registerMemSize2D  = registerMemSize2D,
-        .irqLineVG          = irqLineVG,
-        .registerMemBaseVG  = registerMemBaseVG,
-        .registerMemSizeVG  = registerMemSizeVG,
-        .contiguousSize     = contiguousSize,
-        .contiguousBase     = contiguousBase,
-        .externalSize       = externalSize,
-        .externalBase       = externalBase,
-        .bankSize           = bankSize,
-        .fastClear          = fastClear,
-        .powerManagement    = powerManagement,
-        .gpuProfiler        = gpuProfiler,
-        .signal             = signal,
-        .baseAddress        = baseAddress,
-        .physSize           = physSize,
-        .logFileSize        = logFileSize,
-        .recovery           = recovery,
-        .stuckDump          = stuckDump,
-        .showArgs           = showArgs,
-        .gpu3DMinClock      = gpu3DMinClock,
-        .registerMemMapped    = registerMemMapped,
-    };
-
     gcmkHEADER();
 
-    memcpy(moduleParam.irqs, irqs, gcmSIZEOF(gctINT) * gcvCORE_COUNT);
-    memcpy(moduleParam.registerBases, registerBases, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
-    memcpy(moduleParam.registerSizes, registerSizes, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
-    memcpy(moduleParam.chipIDs, chipIDs, gcmSIZEOF(gctUINT) * gcvCORE_COUNT);
     moduleParam.compression = compression;
     platform->device = pdev;
     galcore_device = &pdev->dev;
 
-#if USE_LINUX_PCIE
-    if (pci_enable_device(pdev)) {
-        printk(KERN_ERR "galcore: pci_enable_device() failed.\n");
-    }
-
-    if (pci_set_dma_mask(pdev, dma_mask)) {
-        printk(KERN_ERR "galcore: Failed to set DMA mask.\n");
-    }
-
-    pci_set_master(pdev);
-
-    if (pci_request_regions(pdev, "galcore")) {
-        printk(KERN_ERR "galcore: Failed to get ownership of BAR region.\n");
-    }
-
-#if USE_MSI
-    if (pci_enable_msi(pdev)) {
-        printk(KERN_ERR "galcore: Failed to enable MSI.\n");
-    }
-#  endif
-#else
     galcore_device->dma_mask = &dma_mask;
-#endif
+
+    galcore_device->coherent_dma_mask = dma_mask;
 
     if (platform->ops->getPower)
     {
@@ -981,24 +1049,23 @@ static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         }
     }
 
+    /* Gather module parameters. */
+    _InitModuleParam(&moduleParam);
+
     if (platform->ops->adjustParam)
     {
         /* Override default module param. */
         platform->ops->adjustParam(platform, &moduleParam);
-
-        /* Update module param because drv_init() uses them directly. */
-        _UpdateModuleParam(&moduleParam);
     }
 
+    /* Update module param because drv_init() uses them directly. */
+    _SyncModuleParam(&moduleParam);
+
     ret = drv_init();
 
     if (!ret)
     {
-#if USE_LINUX_PCIE
-        pci_set_drvdata(pdev, galDevice);
-#else
         platform_set_drvdata(pdev, galDevice);
-#endif
 
 #if gcdENABLE_DRM
         ret = viv_drm_probe(&pdev->dev);
@@ -1013,18 +1080,16 @@ static int gpu_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
     {
         gcmkFOOTER_NO();
     }
+
+    gcmkFOOTER_ARG(KERN_INFO "Success ret=%d", ret);
     return ret;
 }
 
-#if USE_LINUX_PCIE
-static void gpu_remove(struct pci_dev *pdev)
-#else /* USE_LINUX_PCIE */
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
-    static int gpu_remove(struct platform_device *pdev)
+static int gpu_remove(struct platform_device *pdev)
 #else
   static int __devexit gpu_remove(struct platform_device *pdev)
+ static int __devexit gpu_remove(struct platform_device *pdev)
 #endif
-#endif /* USE_LINUX_PCIE */
 {
     gcmkHEADER();
 
@@ -1039,22 +1104,10 @@ static void gpu_remove(struct pci_dev *pdev)
         platform->ops->putPower(platform);
     }
 
-#if USE_LINUX_PCIE
-    pci_set_drvdata(pdev, NULL);
-#if USE_MSI
-    pci_disable_msi(pdev);
-#endif
-    pci_clear_master(pdev);
-    pci_release_regions(pdev);
-    pci_disable_device(pdev);
-    gcmkFOOTER_NO();
-    return;
-#else
     galcore_device->dma_mask = NULL;
     galcore_device = NULL;
     gcmkFOOTER_NO();
     return 0;
-#endif
 }
 
 static int gpu_suspend(struct platform_device *dev, pm_message_t state)
@@ -1083,7 +1136,7 @@ static int gpu_suspend(struct platform_device *dev, pm_message_t state)
             else
 #endif
             {
-                status = gckHARDWARE_QueryPowerManagementState(device->kernels[i]->hardware, &device->statesStored[i]);
+                status = gckHARDWARE_QueryPowerState(device->kernels[i]->hardware, &device->statesStored[i]);
             }
 
             if (gcmIS_ERROR(status))
@@ -1095,12 +1148,12 @@ static int gpu_suspend(struct platform_device *dev, pm_message_t state)
 #if gcdENABLE_VG
             if (i == gcvCORE_VG)
             {
-                status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
+                status = gckVGHARDWARE_SetPowerState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
             }
             else
 #endif
             {
-                status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON);
+                status = gckHARDWARE_SetPowerState(device->kernels[i]->hardware, gcvPOWER_ON);
             }
 
             if (gcmIS_ERROR(status))
@@ -1111,12 +1164,12 @@ static int gpu_suspend(struct platform_device *dev, pm_message_t state)
 #if gcdENABLE_VG
             if (i == gcvCORE_VG)
             {
-                status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_OFF);
+                status = gckVGHARDWARE_SetPowerState(device->kernels[i]->vg->hardware, gcvPOWER_OFF);
             }
             else
 #endif
             {
-                status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_OFF);
+                status = gckHARDWARE_SetPowerState(device->kernels[i]->hardware, gcvPOWER_OFF);
             }
 
             if (gcmIS_ERROR(status))
@@ -1151,12 +1204,12 @@ static int gpu_resume(struct platform_device *dev)
 #if gcdENABLE_VG
             if (i == gcvCORE_VG)
             {
-                status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
+                status = gckVGHARDWARE_SetPowerState(device->kernels[i]->vg->hardware, gcvPOWER_ON);
             }
             else
 #endif
             {
-                status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, gcvPOWER_ON);
+                status = gckHARDWARE_SetPowerState(device->kernels[i]->hardware, gcvPOWER_ON);
             }
 
             if (gcmIS_ERROR(status))
@@ -1167,8 +1220,8 @@ static int gpu_resume(struct platform_device *dev)
             /* Convert global state to crossponding internal state. */
             switch(device->statesStored[i])
             {
-            case gcvPOWER_OFF:
-                statesStored = gcvPOWER_OFF_BROADCAST;
+            case gcvPOWER_ON:
+                statesStored = gcvPOWER_ON_AUTO;
                 break;
             case gcvPOWER_IDLE:
                 statesStored = gcvPOWER_IDLE_BROADCAST;
@@ -1176,8 +1229,8 @@ static int gpu_resume(struct platform_device *dev)
             case gcvPOWER_SUSPEND:
                 statesStored = gcvPOWER_SUSPEND_BROADCAST;
                 break;
-            case gcvPOWER_ON:
-                statesStored = gcvPOWER_ON_AUTO;
+            case gcvPOWER_OFF:
+                statesStored = gcvPOWER_OFF_BROADCAST;
                 break;
             default:
                 statesStored = device->statesStored[i];
@@ -1188,7 +1241,7 @@ static int gpu_resume(struct platform_device *dev)
 #if gcdENABLE_VG
             if (i == gcvCORE_VG)
             {
-                status = gckVGHARDWARE_SetPowerManagementState(device->kernels[i]->vg->hardware, statesStored);
+                status = gckVGHARDWARE_SetPowerState(device->kernels[i]->vg->hardware, statesStored);
             }
             else
 #endif
@@ -1197,7 +1250,7 @@ static int gpu_resume(struct platform_device *dev)
 
                 for (; j < 100; j++)
                 {
-                    status = gckHARDWARE_SetPowerManagementState(device->kernels[i]->hardware, statesStored);
+                    status = gckHARDWARE_SetPowerState(device->kernels[i]->hardware, statesStored);
 
                     if (( statesStored != gcvPOWER_OFF_BROADCAST
                        && statesStored != gcvPOWER_SUSPEND_BROADCAST)
@@ -1239,30 +1292,6 @@ static const struct dev_pm_ops gpu_pm_ops = {
 };
 #endif
 
-#if USE_LINUX_PCIE
-static const struct pci_device_id vivpci_ids[] = {
-  {
-    .class = 0x000000,
-    .class_mask = 0x000000,
-    .vendor = 0x10ee,
-    .device = 0x7012,
-    .subvendor = PCI_ANY_ID,
-    .subdevice = PCI_ANY_ID,
-    .driver_data = 0
-  }, { /* End: all zeroes */ }
-};
-
-MODULE_DEVICE_TABLE(pci, vivpci_ids);
-
-static struct pci_driver gpu_driver = {
-    .name = DEVICE_NAME,
-    .id_table = vivpci_ids,
-    .probe = gpu_probe,
-    .remove = gpu_remove
-};
-
-#else /* USE_LINUX_PCIE */
-
 static struct platform_driver gpu_driver = {
     .probe      = gpu_probe,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)
@@ -1282,13 +1311,12 @@ static struct platform_driver gpu_driver = {
 #endif
     }
 };
-#endif /* USE_LINUX_PCIE */
 
 static int __init gpu_init(void)
 {
     int ret = 0;
 
-    ret = soc_platform_init(&gpu_driver, &platform);
+    ret = gckPLATFORM_Init(&gpu_driver, &platform);
 
     if (ret || !platform)
     {
@@ -1296,34 +1324,25 @@ static int __init gpu_init(void)
         return -ENODEV;
     }
 
-#if USE_LINUX_PCIE
-    ret = pci_register_driver(&gpu_driver);
-#else /* USE_LINUX_PCIE */
     ret = platform_driver_register(&gpu_driver);
-#endif /* USE_LINUX_PCIE */
 
     if (ret)
     {
         printk(KERN_ERR "galcore: gpu_init() failed to register driver!\n");
-        soc_platform_terminate(platform);
+        gckPLATFORM_Terminate(platform);
         platform = NULL;
-        return ret;
+        return -ENODEV;
     }
 
     platform->driver = &gpu_driver;
-
     return 0;
 }
 
 static void __exit gpu_exit(void)
 {
-#if USE_LINUX_PCIE
-    pci_unregister_driver(&gpu_driver);
-#else
     platform_driver_unregister(&gpu_driver);
-#endif /* USE_LINUX_PCIE */
 
-    soc_platform_terminate(platform);
+    gckPLATFORM_Terminate(platform);
     platform = NULL;
 }
 
index 1fd3401..41532ba 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -86,7 +86,7 @@ struct dma_buf *viv_gem_prime_export(struct drm_device *drm,
     if (gal_dev)
     {
         gckKERNEL kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
-        gcmkVERIFY_OK(gckVIDMEM_NODE_Export(kernel, viv_obj->node_handle, flags,
+        gcmkVERIFY_OK(gckVIDMEM_NODE_Export(kernel, viv_obj->node_object, flags,
                                             (gctPOINTER*)&dmabuf, gcvNULL));
     }
 
@@ -168,7 +168,7 @@ static int viv_ioctl_gem_create(struct drm_device *drm, void *data,
     gckVIDMEM_NODE nodeObject;
     gctUINT32 flags = gcvALLOC_FLAG_DMABUF_EXPORTABLE;
     gceSTATUS status = gcvSTATUS_OK;
-    gcePOOL pool = gcvPOOL_DEFAULT;
+    gctUINT64 alignSize = PAGE_ALIGN(args->size);
 
     gal_dev = (gckGALDEVICE)drm->dev_private;
     if (!gal_dev)
@@ -192,19 +192,15 @@ static int viv_ioctl_gem_create(struct drm_device *drm, void *data,
     {
         flags |= gcvALLOC_FLAG_CMA_LIMIT;
     }
-    if (args->flags & DRM_VIV_GEM_VIRTUAL_POOL) {
-        flags &= ~(gcvALLOC_FLAG_CMA_LIMIT | gcvALLOC_FLAG_CONTIGUOUS);
-        pool = gcvPOOL_VIRTUAL;
-    }
 
     gckOS_ZeroMemory(&iface, sizeof(iface));
     iface.command = gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY;
     iface.hardwareType = gal_dev->device->defaultHwType;
-    iface.u.AllocateLinearVideoMemory.bytes = PAGE_ALIGN(args->size);
+    iface.u.AllocateLinearVideoMemory.bytes = alignSize;
     iface.u.AllocateLinearVideoMemory.alignment = 256;
-    iface.u.AllocateLinearVideoMemory.type = gcvSURF_RENDER_TARGET; /* should be general */
+    iface.u.AllocateLinearVideoMemory.type = gcvVIDMEM_TYPE_GENERIC;
     iface.u.AllocateLinearVideoMemory.flag = flags;
-    iface.u.AllocateLinearVideoMemory.pool = pool;
+    iface.u.AllocateLinearVideoMemory.pool = gcvPOOL_DEFAULT;
     gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
 
     kernel = gal_dev->device->map[gal_dev->device->defaultHwType].kernels[0];
@@ -213,7 +209,7 @@ static int viv_ioctl_gem_create(struct drm_device *drm, void *data,
 
     /* ioctl output */
     gem_obj = kzalloc(sizeof(struct viv_gem_object), GFP_KERNEL);
-    drm_gem_private_object_init(drm, gem_obj, iface.u.AllocateLinearVideoMemory.bytes);
+    drm_gem_private_object_init(drm, gem_obj, (size_t)alignSize);
     ret = drm_gem_handle_create(file, gem_obj, &args->handle);
 
     viv_obj = container_of(gem_obj, struct viv_gem_object, base);
@@ -297,14 +293,14 @@ static int viv_ioctl_gem_unlock(struct drm_device *drm, void *data,
     iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
     iface.hardwareType = gal_dev->device->defaultHwType;
     iface.u.UnlockVideoMemory.node = (gctUINT64)viv_obj->node_handle;
-    iface.u.UnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN;
+    iface.u.UnlockVideoMemory.type = gcvVIDMEM_TYPE_GENERIC;
     gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
 
     memset(&iface, 0, sizeof(iface));
     iface.command = gcvHAL_BOTTOM_HALF_UNLOCK_VIDEO_MEMORY;
     iface.hardwareType = gal_dev->device->defaultHwType;
     iface.u.BottomHalfUnlockVideoMemory.node = (gctUINT64)viv_obj->node_handle;
-    iface.u.BottomHalfUnlockVideoMemory.type = gcvSURF_TYPE_UNKNOWN;
+    iface.u.BottomHalfUnlockVideoMemory.type = gcvVIDMEM_TYPE_GENERIC;
     gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
 
 OnError:
@@ -562,6 +558,8 @@ static int viv_ioctl_gem_attach_aux(struct drm_device *drm, void *data,
         gctBOOL is2BitPerTile = gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_TILE_STATUS_2BITS);
         gctBOOL isCompressionDEC400 = gckHARDWARE_IsFeatureAvailable(kernel->hardware , gcvFEATURE_COMPRESSION_DEC400);
         gctPOINTER entry = gcvNULL;
+        gckVIDMEM_NODE ObjNode = gcvNULL;
+        gctUINT32 processID = 0;
         gctUINT32 tileStatusFiller = (isCompressionDEC400 || ((kernel->hardware->identity.chipModel == gcv500) && (kernel->hardware->identity.chipRevision > 2)))
                                   ? 0xFFFFFFFF
                                   : is2BitPerTile ? 0x55555555 : 0x11111111;
@@ -585,10 +583,13 @@ static int viv_ioctl_gem_attach_aux(struct drm_device *drm, void *data,
         iface.u.LockVideoMemory.cacheable = viv_ts_obj->cacheable;
         gcmkONERROR(gckDEVICE_Dispatch(gal_dev->device, &iface));
 
+        gcmkONERROR(gckOS_GetProcessID(&processID));
+        gcmkONERROR(gckVIDMEM_HANDLE_Lookup(kernel, processID, viv_ts_obj->node_handle, &ObjNode));
+        gcmkONERROR(gckVIDMEM_NODE_LockCPU(kernel, ObjNode, gcvFALSE, gcvFALSE, &entry));
+
         /* Fill tile status node with tileStatusFiller. */
-        gcmkONERROR(gckVIDMEM_NODE_LockCPU(kernel, viv_ts_obj->node_handle, &entry));
         memset(entry , tileStatusFiller , (__u64)gem_ts_obj->size);
-        gcmkONERROR(gckVIDMEM_NODE_UnlockCPU(kernel, viv_ts_obj->node_handle, entry));
+        gcmkONERROR(gckVIDMEM_NODE_UnlockCPU(kernel, ObjNode, 0, gcvFALSE));
 
         /* UnLock tile status node. */
         memset(&iface, 0, sizeof(iface));
index f36e116..ae86dd2 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -95,9 +95,11 @@ _FlatMapping(
     IN gckIOMMU Iommu
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     gctUINT32 physical;
 
+    gcmkHEADER_ARG("Iommu=%p", Iommu);
+
     for (physical = 0; physical < 0x80000000; physical += PAGE_SIZE)
     {
         gcmkTRACE_ZONE(
@@ -109,9 +111,8 @@ _FlatMapping(
         gcmkONERROR(gckIOMMU_Map(Iommu, physical, physical, PAGE_SIZE));
     }
 
-    return gcvSTATUS_OK;
-
 OnError:
+    gcmkFOOTER();
     return status;
 }
 
@@ -121,7 +122,7 @@ gckIOMMU_Destory(
     IN gckIOMMU Iommu
     )
 {
-    gcmkHEADER();
+    gcmkHEADER_ARG("Os=%p Iommu=%p", Os, Iommu);
 
     if (Iommu->domain && Iommu->device)
     {
@@ -147,12 +148,11 @@ gckIOMMU_Construct(
     OUT gckIOMMU * Iommu
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     gckIOMMU iommu = gcvNULL;
     struct device *dev;
-    int ret;
 
-    gcmkHEADER();
+    gcmkHEADER_ARG("Os=%p", Os);
 
     dev = &Os->device->platform->device->dev;
 
@@ -165,7 +165,6 @@ gckIOMMU_Construct(
     if (!iommu->domain)
     {
         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "iommu_domain_alloc() fail");
-
         gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
     }
 
@@ -175,13 +174,9 @@ gckIOMMU_Construct(
     iommu_set_fault_handler(iommu->domain, _IOMMU_Fault_Handler);
 #endif
 
-    ret = iommu_attach_device(iommu->domain, dev);
-
-    if (ret)
+    if (iommu_attach_device(iommu->domain, dev))
     {
-        gcmkTRACE_ZONE(
-            gcvLEVEL_INFO, gcvZONE_OS, "iommu_attach_device() fail %d", ret);
-
+        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "iommu_attach_device() fail");
         gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
     }
 
@@ -191,12 +186,11 @@ gckIOMMU_Construct(
 
     *Iommu = iommu;
 
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
-
-    gckIOMMU_Destory(Os, iommu);
+    if (gcmIS_ERROR(status))
+    {
+        gckIOMMU_Destory(Os, iommu);
+    }
 
     gcmkFOOTER();
     return status;
@@ -210,27 +204,19 @@ gckIOMMU_Map(
     IN gctUINT32 Bytes
     )
 {
-    gceSTATUS status;
-    int ret;
+    gceSTATUS status = gcvSTATUS_OK;
 
     gcmkHEADER_ARG("DomainAddress=%#X, Physical=%#X, Bytes=%d",
                    DomainAddress, Physical, Bytes);
 
-    ret = iommu_map(Iommu->domain, DomainAddress, Physical, Bytes, 0);
-
-    if (ret)
+    if (iommu_map(Iommu->domain, DomainAddress, Physical, Bytes, 0))
     {
         gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
     }
 
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
-
     gcmkFOOTER();
     return status;
-
 }
 
 gceSTATUS
index 5efa3d4..3b72a66 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -97,15 +97,15 @@ gckKERNEL_QueryVideoMemory(
 
     /* Get internal memory size and physical address. */
     Interface->u.QueryVideoMemory.internalSize = device->internalSize;
-    Interface->u.QueryVideoMemory.internalPhysical = device->internalPhysicalName;
+    Interface->u.QueryVideoMemory.internalPhysName = device->internalPhysName;
 
     /* Get external memory size and physical address. */
     Interface->u.QueryVideoMemory.externalSize = device->externalSize;
-    Interface->u.QueryVideoMemory.externalPhysical = device->externalPhysicalName;
+    Interface->u.QueryVideoMemory.externalPhysName = device->externalPhysName;
 
     /* Get contiguous memory size and physical address. */
     Interface->u.QueryVideoMemory.contiguousSize = device->contiguousSize;
-    Interface->u.QueryVideoMemory.contiguousPhysical = device->contiguousPhysicalName;
+    Interface->u.QueryVideoMemory.contiguousPhysName = device->contiguousPhysName;
 
     /* Success. */
     gcmkFOOTER_NO();
@@ -169,6 +169,11 @@ gckKERNEL_GetVideoMemoryPool(
         videoMemory = device->contiguousVidMem;
         break;
 
+    case gcvPOOL_SRAM:
+        /* SRAM memory. */
+        videoMemory = Kernel->sRAMVideoMem[Kernel->sRAMIndex];
+        break;
+
     default:
         /* Unknown pool. */
         videoMemory = NULL;
@@ -273,8 +278,14 @@ gckKERNEL_UnmapMemory(
 **      gctBOOL InUserSpace
 **          gcvTRUE to map the memory into the user space.
 **
-**      gctUINT32 Address
-**          Hardware specific memory address.
+**      gcePOOL Pool
+**          Specify pool type.
+**
+**      gctUINT32 Offset
+**          Offset to pool start.
+**
+**      gctUINT32 Bytes
+**          Number of bytes to map.
 **
 **  OUTPUT:
 **
@@ -283,28 +294,23 @@ gckKERNEL_UnmapMemory(
 **          specified memory address.
 */
 gceSTATUS
-gckKERNEL_MapVideoMemoryEx(
+gckKERNEL_MapVideoMemory(
     IN gckKERNEL Kernel,
-    IN gceCORE Core,
     IN gctBOOL InUserSpace,
-    IN gctUINT32 Address,
     IN gcePOOL Pool,
+    IN gctUINT32 Offset,
+    IN gctUINT32 Bytes,
     OUT gctPOINTER * Logical
     )
 {
     gckGALDEVICE device   = gcvNULL;
-    gctUINT32 offset      = 0;
-    gctUINT32 base        = 0;
     gctSIZE_T bytes       = 0;
-    gctPHYS_ADDR physical = gcvNULL;
-    gceSTATUS status;
+    gctPHYS_ADDR physHandle = gcvNULL;
+    gceSTATUS status      = gcvSTATUS_OK;
     gctPOINTER logical    = gcvNULL;
-#if gcdENABLE_VG
-    gcePOOL pool = gcvPOOL_UNKNOWN;
-#endif
 
-    gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Address=%08x",
-                   Kernel, InUserSpace, Address);
+    gcmkHEADER_ARG("Kernel=%p InUserSpace=%d Pool=%d Offset=%X Bytes=%X",
+                   Kernel, InUserSpace, Pool, Offset, Bytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
@@ -313,70 +319,29 @@ gckKERNEL_MapVideoMemoryEx(
     /* Extract the pointer to the gckGALDEVICE class. */
     device = (gckGALDEVICE) Kernel->context;
 
-#if gcdENABLE_VG
-    if (Core == gcvCORE_VG)
-    {
-        /* Split the memory address into a pool type and offset. */
-        gcmkONERROR(
-            gckVGHARDWARE_SplitMemory(Kernel->vg->hardware, Address, &pool, &offset));
-    }
-    else
-#endif
-    {
-        offset = Address;
-    }
-
     /* Dispatch on pool. */
     switch (Pool)
     {
     case gcvPOOL_LOCAL_INTERNAL:
-        /* Internal memory. */
-        logical = device->internalLogical;
-        /* Impossible to use per device logical for all user processes. */
-        BUG_ON("Incorrect path");
+        physHandle = (PLINUX_MDL)device->internalPhysical;
+        bytes = device->internalSize;
         break;
 
     case gcvPOOL_LOCAL_EXTERNAL:
-        physical = device->externalPhysical;
+        physHandle = (PLINUX_MDL)device->externalPhysical;
         bytes = device->externalSize;
-
-#if gcdENABLE_VG
-        if (Core == gcvCORE_VG)
-        {
-            gcmkVERIFY_OK(
-                gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
-                                        device->externalVidMem->baseAddress,
-                                        &pool,
-                                        &base));
-        }
-        else
-#endif
-        {
-            base = Kernel->externalBaseAddress;
-        }
-
         break;
 
     case gcvPOOL_SYSTEM:
         /* System memory. */
-        physical = device->contiguousPhysical;
+        physHandle = (PLINUX_MDL)device->contiguousPhysical;
         bytes = device->contiguousSize;
+        break;
 
-#if gcdENABLE_VG
-        if (Core == gcvCORE_VG)
-        {
-            gcmkVERIFY_OK(
-                gckVGHARDWARE_SplitMemory(Kernel->vg->hardware,
-                                        device->contiguousVidMem->baseAddress,
-                                        &pool,
-                                        &base));
-        }
-        else
-#endif
-        {
-            base = Kernel->contiguousBaseAddress;
-        }
-
+    case gcvPOOL_SRAM:
+        /* SRAM memory. */
+        physHandle = (PLINUX_MDL)Kernel->sRAMPhysical[Kernel->sRAMIndex];
+        bytes = Kernel->sRAMSizes[Kernel->sRAMIndex];
         break;
 
     default:
@@ -384,58 +349,17 @@ gckKERNEL_MapVideoMemoryEx(
         gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
     }
 
-    gcmkONERROR(gckOS_MapMemory(Kernel->os, physical, bytes, &logical));
-
-    /* GPU address offset */
-    offset -= base;
+    gcmkONERROR(gckOS_MapMemory(Kernel->os, physHandle, bytes, &logical));
 
     /* Build logical address of specified address. */
-    *Logical = (gctPOINTER) ((gctUINT8_PTR) logical + offset);
-
-    /* Success. */
-    gcmkFOOTER_ARG("*Logical=%p", *Logical);
-    return gcvSTATUS_OK;
+    *Logical = (gctPOINTER)((gctUINT8_PTR)logical + Offset);
 
 OnError:
     /* Retunn the status. */
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*Logical=%p", gcmOPT_POINTER(Logical));
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckKERNEL_MapVideoMemory
-**
-**  Get the logical address for a hardware specific memory address for the
-**  current process.
-**
-**  INPUT:
-**
-**      gckKERNEL Kernel
-**          Pointer to an gckKERNEL object.
-**
-**      gctBOOL InUserSpace
-**          gcvTRUE to map the memory into the user space.
-**
-**      gctUINT32 Address
-**          Hardware specific memory address.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * Logical
-**          Pointer to a variable that will hold the logical address of the
-**          specified memory address.
-*/
-gceSTATUS
-gckKERNEL_MapVideoMemory(
-    IN gckKERNEL Kernel,
-    IN gctBOOL InUserSpace,
-    IN gctUINT32 Address,
-    OUT gctPOINTER * Logical
-    )
-{
-    return gckKERNEL_MapVideoMemoryEx(Kernel, gcvCORE_MAJOR, InUserSpace, Address, gcvPOOL_SYSTEM, Logical);
-}
 /*******************************************************************************
 **
 **  gckKERNEL_Notify
@@ -457,11 +381,15 @@ gckKERNEL_MapVideoMemory(
 gceSTATUS
 gckKERNEL_Notify(
     IN gckKERNEL Kernel,
-    IN gceNOTIFY Notification,
-    IN gctBOOL Data
+    IN gceNOTIFY Notification
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
+
+    gcmkHEADER_ARG("Kernel=%p Notification=%d", Kernel, Notification);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
 
     /* Dispatch on notifcation. */
     switch (Notification)
@@ -469,42 +397,17 @@ gckKERNEL_Notify(
     case gcvNOTIFY_INTERRUPT:
         /* Process the interrupt. */
 #if COMMAND_PROCESSOR_VERSION > 1
-        status = gckINTERRUPT_Notify(Kernel->interrupt, Data);
+        status = gckINTERRUPT_Notify(Kernel->interrupt, 0);
 #else
-        status = gckHARDWARE_Interrupt(Kernel->hardware, Data);
+        status = gckHARDWARE_Notify(Kernel->hardware);
 #endif
         break;
 
     default:
-        status = gcvSTATUS_OK;
         break;
     }
 
     /* Success. */
+    gcmkFOOTER();
     return status;
 }
-
-gceSTATUS
-gckKERNEL_QuerySettings(
-    IN gckKERNEL Kernel,
-    OUT gcsKERNEL_SETTINGS * Settings
-    )
-{
-    gckGALDEVICE device;
-
-    gcmkHEADER_ARG("Kernel=%p", Kernel);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL);
-    gcmkVERIFY_ARGUMENT(Settings != gcvNULL);
-
-    /* Extract the pointer to the gckGALDEVICE class. */
-    device = (gckGALDEVICE) Kernel->context;
-
-    /* Fill in signal. */
-    Settings->signal = device->signal;
-
-    /* Success. */
-    gcmkFOOTER_ARG("Settings->signal=%d", Settings->signal);
-    return gcvSTATUS_OK;
-}
index c536e44..935d70b 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 #  include <linux/modversions.h>
 #endif
 #include <asm/io.h>
-#include <asm/uaccess.h>
+#if LINUX_VERSION_CODE > KERNEL_VERSION(4,7,0)
+    #include <linux/uaccess.h>
+#else
+    #include <asm/uaccess.h>
+#endif
 
 #if ENABLE_GPU_CLOCK_BY_DRIVER && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
 #include <linux/clk.h>
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 1, 0)
 #ifdef gcdIRQ_SHARED
-#       define gcdIRQF_FLAG   (IRQF_SHARED)
+#       define gcdIRQF_FLAG   (IRQF_SHARED | IRQF_TRIGGER_HIGH)
 #   else
-#       define gcdIRQF_FLAG   (0)
+#       define gcdIRQF_FLAG   (IRQF_TRIGGER_HIGH)
 #   endif
 #else
 #ifdef gcdIRQ_SHARED
-#       define gcdIRQF_FLAG   (IRQF_DISABLED | IRQF_SHARED)
+#       define gcdIRQF_FLAG   (IRQF_DISABLED | IRQF_SHARED | IRQF_TRIGGER_HIGH)
 #   else
-#       define gcdIRQF_FLAG   (IRQF_DISABLED)
+#       define gcdIRQF_FLAG   (IRQF_DISABLED | IRQF_TRIGGER_HIGH)
 #   endif
 #endif
 
@@ -168,29 +172,6 @@ extern struct device *galcore_device;
 \******************************************************************************/
 typedef struct _gcsIOMMU * gckIOMMU;
 
-typedef struct _gcsUSER_MAPPING * gcsUSER_MAPPING_PTR;
-typedef struct _gcsUSER_MAPPING
-{
-    /* Pointer to next mapping structure. */
-    gcsUSER_MAPPING_PTR         next;
-
-    /* Physical address of this mapping. */
-    gctUINT32                   physical;
-
-    /* Logical address of this mapping. */
-    gctPOINTER                  logical;
-
-    /* Number of bytes of this mapping. */
-    gctSIZE_T                   bytes;
-
-    /* Starting address of this mapping. */
-    gctINT8_PTR                 start;
-
-    /* Ending address of this mapping. */
-    gctINT8_PTR                 end;
-}
-gcsUSER_MAPPING;
-
 typedef struct _gcsINTEGER_DB * gcsINTEGER_DB_PTR;
 typedef struct _gcsINTEGER_DB
 {
@@ -223,8 +204,6 @@ struct _gckOS
     /* signal id database. */
     gcsINTEGER_DB               signalDB;
 
-    gcsUSER_MAPPING_PTR         userMap;
-
     /* workqueue for os timer. */
     struct workqueue_struct *   workqueue;
 
@@ -251,6 +230,14 @@ struct _gckOS
 
     /* IOMMU. */
     gckIOMMU                    iommu;
+
+    /* Dump in kernel. */
+    struct file *               dumpFilp;
+    struct mutex                dumpFilpMutex;
+
+    int                         dumpTarget;
+    char                        dumpFileName[256];
+    gcsDEBUGFS_DIR              dumpDebugfsDir;
 };
 
 typedef struct _gcsSIGNAL * gcsSIGNAL_PTR;
@@ -303,23 +290,6 @@ gckOS_FreeAllocators(
     gckOS Os
     );
 
-/* Reserved memory. */
-gceSTATUS
-gckOS_RequestReservedMemory(
-    gckOS Os,
-    unsigned long Start,
-    unsigned long Size,
-    const char * Name,
-    gctBOOL Requested,
-    void ** MemoryHandle
-    );
-
-void
-gckOS_ReleaseReservedMemory(
-    gckOS Os,
-    void * MemoryHandle
-    );
-
 gceSTATUS
 _ConvertLogical2Physical(
     IN gckOS Os,
index f373f47..3e72ea3 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index d2c94e2..b2d9e6c 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 #include <linux/mutex.h>
 
 /* Create a new mutex. */
-#define gckOS_CreateMutex(Os, Mutex)                                \
-({                                                                  \
-    gceSTATUS _status;                                              \
-    gcmkHEADER_ARG("Os=0x%X", Os);                                  \
-                                                                    \
-    /* Validate the arguments. */                                   \
-    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);                               \
-    gcmkVERIFY_ARGUMENT(Mutex != gcvNULL);                          \
-                                                                    \
-    /* Allocate the mutex structure. */                             \
-    _status = gckOS_Allocate(Os, gcmSIZEOF(struct mutex), Mutex);   \
-                                                                    \
-    if (gcmIS_SUCCESS(_status))                                     \
-    {                                                               \
-        /* Initialize the mutex. */                                 \
-        mutex_init(*(struct mutex **)Mutex);                        \
-    }                                                               \
-                                                                    \
-    /* Return status. */                                            \
-    gcmkFOOTER_ARG("*Mutex=0x%X", *(struct mutex **)Mutex);         \
-    _status;                                                        \
+#define gckOS_CreateMutex(Os, Mutex)                                        \
+({                                                                          \
+    /* Allocate the mutex structure. */                                     \
+    gceSTATUS _status = gckOS_Allocate(Os, gcmSIZEOF(struct mutex), Mutex); \
+                                                                            \
+    if (gcmIS_SUCCESS(_status))                                             \
+    {                                                                       \
+        /* Initialize the mutex. */                                         \
+        mutex_init(*(struct mutex **)Mutex);                                \
+    }                                                                       \
+                                                                            \
+    _status;                                                                \
 })
 
 #endif
index 0d06fc1..0e8f386 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -54,6 +54,7 @@
 
 
 #include "gc_hal_kernel_linux.h"
+#include "gc_hal_dump.h"
 
 #include <linux/pagemap.h>
 #include <linux/seq_file.h>
@@ -121,16 +122,15 @@ _CreateMdlMap(
     IN gctINT ProcessID
     )
 {
-    PLINUX_MDL_MAP  mdlMap;
+    PLINUX_MDL_MAP mdlMap = gcvNULL;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
+    gcmkHEADER_ARG("Mdl=%p ProcessID=%d", Mdl, ProcessID);
 
     mdlMap = (PLINUX_MDL_MAP)kmalloc(sizeof(struct _LINUX_MDL_MAP), GFP_KERNEL | gcdNOWARN);
-
     if (mdlMap == gcvNULL)
     {
-        gcmkFOOTER_NO();
-        return gcvNULL;
+        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
     }
 
     mdlMap->pid     = ProcessID;
@@ -139,7 +139,8 @@ _CreateMdlMap(
 
     list_add(&mdlMap->link, &Mdl->mapsHead);
 
-    gcmkFOOTER_ARG("0x%X", mdlMap);
+OnError:
+    gcmkFOOTER_ARG("ret=%p", mdlMap);
     return mdlMap;
 }
 
@@ -150,7 +151,7 @@ _DestroyMdlMap(
     IN PLINUX_MDL_MAP MdlMap
     )
 {
-    gcmkHEADER_ARG("Mdl=0x%X MdlMap=0x%X", Mdl, MdlMap);
+    gcmkHEADER_ARG("Mdl=%p MdlMap=%p", Mdl, MdlMap);
 
     /* Verify the arguments. */
     gcmkVERIFY_ARGUMENT(MdlMap != gcvNULL);
@@ -169,27 +170,25 @@ FindMdlMap(
     IN gctINT ProcessID
     )
 {
-    PLINUX_MDL_MAP mdlMap;
-
-    gcmkHEADER_ARG("Mdl=0x%X ProcessID=%d", Mdl, ProcessID);
+    PLINUX_MDL_MAP mdlMap = gcvNULL;
 
-    if (Mdl == gcvNULL)
-    {
-        gcmkFOOTER_NO();
-        return gcvNULL;
-    }
+    gcmkHEADER_ARG("Mdl=%p ProcessID=%d", Mdl, ProcessID);
 
-    list_for_each_entry(mdlMap, &Mdl->mapsHead, link)
+    if (Mdl)
     {
-        if (mdlMap->pid == ProcessID)
+        PLINUX_MDL_MAP iter = gcvNULL;
+        list_for_each_entry(iter, &Mdl->mapsHead, link)
         {
-            gcmkFOOTER_ARG("0x%X", mdlMap);
-            return mdlMap;
+            if (iter->pid == ProcessID)
+            {
+                mdlMap = iter;
+                break;
+            }
         }
     }
 
-    gcmkFOOTER_NO();
-    return gcvNULL;
+    gcmkFOOTER_ARG("ret=%p", mdlMap);
+    return mdlMap;
 }
 
 
@@ -212,7 +211,7 @@ _CreateMdl(
         INIT_LIST_HEAD(&mdl->mapsHead);
     }
 
-    gcmkFOOTER_ARG("0x%X", mdl);
+    gcmkFOOTER_ARG("%p", mdl);
     return mdl;
 }
 
@@ -221,7 +220,7 @@ _DestroyMdl(
     IN PLINUX_MDL Mdl
     )
 {
-    gcmkHEADER_ARG("Mdl=0x%X", Mdl);
+    gcmkHEADER_ARG("Mdl=%p", Mdl);
 
     /* Verify the arguments. */
     gcmkVERIFY_ARGUMENT(Mdl != gcvNULL);
@@ -429,7 +428,15 @@ _QueryProcessPageTable(
         if (pgd_none(*pgd) || pgd_bad(*pgd))
             return gcvSTATUS_NOT_FOUND;
 
+#if (defined(CONFIG_CPU_CSKYV2) || defined(CONFIG_X86)) \
+    && LINUX_VERSION_CODE >= KERNEL_VERSION (4,12,0)
+        pud = pud_offset((p4d_t*)pgd, logical);
+#elif (defined(CONFIG_CPU_CSKYV2)) \
+    && LINUX_VERSION_CODE >= KERNEL_VERSION (4,11,0)
+        pud = pud_offset((p4d_t*)pgd, logical);
+#else
         pud = pud_offset(pgd, logical);
+#endif
         if (pud_none(*pud) || pud_bad(*pud))
             return gcvSTATUS_NOT_FOUND;
 
@@ -466,7 +473,7 @@ _ShrinkMemory(
     gcsPLATFORM * platform;
     gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
 
     platform = Os->device->platform;
@@ -477,14 +484,155 @@ _ShrinkMemory(
     }
     else
     {
-        gcmkFOOTER_NO();
-        return gcvSTATUS_NOT_SUPPORTED;
+        status = gcvSTATUS_NOT_SUPPORTED;
     }
 
-    gcmkFOOTER_NO();
+    gcmkFOOTER();
+    return status;
+}
+
+#if gcdDUMP_IN_KERNEL
+
+#define DUMP_TO_KERNEL_DMESG    0
+#define DUMP_TO_FILE            1
+#define DUMP_IGNORE             2
+
+static void set_dump_file(gckOS os, char * fname)
+{
+    if (os->dumpFilp)
+    {
+        /* close exist opened file. */
+        printk("galcore: end dump to file: %s\n", os->dumpFileName);
+
+        filp_close(os->dumpFilp, NULL);
+        os->dumpFilp = NULL;
+    }
+
+    if (fname[0] == '\0' || !strcmp(fname, "[ignored]"))
+    {
+        /* empty or [ignored] means ignored. */
+        printk("galcore: dump ignored\n");
+
+        os->dumpTarget = DUMP_IGNORE;
+        strcpy(os->dumpFileName, "[ignored]");
+    }
+    else if (!strcmp(fname, "[dmesg]"))
+    {
+        /* [dmesg] means dump to kernel dmesg. */
+        printk("galcore: dump to kernel dmesg\n");
+
+        os->dumpTarget = DUMP_TO_KERNEL_DMESG;
+        strcpy(os->dumpFileName, "[dmesg]");
+    }
+    else if (fname[0] != '/')
+    {
+        /* invalid path, switch to kernel dmesg. */
+        printk(KERN_ERR "galcore: invalid path: %s\n", fname);
+        printk(KERN_ERR "galcore: must be absolute path start with '/'\n");
+        printk("galcore: dump to kernel dmesg\n");
+
+        os->dumpTarget = DUMP_TO_KERNEL_DMESG;
+        strcpy(os->dumpFileName, "[dmesg]");
+    }
+    else
+    {
+        /* try open file. */
+        os->dumpFilp = filp_open(fname, O_RDWR | O_CREAT, 0644);
+
+        if (IS_ERR(os->dumpFilp))
+        {
+            printk(KERN_ERR "galcore: failed to open file: %s\n", fname);
+            printk("galcore: dump to kernel dmesg\n");
+
+            os->dumpFilp = NULL;
+            os->dumpTarget = DUMP_TO_KERNEL_DMESG;
+            strcpy(os->dumpFileName, "[dmesg]");
+        }
+        else
+        {
+            printk("galcore: start dump to file: %s\n", fname);
+
+            os->dumpTarget = DUMP_TO_FILE;
+            strcpy(os->dumpFileName, fname);
+        }
+    }
+}
+
+static int dump_file_show(struct seq_file *m, void *unused)
+{
+    gcsINFO_NODE *node = m->private;
+    gckOS os = node->device;
+
+    seq_printf(m, "%s\n", os->dumpFileName);
+    return 0;
+}
+
+static int dump_file_write(const char __user *buf, size_t count, void* data)
+{
+    gcsINFO_NODE *node = data;
+    gckOS os = node->device;
+    char fname[256];
+    size_t len = min(count, sizeof(fname) - 1);
+
+    if (copy_from_user(fname, buf, len))
+    {
+        return -EFAULT;
+    }
+
+    /* Remove tailing space. */
+    while (len > 0 && (fname[len - 1] == '\n' || fname[len - 1] == ' '))
+    {
+        fname[len - 1] = '\0';
+    }
+
+    fname[len] = '\0';
+
+    mutex_lock(&os->dumpFilpMutex);
+    set_dump_file(os, fname);
+    mutex_unlock(&os->dumpFilpMutex);
+
+    return count;
+}
+
+static gcsINFO dumpDebugList[] =
+{
+    {"dump_file", dump_file_show, dump_file_write},
+};
+
+static gceSTATUS
+_DumpDebugfsInit(
+    IN gckOS Os
+    )
+{
+    gceSTATUS status;
+    gckGALDEVICE device = Os->device;
+    gckDEBUGFS_DIR dir = &Os->dumpDebugfsDir;
+
+    gcmkONERROR(gckDEBUGFS_DIR_Init(dir, device->debugfsDir.root, "dump"));
+
+    gcmkONERROR(
+        gckDEBUGFS_DIR_CreateFiles(dir, dumpDebugList,
+                                   gcmCOUNTOF(dumpDebugList), Os));
+
+OnError:
     return status;
 }
 
+static void
+_DumpDebugfsCleanup(
+    IN gckOS Os
+    )
+{
+    gckDEBUGFS_DIR dir = &Os->dumpDebugfsDir;
+
+    if (dir->root)
+    {
+        gckDEBUGFS_DIR_RemoveFiles(dir, dumpDebugList, gcmCOUNTOF(dumpDebugList));
+        gckDEBUGFS_DIR_Deinit(dir);
+    }
+}
+#endif
+
 /*******************************************************************************
 **
 **  gckOS_Construct
@@ -507,22 +655,20 @@ gckOS_Construct(
     OUT gckOS * Os
     )
 {
-    gckOS os;
-    gceSTATUS status;
+    gckOS os = gcvNULL;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Context=0x%X", Context);
+    gcmkHEADER_ARG("Context=%p", Context);
 
     /* Verify the arguments. */
     gcmkVERIFY_ARGUMENT(Os != gcvNULL);
 
     /* Allocate the gckOS object. */
-    os = (gckOS) kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | gcdNOWARN);
+    os = (gckOS)kmalloc(gcmSIZEOF(struct _gckOS), GFP_KERNEL | gcdNOWARN);
 
     if (os == gcvNULL)
     {
-        /* Out of memory. */
-        gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
-        return gcvSTATUS_OUT_OF_MEMORY;
+        gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
     }
 
     /* Zero the memory. */
@@ -582,13 +728,11 @@ gckOS_Construct(
 
     gckOS_ImportAllocators(os);
 
-#ifdef CONFIG_IOMMU_SUPPORT
-    if (((gckGALDEVICE)(os->device))->args.mmu == gcvFALSE)
+#if defined(CONFIG_IOMMU_SUPPORT)
+    if (0)
     {
         /* Only use IOMMU when internal MMU is not enabled. */
-        status = gckIOMMU_Construct(os, &os->iommu);
-
-        if (gcmIS_ERROR(status))
+        if (gcmIS_ERROR(gckIOMMU_Construct(os, &os->iommu)))
         {
             gcmkTRACE_ZONE(
                 gcvLEVEL_INFO, gcvZONE_OS,
@@ -599,23 +743,33 @@ gckOS_Construct(
     }
 #endif
 
+#if gcdDUMP_IN_KERNEL
+    mutex_init(&os->dumpFilpMutex);
+
+    /* Set default dump file. */
+    set_dump_file(os, gcdDUMP_FILE_IN_KERNEL);
+
+    /* Init debugfs for kernel dump feature. */
+    _DumpDebugfsInit(os);
+#endif
+
     /* Return pointer to the gckOS object. */
     *Os = os;
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Os=0x%X", *Os);
-    return gcvSTATUS_OK;
-
 OnError:
-    if (os->workqueue != gcvNULL)
+    if (gcmIS_ERROR(status) && os)
     {
-        destroy_workqueue(os->workqueue);
-    }
+        if (os->workqueue != gcvNULL)
+        {
+            destroy_workqueue(os->workqueue);
+        }
 
-    kfree(os);
+        kfree(os);
+        os = gcvNULL;
+    }
 
     /* Return the error. */
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*Os=%p", os);
     return status;
 }
 
@@ -639,7 +793,7 @@ gckOS_Destroy(
     IN gckOS Os
     )
 {
-    gcmkHEADER_ARG("Os=0x%X", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -670,13 +824,26 @@ gckOS_Destroy(
     }
 #endif
 
-    /* Flush the debug cache. */
-    gcmkDEBUGFLUSH(~0U);
-
     /* Mark the gckOS object as unknown. */
     Os->object.type = gcvOBJ_UNKNOWN;
 
 
+#if gcdDUMP_IN_KERNEL
+    mutex_lock(&Os->dumpFilpMutex);
+
+    if (Os->dumpFilp)
+    {
+        filp_close(Os->dumpFilp, NULL);
+        Os->dumpFilp = NULL;
+        Os->dumpTarget = DUMP_IGNORE;
+    }
+
+    mutex_unlock(&Os->dumpFilpMutex);
+
+    /* Cleanup debugfs for kernel dump feature. */
+    _DumpDebugfsCleanup(Os);
+#endif
+
     /* Free the gckOS object. */
     kfree(Os);
 
@@ -708,7 +875,7 @@ gckOS_CreateKernelMapping(
     }
     else
     {
-        gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, Logical));
+        gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, Offset, Bytes, Logical));
     }
 
 OnError:
@@ -741,75 +908,6 @@ gckOS_DestroyKernelMapping(
     return gcvSTATUS_OK;
 }
 
-gceSTATUS
-gckOS_CreateKernelVirtualMapping(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    OUT gctPOINTER * Logical,
-    OUT gctSIZE_T * PageCount
-    )
-{
-    gceSTATUS status;
-    PLINUX_MDL mdl = (PLINUX_MDL)Physical;
-    gckALLOCATOR allocator = mdl->allocator;
-
-    gcmkHEADER();
-
-    *PageCount = mdl->numPages;
-
-    gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, Logical));
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckOS_DestroyKernelVirtualMapping(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    IN gctPOINTER Logical
-    )
-{
-    PLINUX_MDL mdl = (PLINUX_MDL)Physical;
-    gckALLOCATOR allocator = mdl->allocator;
-
-    gcmkHEADER();
-
-    allocator->ops->UnmapKernel(allocator, mdl, Logical);
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-gceSTATUS
-gckOS_CreateUserVirtualMapping(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    OUT gctPOINTER * Logical,
-    OUT gctSIZE_T * PageCount
-    )
-{
-    return gckOS_LockPages(Os, Physical, Bytes, gcvFALSE, Logical, PageCount);
-}
-
-gceSTATUS
-gckOS_DestroyUserVirtualMapping(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    IN gctPOINTER Logical
-    )
-{
-    return gckOS_UnlockPages(Os, Physical, Bytes, Logical);
-}
-
 /*******************************************************************************
 **
 **  gckOS_Allocate
@@ -836,9 +934,9 @@ gckOS_Allocate(
     OUT gctPOINTER * Memory
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
+    gcmkHEADER_ARG("Os=%p Bytes=0x%zx", Os, Bytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -847,13 +945,9 @@ gckOS_Allocate(
 
     gcmkONERROR(gckOS_AllocateMemory(Os, Bytes, Memory));
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*Memory=%p", gcmOPT_POINTER(Memory));
     return status;
 }
 
@@ -881,9 +975,9 @@ gckOS_Free(
     IN gctPOINTER Memory
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Memory=0x%X", Os, Memory);
+    gcmkHEADER_ARG("Os=%p Memory=%p", Os, Memory);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -891,10 +985,6 @@ gckOS_Free(
 
     gcmkONERROR(gckOS_FreeMemory(Os, Memory));
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
     gcmkFOOTER();
@@ -924,10 +1014,10 @@ gckOS_AllocateMemory(
     OUT gctPOINTER * Memory
     )
 {
-    gctPOINTER memory;
-    gceSTATUS status;
+    gctPOINTER memory = gcvNULL;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
+    gcmkHEADER_ARG("Os=%p Bytes=0x%zx", Os, Bytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_ARGUMENT(Bytes > 0);
@@ -954,13 +1044,9 @@ gckOS_AllocateMemory(
     /* Return pointer to the memory allocation. */
     *Memory = memory;
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Memory=0x%X", *Memory);
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*Memory=%p", gcmOPT_POINTER(Memory));
     return status;
 }
 
@@ -985,7 +1071,7 @@ gckOS_FreeMemory(
     IN gctPOINTER Memory
     )
 {
-    gcmkHEADER_ARG("Memory=0x%X", Memory);
+    gcmkHEADER_ARG("Os=%p Memory=%p", Os, Memory);
 
     /* Verify the arguments. */
     gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
@@ -1039,13 +1125,13 @@ gckOS_MapMemory(
     OUT gctPOINTER * Logical
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     PLINUX_MDL_MAP  mdlMap;
     PLINUX_MDL      mdl = (PLINUX_MDL) Physical;
     gckALLOCATOR allocator;
     gctINT pid = _GetProcessID();
 
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
+    gcmkHEADER_ARG("Os=%p Physical=%p Bytes=0x%zx", Os, Physical, Bytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -1060,7 +1146,6 @@ gckOS_MapMemory(
     if (mdlMap == gcvNULL)
     {
         mdlMap = _CreateMdlMap(mdl, pid);
-
         if (mdlMap == gcvNULL)
         {
             gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
@@ -1080,8 +1165,7 @@ gckOS_MapMemory(
     mutex_unlock(&mdl->mapsMutex);
 
     *Logical = mdlMap->vmaAddr;
-
-    gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
+    gcmkFOOTER_ARG("*Logical=%p", Logical);
     return gcvSTATUS_OK;
 
 OnError:
@@ -1123,7 +1207,7 @@ gckOS_UnmapMemory(
     IN gctPOINTER Logical
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
+    gcmkHEADER_ARG("Os=%p Physical=0%p Bytes=0x%zx Logical=%p",
                    Os, Physical, Bytes, Logical);
 
     /* Verify the arguments. */
@@ -1176,10 +1260,11 @@ gckOS_UnmapMemoryEx(
     IN gctUINT32 PID
     )
 {
-    PLINUX_MDL_MAP          mdlMap;
-    PLINUX_MDL              mdl = (PLINUX_MDL)Physical;
+    PLINUX_MDL_MAP mdlMap;
+    PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X PID=%d",
+    gcmkHEADER_ARG("Os=%p Physical=%p Bytes=0x%zx Logical=%p PID=%d",
                    Os, Physical, Bytes, Logical, PID);
 
     /* Verify the arguments. */
@@ -1200,9 +1285,7 @@ gckOS_UnmapMemoryEx(
         if (mdlMap == gcvNULL || mdlMap->vmaAddr == gcvNULL)
         {
             mutex_unlock(&mdl->mapsMutex);
-
-            gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT);
-            return gcvSTATUS_INVALID_ARGUMENT;
+            gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
         }
 
         BUG_ON(!allocator || !allocator->ops->UnmapUser);
@@ -1214,58 +1297,9 @@ gckOS_UnmapMemoryEx(
         mutex_unlock(&mdl->mapsMutex);
     }
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gckOS_UnmapUserLogical
-**
-**  Unmap user logical memory out of physical memory.
-**
-**  INPUT:
-**
-**      gckOS Os
-**          Pointer to an gckOS object.
-**
-**      gctPHYS_ADDR Physical
-**          Start of physical address memory.
-**
-**      gctSIZE_T Bytes
-**          Number of bytes to unmap.
-**
-**      gctPOINTER Memory
-**          Pointer to a previously mapped memory region.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckOS_UnmapUserLogical(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    IN gctPOINTER Logical
-    )
-{
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu Logical=0x%X",
-                   Os, Physical, Bytes, Logical);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Physical != 0);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-
-    gckOS_UnmapMemory(Os, Physical, Bytes, Logical);
-
-    /* Success. */
+OnError:
     gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
+    return status;
 }
 
 /*******************************************************************************
@@ -1312,14 +1346,14 @@ gckOS_AllocateNonPagedMemory(
     )
 {
     gctSIZE_T bytes;
-    gctINT numPages;
+    gctSIZE_T numPages;
     PLINUX_MDL mdl = gcvNULL;
     PLINUX_MDL_MAP mdlMap = gcvNULL;
     gctPOINTER addr;
     gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
     gckALLOCATOR allocator;
 
-    gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
+    gcmkHEADER_ARG("Os=%p InUserSpace=%d *Bytes=0x%zx",
                    Os, InUserSpace, gcmOPT_VALUE(Bytes));
 
     /* Verify the arguments. */
@@ -1344,6 +1378,10 @@ gckOS_AllocateNonPagedMemory(
 
     gcmkASSERT(Flag & gcvALLOC_FLAG_CONTIGUOUS);
 
+#if gcdENABLE_CACHEABLE_COMMAND_BUFFER
+    Flag &= ~gcvALLOC_FLAG_CACHEABLE;
+#endif
+
     Flag |= gcvALLOC_FLAG_CMA_PREEMPT;
 
     /* Walk all allocators. */
@@ -1355,36 +1393,37 @@ gckOS_AllocateNonPagedMemory(
 
 #ifndef NO_DMA_COHERENT
         /* Point to dma coherent allocator. */
-        if (strcmp(allocator->name, "dma"))
+        if (!strcmp(allocator->name, "dma") ||
+            ((Flag & allocator->capability) == Flag && numPages == 1))
         {
             /*!VIV:
              * For historical issue, we force allocate all non-paged memory from
              * dma coherent pool when it is not disabled.
              *
-             * The code below changes the scheme a little: force allocate
-             * non-paged memory whose size is larger than 1 pages, can try other
-             * allocators otherwise. This is to save memory usage of dma
-             * coherent pool.
+             * The code here changes the scheme a little: can try other
+             * allocators when page count is 1. This is to save memory usage of
+             * dma coherent pool.
              */
-            if (((Flag & allocator->capability) != Flag) ||
-                (numPages > 1))
+            status = allocator->ops->Alloc(allocator, mdl, numPages, Flag);
+
+            if (gcmIS_SUCCESS(status))
             {
-                continue;
+                mdl->allocator = allocator;
+                break;
             }
         }
 #else
-        if ((Flag & allocator->capability) != Flag)
+        if ((Flag & allocator->capability) == Flag)
         {
-            continue;
-        }
-#endif
-        status = allocator->ops->Alloc(allocator, mdl, numPages, Flag);
+            status = allocator->ops->Alloc(allocator, mdl, numPages, Flag);
 
-        if (gcmIS_SUCCESS(status))
-        {
-            mdl->allocator = allocator;
-            break;
+            if (gcmIS_SUCCESS(status))
+            {
+                mdl->allocator = allocator;
+                break;
+            }
         }
+#endif
     }
 
     /* Check status. */
@@ -1397,7 +1436,7 @@ gckOS_AllocateNonPagedMemory(
 
     mdl->contiguous = gcvTRUE;
 
-    gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, &addr));
+    gcmkONERROR(allocator->ops->MapKernel(allocator, mdl, 0, bytes, &addr));
 
     if (!strcmp(allocator->name, "gfp"))
     {
@@ -1439,19 +1478,26 @@ gckOS_AllocateNonPagedMemory(
     *Physical = (gctPHYS_ADDR) mdl;
 
     /* Success. */
-    gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
-                   *Bytes, *Physical, *Logical);
-    return gcvSTATUS_OK;
+    status = gcvSTATUS_OK;
 
 OnError:
-    if (mdl != gcvNULL)
+    if (gcmIS_ERROR(status))
     {
-        /* Free LINUX_MDL. */
-        gcmkVERIFY_OK(_DestroyMdl(mdl));
-    }
+        if (mdlMap)
+        {
+            /* Free LINUX_MDL_MAP. */
+            gcmkVERIFY_OK(_DestroyMdlMap(mdl, mdlMap));
+        }
 
+        if (mdl)
+        {
+            /* Free LINUX_MDL. */
+            gcmkVERIFY_OK(_DestroyMdl(mdl));
+        }
+    }
     /* Return the status. */
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*Bytes=0x%zx *Physical=%p *Logical=%p",
+                   gcmOPT_VALUE(Bytes), gcmOPT_POINTER(Physical), gcmOPT_POINTER(Logical));
     return status;
 }
 
@@ -1467,29 +1513,29 @@ OnError:
 **      gckOS Os
 **          Pointer to an gckOS object.
 **
-**      gctSIZE_T Bytes
-**          Number of bytes allocated.
-**
 **      gctPHYS_ADDR Physical
 **          Physical address of the allocated memory.
 **
 **      gctPOINTER Logical
 **          Logical address of the allocated memory.
 **
+**      gctSIZE_T Bytes
+**          Number of bytes allocated.
+**
 **  OUTPUT:
 **
 **      Nothing.
 */
 gceSTATUS gckOS_FreeNonPagedMemory(
     IN gckOS Os,
-    IN gctSIZE_T Bytes,
     IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical
+    IN gctPOINTER Logical,
+    IN gctSIZE_T Bytes
     )
 {
     PLINUX_MDL mdl = (PLINUX_MDL)Physical;
 
-    gcmkHEADER_ARG("Os=0x%X Bytes=%lu Physical=0x%X Logical=0x%X",
+    gcmkHEADER_ARG("Os=%p Bytes=0x%zx Physical=%p Logical=%p",
                    Os, Bytes, Physical, Logical);
 
     /* Verify the arguments. */
@@ -1527,11 +1573,11 @@ _FindAllocator(
 gceSTATUS
 gckOS_RequestReservedMemory(
     gckOS Os,
-    unsigned long Start,
-    unsigned long Size,
+    gctPHYS_ADDR_T Start,
+    gctSIZE_T Size,
     const char * Name,
     gctBOOL Requested,
-    void ** MemoryHandle
+    gctPOINTER * MemoryHandle
     )
 {
     PLINUX_MDL mdl = gcvNULL;
@@ -1601,7 +1647,7 @@ OnError:
 void
 gckOS_ReleaseReservedMemory(
     gckOS Os,
-    void * MemoryHandle
+    gctPOINTER MemoryHandle
     )
 {
     gckALLOCATOR allocator;
@@ -1723,43 +1769,13 @@ gckOS_ReadRegisterEx(
     return gcvSTATUS_OK;
 }
 
-/*******************************************************************************
-**
-**  gckOS_WriteRegister
-**
-**  Write data to a register.
-**
-**  INPUT:
-**
-**      gckOS Os
-**          Pointer to an gckOS object.
-**
-**      gctUINT32 Address
-**          Address of register.
-**
-**      gctUINT32 Data
-**          Data for register.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckOS_WriteRegister(
-    IN gckOS Os,
-    IN gctUINT32 Address,
-    IN gctUINT32 Data
-    )
-{
-    return gckOS_WriteRegisterEx(Os, gcvCORE_MAJOR, Address, Data);
-}
-
-gceSTATUS
-gckOS_WriteRegisterEx(
+static gceSTATUS
+_WriteRegisterEx(
     IN gckOS Os,
     IN gceCORE Core,
     IN gctUINT32 Address,
-    IN gctUINT32 Data
+    IN gctUINT32 Data,
+    IN gctBOOL Dump
     )
 {
     if (in_irq())
@@ -1785,6 +1801,11 @@ gckOS_WriteRegisterEx(
     {
         unsigned long flags;
 
+        if (Dump)
+        {
+            gcmkDUMP(Os, "@[register.write %u 0x%05X 0x%08X]", Core, Address, Data);
+        }
+
         spin_lock_irqsave(&Os->registerAccessLock, flags);
 
         if (unlikely(Os->clockStates[Core] == gcvFALSE))
@@ -1812,6 +1833,59 @@ gckOS_WriteRegisterEx(
     return gcvSTATUS_OK;
 }
 
+/*******************************************************************************
+**
+**  gckOS_WriteRegister
+**
+**  Write data to a register.
+**
+**  INPUT:
+**
+**      gckOS Os
+**          Pointer to an gckOS object.
+**
+**      gctUINT32 Address
+**          Address of register.
+**
+**      gctUINT32 Data
+**          Data for register.
+**
+**  OUTPUT:
+**
+**      Nothing.
+*/
+gceSTATUS
+gckOS_WriteRegister(
+    IN gckOS Os,
+    IN gctUINT32 Address,
+    IN gctUINT32 Data
+    )
+{
+    return _WriteRegisterEx(Os, gcvCORE_MAJOR, Address, Data, gcvTRUE);
+}
+
+gceSTATUS
+gckOS_WriteRegisterEx(
+    IN gckOS Os,
+    IN gceCORE Core,
+    IN gctUINT32 Address,
+    IN gctUINT32 Data
+    )
+{
+    return _WriteRegisterEx(Os, Core, Address, Data, gcvTRUE);
+}
+
+gceSTATUS
+gckOS_WriteRegisterEx_NoDump(
+    IN gckOS Os,
+    IN gceCORE Core,
+    IN gctUINT32 Address,
+    IN gctUINT32 Data
+    )
+{
+    return _WriteRegisterEx(Os, Core, Address, Data, gcvFALSE);
+}
+
 /*******************************************************************************
 **
 **  gckOS_GetPageSize
@@ -1833,7 +1907,7 @@ gceSTATUS gckOS_GetPageSize(
     OUT gctSIZE_T * PageSize
     )
 {
-    gcmkHEADER_ARG("Os=0x%X", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -1843,13 +1917,13 @@ gceSTATUS gckOS_GetPageSize(
     *PageSize = (gctSIZE_T) PAGE_SIZE;
 
     /* Success. */
-    gcmkFOOTER_ARG("*PageSize=%d", *PageSize);
+    gcmkFOOTER_ARG("*PageSize=0x%zx", *PageSize);
     return gcvSTATUS_OK;
 }
 
 /*******************************************************************************
 **
-**  gckOS_GetPhysicalAddressProcess
+**  _GetPhysicalAddressProcess
 **
 **  Get the physical system address of a corresponding virtual address for a
 **  given process.
@@ -1881,7 +1955,7 @@ _GetPhysicalAddressProcess(
     PLINUX_MDL mdl;
     gceSTATUS status = gcvSTATUS_INVALID_ADDRESS;
 
-    gcmkHEADER_ARG("Os=0x%X Logical=0x%X ProcessID=%d", Os, Logical, ProcessID);
+    gcmkHEADER_ARG("Os=%p Logical=%p ProcessID=%d", Os, Logical, ProcessID);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -1922,14 +1996,11 @@ _GetPhysicalAddressProcess(
     mutex_unlock(&Os->mdlMutex);
 
     gcmkONERROR(status);
-
     /* Success. */
-    gcmkFOOTER_ARG("*Address=%p", *Address);
-    return gcvSTATUS_OK;
 
 OnError:
     /* Return the status. */
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*Address=%p", *Address);
     return status;
 }
 
@@ -1964,7 +2035,7 @@ gckOS_GetPhysicalAddress(
     gceSTATUS status;
     gctUINT32 processID;
 
-    gcmkHEADER_ARG("Os=0x%X Logical=0x%X", Os, Logical);
+    gcmkHEADER_ARG("Os=%p Logical=%p", Os, Logical);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -1984,7 +2055,7 @@ gckOS_GetPhysicalAddress(
     }
 
     /* Success. */
-    gcmkFOOTER_ARG("*Address=%p", *Address);
+    gcmkFOOTER_ARG("*Address=0x%llx", *Address);
     return gcvSTATUS_OK;
 
 OnError:
@@ -1993,6 +2064,21 @@ OnError:
     return status;
 }
 
+gceSTATUS
+gckOS_GetPhysicalFromHandle(
+    IN gckOS Os,
+    IN gctPHYS_ADDR Physical,
+    IN gctUINT32 Offset,
+    OUT gctPHYS_ADDR_T * PhysicalAddress
+    )
+{
+    PLINUX_MDL mdl = (PLINUX_MDL)Physical;
+    gckALLOCATOR allocator = mdl->allocator;
+
+    return allocator->ops->Physical(allocator, mdl, Offset, PhysicalAddress);
+}
+
+
 /*******************************************************************************
 **
 **  gckOS_UserLogicalToPhysical
@@ -2021,89 +2107,6 @@ gceSTATUS gckOS_UserLogicalToPhysical(
     return gckOS_GetPhysicalAddress(Os, Logical, Address);
 }
 
-#if gcdSECURE_USER
-static gceSTATUS
-gckOS_AddMapping(
-    IN gckOS Os,
-    IN gctUINT32 Physical,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gceSTATUS status;
-    gcsUSER_MAPPING_PTR map;
-
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
-                   Os, Physical, Logical, Bytes);
-
-    gcmkONERROR(gckOS_Allocate(Os,
-                               gcmSIZEOF(gcsUSER_MAPPING),
-                               (gctPOINTER *) &map));
-
-    map->next     = Os->userMap;
-    map->physical = Physical - Os->device->baseAddress;
-    map->logical  = Logical;
-    map->bytes    = Bytes;
-    map->start    = (gctINT8_PTR) Logical;
-    map->end      = map->start + Bytes;
-
-    Os->userMap = map;
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-static gceSTATUS
-gckOS_RemoveMapping(
-    IN gckOS Os,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
-    )
-{
-    gceSTATUS status;
-    gcsUSER_MAPPING_PTR map, prev;
-
-    gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
-
-    for (map = Os->userMap, prev = gcvNULL; map != gcvNULL; map = map->next)
-    {
-        if ((map->logical == Logical) && (map->bytes == Bytes))
-        {
-            break;
-        }
-
-        prev = map;
-    }
-
-    if (map == gcvNULL)
-    {
-        gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
-    }
-
-    if (prev == gcvNULL)
-    {
-        Os->userMap = map->next;
-    }
-    else
-    {
-        prev->next = map->next;
-    }
-
-    gcmkONERROR(gcmkOS_SAFE_FREE(Os, map));
-
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-#endif
-
 gceSTATUS
 _ConvertLogical2Physical(
     IN gckOS Os,
@@ -2160,7 +2163,7 @@ _ConvertLogical2Physical(
 **      gckOS Os
 **          Pointer to an gckOS object.
 **
-**      gctUINT32 Physical
+**      gctPHYS_ADDR_T Physical
 **          Physical address of the memory to map.
 **
 **      gctSIZE_T Bytes
@@ -2175,7 +2178,7 @@ _ConvertLogical2Physical(
 gceSTATUS
 gckOS_MapPhysical(
     IN gckOS Os,
-    IN gctUINT32 Physical,
+    IN gctPHYS_ADDR_T Physical,
     IN gctSIZE_T Bytes,
     OUT gctPOINTER * Logical
     )
@@ -2183,9 +2186,10 @@ gckOS_MapPhysical(
     gctPOINTER logical;
     PLINUX_MDL mdl;
     gctBOOL found = gcvFALSE;
-    gctUINT32 physical = Physical;
+    dma_addr_t physical = Physical;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
+    gcmkHEADER_ARG("Os=%p Physical=0x%llx Bytes=0x%zx", Os, Physical, Bytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -2222,18 +2226,16 @@ gckOS_MapPhysical(
             gctUINT32 offset = physical & ~PAGE_MASK;
             struct page ** pages;
             struct page * page;
-            gctUINT numPages;
-            gctINT i;
+            gctSIZE_T numPages;
+            gctSIZE_T i;
             pgprot_t pgprot;
 
             numPages = GetPageCount(PAGE_ALIGN(offset + Bytes), 0);
 
             pages = kmalloc(sizeof(struct page *) * numPages, GFP_KERNEL | gcdNOWARN);
-
             if (!pages)
             {
-                gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_MEMORY);
-                return gcvSTATUS_OUT_OF_MEMORY;
+                gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
             }
 
             page = pfn_to_page(pfn);
@@ -2262,8 +2264,7 @@ gckOS_MapPhysical(
                     );
 
                 /* Out of resources. */
-                gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
-                return gcvSTATUS_OUT_OF_RESOURCES;
+                gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
             }
 
             logical += offset;
@@ -2283,8 +2284,7 @@ gckOS_MapPhysical(
                     );
 
                 /* Out of resources. */
-                gcmkFOOTER_ARG("status=%d", gcvSTATUS_OUT_OF_RESOURCES);
-                return gcvSTATUS_OUT_OF_RESOURCES;
+                gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
             }
         }
 
@@ -2292,9 +2292,10 @@ gckOS_MapPhysical(
         *Logical = logical;
     }
 
+OnError:
     /* Success. */
-    gcmkFOOTER_ARG("*Logical=0x%X", *Logical);
-    return gcvSTATUS_OK;
+    gcmkFOOTER_ARG("*Logical=%p", *Logical);
+    return status;
 }
 
 /*******************************************************************************
@@ -2328,7 +2329,7 @@ gckOS_UnmapPhysical(
     PLINUX_MDL  mdl;
     gctBOOL found = gcvFALSE;
 
-    gcmkHEADER_ARG("Os=0x%X Logical=0x%X Bytes=%lu", Os, Logical, Bytes);
+    gcmkHEADER_ARG("Os=%p Logical=%p Bytes=0x%zx", Os, Logical, Bytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -2387,9 +2388,9 @@ gckOS_DeleteMutex(
     IN gctPOINTER Mutex
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Mutex=0x%X", Os, Mutex);
+    gcmkHEADER_ARG("Os=%p Mutex=%p", Os, Mutex);
 
     /* Validate the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -2401,9 +2402,6 @@ gckOS_DeleteMutex(
     /* Free the mutex structure. */
     gcmkONERROR(gckOS_Free(Os, Mutex));
 
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return status. */
     gcmkFOOTER();
@@ -2440,7 +2438,8 @@ gckOS_AcquireMutex(
     IN gctUINT32 Timeout
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x Timeout=%u", Os, Mutex, Timeout);
+    gceSTATUS status = gcvSTATUS_TIMEOUT;
+    gcmkHEADER_ARG("Os=%p Mutex=%p Timeout=%u", Os, Mutex, Timeout);
 
     /* Validate the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -2452,32 +2451,33 @@ gckOS_AcquireMutex(
         mutex_lock(Mutex);
 
         /* Success. */
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
+        status = gcvSTATUS_OK;
     }
-
-    for (;;)
+    else
     {
-        /* Try to acquire the mutex. */
-        if (mutex_trylock(Mutex))
+        for (;;)
         {
-            /* Success. */
-            gcmkFOOTER_NO();
-            return gcvSTATUS_OK;
-        }
+            /* Try to acquire the mutex. */
+            if (mutex_trylock(Mutex))
+            {
+                /* Success. */
+                status = gcvSTATUS_OK;
+                break;
+            }
 
-        if (Timeout-- == 0)
-        {
-            break;
-        }
+            if (Timeout-- == 0)
+            {
+                break;
+            }
 
-        /* Wait for 1 millisecond. */
-        gcmkVERIFY_OK(gckOS_Delay(Os, 1));
+            /* Wait for 1 millisecond. */
+            gcmkVERIFY_OK(gckOS_Delay(Os, 1));
+        }
     }
 
     /* Timeout. */
-    gcmkFOOTER_ARG("status=%d", gcvSTATUS_TIMEOUT);
-    return gcvSTATUS_TIMEOUT;
+    gcmkFOOTER();
+    return status;
 }
 
 /*******************************************************************************
@@ -2504,7 +2504,7 @@ gckOS_ReleaseMutex(
     IN gctPOINTER Mutex
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Mutex=0x%0x", Os, Mutex);
+    gcmkHEADER_ARG("Os=%p Mutex=%p", Os, Mutex);
 
     /* Validate the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -2616,12 +2616,14 @@ gckOS_AtomSetMask(
     )
 {
     gctUINT32 oval, nval;
+
     do
     {
         oval = atomic_read((atomic_t *) Atom);
         nval = oval | Mask;
     }
     while (atomic_cmpxchg((atomic_t *) Atom, oval, nval) != oval);
+
     return gcvSTATUS_OK;
 }
 
@@ -2682,9 +2684,9 @@ gckOS_AtomConstruct(
     OUT gctPOINTER * Atom
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -2696,13 +2698,9 @@ gckOS_AtomConstruct(
     /* Initialize the atom. */
     atomic_set((atomic_t *) *Atom, 0);
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Atom=0x%X", *Atom);
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*Atom=%p", *Atom);
     return status;
 }
 
@@ -2730,9 +2728,9 @@ gckOS_AtomDestroy(
     OUT gctPOINTER Atom
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Atom=0x%0x", Os, Atom);
+    gcmkHEADER_ARG("Os=%p Atom=%p", Os, Atom);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -2741,10 +2739,6 @@ gckOS_AtomDestroy(
     /* Free the atom. */
     gcmkONERROR(gcmkOS_SAFE_FREE(Os, Atom));
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
     gcmkFOOTER();
@@ -2841,7 +2835,6 @@ gckOS_AtomIncrement(
     OUT gctINT32_PTR Value
     )
 {
-    /* Increment the atom. */
     *Value = atomic_inc_return((atomic_t *) Atom) - 1;
     return gcvSTATUS_OK;
 }
@@ -2901,7 +2894,7 @@ gckOS_Delay(
     IN gctUINT32 Delay
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Delay=%u", Os, Delay);
+    gcmkHEADER_ARG("Os=%p Delay=%u", Os, Delay);
 
     if (Delay > 0)
     {
@@ -2999,12 +2992,21 @@ gckOS_GetTime(
     OUT gctUINT64_PTR Time
     )
 {
-    struct timeval tv;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)
+    struct timespec64 tv;
     gcmkHEADER();
 
     /* Return the time of day in microseconds. */
+    ktime_get_real_ts64(&tv);
+    *Time = (tv.tv_sec * 1000000ULL) + (tv.tv_nsec * 1000);
+#else
+    struct timeval tv;
+    gcmkHEADER();
+
+     /* Return the time of day in microseconds. */
     do_gettimeofday(&tv);
     *Time = (tv.tv_sec * 1000000ULL) + tv.tv_usec;
+#endif
 
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
@@ -3051,93 +3053,47 @@ gckOS_MemoryBarrier(
 **      gckOS Os
 **          Pointer to an gckOS object.
 **
-**      gctSIZE_T Bytes
+**      gctUINT32 Flag
+**          Allocation attribute.
+**
+**      gctSIZE_T * Bytes
 **          Number of bytes to allocate.
 **
 **  OUTPUT:
 **
+**      gctSIZE_T * Bytes
+**          Return number of bytes actually allocated.
+**
+**      gctUINT32 * Gid
+**          Save the global ID for the piece of allocated memory.
+**
 **      gctPHYS_ADDR * Physical
 **          Pointer to a variable that receives the physical address of the
 **          memory allocation.
 */
 gceSTATUS
 gckOS_AllocatePagedMemory(
-    IN gckOS Os,
-    IN gctSIZE_T Bytes,
-    OUT gctPHYS_ADDR * Physical
-    )
-{
-    gceSTATUS status;
-
-    gcmkHEADER_ARG("Os=0x%X Bytes=%lu", Os, Bytes);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-    gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
-
-    /* Allocate the memory. */
-    gcmkONERROR(gckOS_AllocatePagedMemoryEx(Os, gcvALLOC_FLAG_NONE, Bytes, gcvNULL, Physical));
-
-    /* Success. */
-    gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-/*******************************************************************************
-**
-**  gckOS_AllocatePagedMemoryEx
-**
-**  Allocate memory from the paged pool.
-**
-**  INPUT:
-**
-**      gckOS Os
-**          Pointer to an gckOS object.
-**
-**      gctUINT32 Flag
-**          Allocation attribute.
-**
-**      gctSIZE_T Bytes
-**          Number of bytes to allocate.
-**
-**  OUTPUT:
-**
-**      gctUINT32 * Gid
-**          Save the global ID for the piece of allocated memory.
-**
-**      gctPHYS_ADDR * Physical
-**          Pointer to a variable that receives the physical address of the
-**          memory allocation.
-*/
-gceSTATUS
-gckOS_AllocatePagedMemoryEx(
     IN gckOS Os,
     IN gctUINT32 Flag,
-    IN gctSIZE_T Bytes,
+    IN OUT gctSIZE_T * Bytes,
     OUT gctUINT32 * Gid,
     OUT gctPHYS_ADDR * Physical
     )
 {
-    gctINT numPages;
+    gctSIZE_T numPages;
     PLINUX_MDL mdl = gcvNULL;
     gctSIZE_T bytes;
     gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
     gckALLOCATOR allocator;
 
-    gcmkHEADER_ARG("Os=0x%X Flag=%x Bytes=%lu", Os, Flag, Bytes);
+    gcmkHEADER_ARG("Os=%p Flag=%x *Bytes=0x%zx", Os, Flag, *Bytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
+    gcmkVERIFY_ARGUMENT(*Bytes > 0);
     gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
 
-    bytes = gcmALIGN(Bytes, PAGE_SIZE);
+    bytes = gcmALIGN(*Bytes, PAGE_SIZE);
 
     numPages = GetPageCount(bytes, 0);
 
@@ -3187,11 +3143,6 @@ gckOS_AllocatePagedMemoryEx(
     mdl->contiguous = Flag & gcvALLOC_FLAG_CONTIGUOUS;
     mdl->cacheable  = Flag & gcvALLOC_FLAG_CACHEABLE;
 
-    if (Gid != gcvNULL)
-    {
-        *Gid = mdl->gid;
-    }
-
     /*
      * Add this to a global list.
      * Will be used by get physical address
@@ -3201,22 +3152,29 @@ gckOS_AllocatePagedMemoryEx(
     list_add_tail(&mdl->link, &Os->mdlHead);
     mutex_unlock(&Os->mdlMutex);
 
+    /* Return allocated bytes. */
+    *Bytes = bytes;
+
+    if (Gid != gcvNULL)
+    {
+        *Gid = mdl->gid;
+    }
+
     /* Return physical address. */
     *Physical = (gctPHYS_ADDR) mdl;
 
     /* Success. */
-    gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
-    return gcvSTATUS_OK;
+    status = gcvSTATUS_OK;
 
 OnError:
-    if (mdl != gcvNULL)
+    if (gcmIS_ERROR(status) && mdl)
     {
         /* Free the memory. */
         _DestroyMdl(mdl);
     }
 
     /* Return the status. */
-    gcmkFOOTER_ARG("Os=0x%X Flag=%x Bytes=%lu", Os, Flag, Bytes);
+    gcmkFOOTER_ARG("*Physical=%p", *Physical);
     return status;
 }
 
@@ -3250,7 +3208,7 @@ gckOS_FreePagedMemory(
 {
     PLINUX_MDL mdl = (PLINUX_MDL)Physical;
 
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Bytes);
+    gcmkHEADER_ARG("Os=%p Physical=%p Bytes=0x%zx", Os, Physical, Bytes);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -3290,10 +3248,6 @@ gckOS_FreePagedMemory(
 **      gctPOINTER * Logical
 **          Pointer to a variable that receives the address of the mapped
 **          memory.
-**
-**      gctSIZE_T * PageCount
-**          Pointer to a variable that receives the number of pages required for
-**          the page table according to the GPU page size.
 */
 gceSTATUS
 gckOS_LockPages(
@@ -3301,24 +3255,22 @@ gckOS_LockPages(
     IN gctPHYS_ADDR Physical,
     IN gctSIZE_T Bytes,
     IN gctBOOL Cacheable,
-    OUT gctPOINTER * Logical,
-    OUT gctSIZE_T * PageCount
+    OUT gctPOINTER * Logical
     )
 {
-    gceSTATUS       status;
+    gceSTATUS       status = gcvSTATUS_OK;
     PLINUX_MDL      mdl;
     PLINUX_MDL_MAP  mdlMap;
     gckALLOCATOR    allocator;
 
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%lu", Os, Physical, Logical);
+    gcmkHEADER_ARG("Os=%p Physical=%p Bytes=0x%zx", Os, Physical, Logical);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
     gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(PageCount != gcvNULL);
 
-    mdl = (PLINUX_MDL) Physical;
+    mdl = (PLINUX_MDL)Physical;
     allocator = mdl->allocator;
 
     mutex_lock(&mdl->mapsMutex);
@@ -3331,24 +3283,13 @@ gckOS_LockPages(
 
         if (mdlMap == gcvNULL)
         {
-            mutex_unlock(&mdl->mapsMutex);
-
-            gcmkFOOTER_ARG("*status=%d", gcvSTATUS_OUT_OF_MEMORY);
-            return gcvSTATUS_OUT_OF_MEMORY;
+            gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
         }
     }
 
     if (mdlMap->vmaAddr == gcvNULL)
     {
-        status = allocator->ops->MapUser(allocator, mdl, mdlMap, Cacheable);
-
-        if (gcmIS_ERROR(status))
-        {
-            mutex_unlock(&mdl->mapsMutex);
-
-            gcmkFOOTER_ARG("*status=%d", status);
-            return status;
-        }
+        gcmkONERROR(allocator->ops->MapUser(allocator, mdl, mdlMap, Cacheable));
     }
 
     mdlMap->count++;
@@ -3356,54 +3297,14 @@ gckOS_LockPages(
     /* Convert pointer to MDL. */
     *Logical = mdlMap->vmaAddr;
 
-    /* Return the page number according to the GPU page size. */
-    gcmkASSERT((PAGE_SIZE % 4096) == 0);
-    gcmkASSERT((PAGE_SIZE / 4096) >= 1);
-
-    *PageCount = mdl->numPages * (PAGE_SIZE / 4096);
-
+OnError:
     mutex_unlock(&mdl->mapsMutex);
-
     /* Success. */
-    gcmkFOOTER_ARG("*Logical=0x%X *PageCount=%lu", *Logical, *PageCount);
-    return gcvSTATUS_OK;
-}
-
-/*******************************************************************************
-**
-**  gckOS_MapPages
-**
-**  Map paged memory into a page table.
-**
-**  INPUT:
-**
-**      gckOS Os
-**          Pointer to an gckOS object.
-**
-**      gctPHYS_ADDR Physical
-**          Physical address of the allocation.
-**
-**      gctSIZE_T PageCount
-**          Number of pages required for the physical address.
-**
-**      gctPOINTER PageTable
-**          Pointer to the page table to fill in.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckOS_MapPages(
-    IN gckOS Os,
-    IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T PageCount,
-    IN gctPOINTER PageTable
-    )
-{
-    return gcvSTATUS_NOT_SUPPORTED;
+    gcmkFOOTER_ARG("*Logical=%p", *Logical);
+    return status;
 }
 
+/* PageCount is GPU page count. */
 gceSTATUS
 gckOS_MapPagesEx(
     IN gckOS Os,
@@ -3413,7 +3314,7 @@ gckOS_MapPagesEx(
     IN gctUINT32 Address,
     IN gctPOINTER PageTable,
     IN gctBOOL Writable,
-    IN gceSURF_TYPE Type
+    IN gceVIDMEM_TYPE Type
     )
 {
     gceSTATUS status = gcvSTATUS_OK;
@@ -3421,13 +3322,7 @@ gckOS_MapPagesEx(
     gctUINT32*  table;
     gctUINT32   offset = 0;
 
-#if gcdPROCESS_ADDRESS_SPACE
-    gckKERNEL kernel = Os->device->kernels[Core];
-    gckMMU      mmu;
-#endif
-
     gctUINT32 bytes = PageCount * 4;
-
     gckALLOCATOR allocator;
 
     gctUINT32 policyID = 0;
@@ -3435,8 +3330,8 @@ gckOS_MapPagesEx(
 
     gcsPLATFORM * platform = Os->device->platform;
 
-    gcmkHEADER_ARG("Os=0x%X Core=%d Physical=0x%X PageCount=%u PageTable=0x%X",
-                   Os, Core, Physical, PageCount, PageTable);
+    gcmkHEADER_ARG("Os=%p Core=%d Physical=%p PageCount=0x%zx Address=0x%x PageTable=%p",
+                   Os, Core, Physical, PageCount, Address, PageTable);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -3459,10 +3354,6 @@ gckOS_MapPagesEx(
         (gctUINT32)(gctUINTPTR_T)PageCount
         );
 
-#if gcdPROCESS_ADDRESS_SPACE
-    gcmkONERROR(gckKERNEL_GetProcessMMU(kernel, &mmu));
-#endif
-
     table = (gctUINT32 *)PageTable;
 
     if (platform && platform->ops->getPolicyID)
@@ -3537,21 +3428,12 @@ gckOS_MapPagesEx(
             {
                 for (i = 0; i < (PAGE_SIZE / 4096); i++)
                 {
-#if gcdPROCESS_ADDRESS_SPACE
-                    gctUINT32_PTR pageTableEntry;
-                    gckMMU_GetPageEntry(mmu, Address + offset + (i * 4096), &pageTableEntry);
-                    gcmkONERROR(
-                        gckMMU_SetPage(mmu,
-                            phys + (i * 4096),
-                            Writable,
-                            pageTableEntry));
-#else
                     gcmkONERROR(
                         gckMMU_SetPage(Os->device->kernels[Core]->mmu,
                             phys + (i * 4096),
+                            gcvPAGE_TYPE_4K,
                             Writable,
                             table++));
-#endif
                 }
             }
         }
@@ -3580,30 +3462,28 @@ gckOS_MapPagesEx(
 #  endif
     {
         gckMMU mmu = Os->device->kernels[Core]->mmu;
-        gcsADDRESS_AREA * area = &mmu->area[0];
+        gcsADDRESS_AREA * area = &mmu->dynamicArea4K;
 
-        offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)area->pageTableLogical;
+        offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)area->stlbLogical;
 
         /* must be in dynamic area. */
-        gcmkASSERT(offset < area->pageTableSize);
+        gcmkASSERT(offset < area->stlbSize);
 
-        gcmkVERIFY_OK(gckOS_CacheClean(
-            Os,
-            0,
-            area->pageTablePhysical,
+        gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
+            Os->device->kernels[Core],
+            area->stlbVideoMem,
             offset,
             PageTable,
             bytes
             ));
 
-        if (mmu->mtlbPhysical)
+        if (mmu->mtlbVideoMem)
         {
             /* Flush MTLB table. */
-            gcmkVERIFY_OK(gckOS_CacheClean(
-                Os,
-                0,
-                mmu->mtlbPhysical,
-                0,
+            gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
+                Os->device->kernels[Core],
+                mmu->mtlbVideoMem,
+                offset,
                 mmu->mtlbLogical,
                 mmu->mtlbSize
                 ));
@@ -3611,12 +3491,12 @@ gckOS_MapPagesEx(
     }
 
 OnError:
-
     /* Return the status. */
     gcmkFOOTER();
     return status;
 }
 
+/* PageCount is GPU page count. */
 gceSTATUS
 gckOS_UnmapPages(
     IN gckOS Os,
@@ -3628,148 +3508,135 @@ gckOS_UnmapPages(
     if (Os->iommu)
     {
         gcmkVERIFY_OK(gckIOMMU_Unmap(
-            Os->iommu, Address, PageCount * PAGE_SIZE));
+            Os->iommu, Address, PageCount * 4096));
     }
 #endif
 
     return gcvSTATUS_OK;
 }
 
-/*******************************************************************************
-**
-**  gckOS_UnlockPages
-**
-**  Unlock memory allocated from the paged pool.
-**
-**  INPUT:
-**
-**      gckOS Os
-**          Pointer to an gckOS object.
-**
-**      gctPHYS_ADDR Physical
-**          Physical address of the allocation.
-**
-**      gctSIZE_T Bytes
-**          Number of bytes of the allocation.
-**
-**      gctPOINTER Logical
-**          Address of the mapped memory.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
+/* Map 1M size GPU page */
 gceSTATUS
-gckOS_UnlockPages(
+gckOS_Map1MPages(
     IN gckOS Os,
+    IN gceCORE Core,
     IN gctPHYS_ADDR Physical,
-    IN gctSIZE_T Bytes,
-    IN gctPOINTER Logical
+    IN gctSIZE_T PageCount,
+    IN gctUINT32 Address,
+    IN gctPOINTER PageTable,
+    IN gctBOOL Writable,
+    IN gceVIDMEM_TYPE Type
     )
 {
-    PLINUX_MDL_MAP mdlMap;
-    PLINUX_MDL  mdl = (PLINUX_MDL)Physical;
-    gckALLOCATOR allocator = mdl->allocator;
-    gctINT pid = _GetProcessID();
+    gceSTATUS status = gcvSTATUS_OK;
+    PLINUX_MDL mdl;
+    gctUINT32* table;
+    gctUINT32  offset = 0;
 
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Bytes=%u Logical=0x%X",
-                   Os, Physical, Bytes, Logical);
+    gctSIZE_T bytes = PageCount * 4;
+    gckALLOCATOR allocator;
+
+    gctUINT32 policyID = 0;
+    gctUINT32 axiConfig = 0;
+
+    gcsPLATFORM * platform = Os->device->platform;
+
+    gcmkHEADER_ARG("Os=%p Core=%d Physical=%p PageCount=0x%zx Address=0x%x PageTable=%p",
+                   Os, Core, Physical, PageCount, Address, PageTable);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+    gcmkVERIFY_ARGUMENT(PageCount > 0);
+    gcmkVERIFY_ARGUMENT(PageTable != gcvNULL);
 
-    mutex_lock(&mdl->mapsMutex);
+    /* Convert pointer to MDL. */
+    mdl = (PLINUX_MDL)Physical;
 
-    list_for_each_entry(mdlMap, &mdl->mapsHead, link)
+    allocator = mdl->allocator;
+
+    gcmkASSERT(allocator != gcvNULL);
+
+    gcmkTRACE_ZONE(
+        gcvLEVEL_INFO, gcvZONE_OS,
+        "%s(%d): Physical->0x%X PageCount->0x%X",
+        __FUNCTION__, __LINE__,
+        (gctUINT32)(gctUINTPTR_T)Physical,
+        (gctUINT32)(gctUINTPTR_T)PageCount
+        );
+
+    table = (gctUINT32 *)PageTable;
+
+    if (platform && platform->ops->getPolicyID)
     {
-        if ((mdlMap->vmaAddr != gcvNULL) && (mdlMap->pid == pid))
+        platform->ops->getPolicyID(platform, Type, &policyID, &axiConfig);
+
+        gcmkBUG_ON(policyID > 0x1F);
+
+        /* ID[3:0] is used in STLB. */
+        policyID &= 0xF;
+    }
+
+    while (PageCount-- > 0)
+    {
+        gctPHYS_ADDR_T phys = ~0U;
+
+        allocator->ops->Physical(allocator, mdl, offset, &phys);
+
+        gcmkVERIFY_OK(gckOS_CPUPhysicalToGPUPhysical(Os, phys, &phys));
+
+        if (policyID)
         {
-            if (--mdlMap->count == 0)
-            {
-                allocator->ops->UnmapUser(
-                    allocator,
-                    mdl,
-                    mdlMap,
-                    mdl->bytes);
+            /* AxUSER must not used for address currently. */
+            gcmkBUG_ON((phys >> 32) & 0xF);
 
-                mdlMap->vmaAddr = gcvNULL;
-            }
+            /* Merge policyID to AxUSER[7:4].*/
+            phys |= ((gctPHYS_ADDR_T)policyID << 36);
         }
-    }
 
-    mutex_unlock(&mdl->mapsMutex);
+        /* Get the start physical of 1M page. */
+        phys &= ~((1 << 20) - 1);
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-}
+        gcmkONERROR(
+            gckMMU_SetPage(Os->device->kernels[Core]->mmu,
+            phys,
+            gcvPAGE_TYPE_1M,
+            Writable,
+            table++));
 
+        offset += gcd1M_PAGE_SIZE;
+    }
 
-/*******************************************************************************
-**
-**  gckOS_AllocateContiguous
-**
-**  Allocate memory from the contiguous pool.
-**
-**  INPUT:
-**
-**      gckOS Os
-**          Pointer to an gckOS object.
-**
-**      gctBOOL InUserSpace
-**          gcvTRUE if the pages need to be mapped into user space.
-**
-**      gctSIZE_T * Bytes
-**          Pointer to the number of bytes to allocate.
-**
-**  OUTPUT:
-**
-**      gctSIZE_T * Bytes
-**          Pointer to a variable that receives the number of bytes allocated.
-**
-**      gctPHYS_ADDR * Physical
-**          Pointer to a variable that receives the physical address of the
-**          memory allocation.
-**
-**      gctPOINTER * Logical
-**          Pointer to a variable that receives the logical address of the
-**          memory allocation.
-*/
-gceSTATUS
-gckOS_AllocateContiguous(
-    IN gckOS Os,
-    IN gctBOOL InUserSpace,
-    IN OUT gctSIZE_T * Bytes,
-    OUT gctPHYS_ADDR * Physical,
-    OUT gctPOINTER * Logical
-    )
-{
-    gceSTATUS status;
+    /* Flush the page table cache. */
+    {
+        gckMMU mmu = Os->device->kernels[Core]->mmu;
+        gcsADDRESS_AREA * area = &mmu->dynamicArea1M;
 
-    gcmkHEADER_ARG("Os=0x%X InUserSpace=%d *Bytes=%lu",
-                   Os, InUserSpace, gcmOPT_VALUE(Bytes));
+        offset = (gctUINT8_PTR)PageTable - (gctUINT8_PTR)area->stlbLogical;
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Bytes != gcvNULL);
-    gcmkVERIFY_ARGUMENT(*Bytes > 0);
-    gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
+        /* must be in dynamic area. */
+        gcmkASSERT(offset < area->stlbSize);
 
-    /* Same as non-paged memory for now. */
-    gcmkONERROR(gckOS_AllocateNonPagedMemory(Os,
-                                             InUserSpace,
-                                             gcvALLOC_FLAG_CONTIGUOUS,
-                                             Bytes,
-                                             Physical,
-                                             Logical));
+        gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
+            Os->device->kernels[Core],
+            area->stlbVideoMem,
+            offset,
+            PageTable,
+            bytes
+            ));
 
-    /* Success. */
-    gcmkFOOTER_ARG("*Bytes=%lu *Physical=0x%X *Logical=0x%X",
-                   *Bytes, *Physical, *Logical);
-    return gcvSTATUS_OK;
+        if (mmu->mtlbVideoMem)
+        {
+            /* Flush MTLB table. */
+            gcmkVERIFY_OK(gckVIDMEM_NODE_CleanCache(
+                Os->device->kernels[Core],
+                mmu->mtlbVideoMem,
+                offset,
+                mmu->mtlbLogical,
+                mmu->mtlbSize
+                ));
+        }
+    }
 
 OnError:
     /* Return the status. */
@@ -3779,9 +3646,9 @@ OnError:
 
 /*******************************************************************************
 **
-**  gckOS_FreeContiguous
+**  gckOS_UnlockPages
 **
-**  Free memory allocated from the contiguous pool.
+**  Unlock memory allocated from the paged pool.
 **
 **  INPUT:
 **
@@ -3791,158 +3658,62 @@ OnError:
 **      gctPHYS_ADDR Physical
 **          Physical address of the allocation.
 **
-**      gctPOINTER Logical
-**          Logicval address of the allocation.
-**
 **      gctSIZE_T Bytes
 **          Number of bytes of the allocation.
 **
+**      gctPOINTER Logical
+**          Address of the mapped memory.
+**
 **  OUTPUT:
 **
 **      Nothing.
 */
 gceSTATUS
-gckOS_FreeContiguous(
+gckOS_UnlockPages(
     IN gckOS Os,
     IN gctPHYS_ADDR Physical,
-    IN gctPOINTER Logical,
-    IN gctSIZE_T Bytes
+    IN gctSIZE_T Bytes,
+    IN gctPOINTER Logical
     )
 {
-    gceSTATUS status;
+    PLINUX_MDL_MAP mdlMap;
+    PLINUX_MDL  mdl = (PLINUX_MDL)Physical;
+    gckALLOCATOR allocator = mdl->allocator;
+    gctINT pid = _GetProcessID();
 
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X Logical=0x%X Bytes=%lu",
-                   Os, Physical, Logical, Bytes);
+    gcmkHEADER_ARG("Os=%p Physical=%p Bytes=0x%zx Logical=%p",
+                   Os, Physical, Bytes, Logical);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
     gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-
-    /* Same of non-paged memory for now. */
-    gcmkONERROR(gckOS_FreeNonPagedMemory(Os, Bytes, Physical, Logical));
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    /* Return the status. */
-    gcmkFOOTER();
-    return status;
-}
-
-#if gcdENABLE_VG
-/******************************************************************************
-**
-**  gckOS_GetKernelLogical
-**
-**  Return the kernel logical pointer that corresponods to the specified
-**  hardware address.
-**
-**  INPUT:
-**
-**      gckOS Os
-**          Pointer to an gckOS object.
-**
-**      gctUINT32 Address
-**          Hardware physical address.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * KernelPointer
-**          Pointer to a variable receiving the pointer in kernel address space.
-*/
-gceSTATUS
-gckOS_GetKernelLogical(
-    IN gckOS Os,
-    IN gctUINT32 Address,
-    OUT gctPOINTER * KernelPointer
-    )
-{
-    return gckOS_GetKernelLogicalEx(Os, gcvCORE_MAJOR, Address, KernelPointer);
-}
-
-gceSTATUS
-gckOS_GetKernelLogicalEx(
-    IN gckOS Os,
-    IN gceCORE Core,
-    IN gctUINT32 Address,
-    OUT gctPOINTER * KernelPointer
-    )
-{
-    gceSTATUS status;
-
-    gcmkHEADER_ARG("Os=0x%X Core=%d Address=0x%08x", Os, Core, Address);
+    mutex_lock(&mdl->mapsMutex);
 
-    do
+    list_for_each_entry(mdlMap, &mdl->mapsHead, link)
     {
-        gckGALDEVICE device;
-        gckKERNEL kernel;
-        gcePOOL pool;
-        gctUINT32 offset;
-        gctPOINTER logical;
-
-        /* Extract the pointer to the gckGALDEVICE class. */
-        device = (gckGALDEVICE) Os->device;
-
-        /* Kernel shortcut. */
-        kernel = device->kernels[Core];
-#if gcdENABLE_VG
-       if (Core == gcvCORE_VG)
-       {
-           gcmkERR_BREAK(gckVGHARDWARE_SplitMemory(
-                kernel->vg->hardware, Address, &pool, &offset
-                ));
-       }
-       else
-#endif
-       {
-        /* Split the memory address into a pool type and offset. */
-            gcmkERR_BREAK(gckHARDWARE_SplitMemory(
-                kernel->hardware, Address, &pool, &offset
-                ));
-       }
-
-        /* Dispatch on pool. */
-        switch (pool)
+        if ((mdlMap->vmaAddr != gcvNULL) && (mdlMap->pid == pid))
         {
-        case gcvPOOL_LOCAL_INTERNAL:
-            /* Internal memory. */
-            logical = device->internalLogical;
-            break;
-
-        case gcvPOOL_LOCAL_EXTERNAL:
-            /* External memory. */
-            logical = device->externalLogical;
-            break;
-
-        case gcvPOOL_SYSTEM:
-            /* System memory. */
-            logical = device->contiguousLogical;
-            break;
+            if (--mdlMap->count == 0)
+            {
+                allocator->ops->UnmapUser(
+                    allocator,
+                    mdl,
+                    mdlMap,
+                    mdl->bytes);
 
-        default:
-            /* Invalid memory pool. */
-            gcmkFOOTER();
-            return gcvSTATUS_INVALID_ARGUMENT;
+                mdlMap->vmaAddr = gcvNULL;
+            }
         }
-
-        /* Build logical address of specified address. */
-        * KernelPointer = ((gctUINT8_PTR) logical) + offset;
-
-        /* Success. */
-        gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
-        return gcvSTATUS_OK;
     }
-    while (gcvFALSE);
 
-    /* Return status. */
-    gcmkFOOTER();
-    return status;
+    mutex_unlock(&mdl->mapsMutex);
+
+    /* Success. */
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
 }
-#endif
 
 /*******************************************************************************
 **
@@ -3975,7 +3746,7 @@ gckOS_MapUserPointer(
     OUT gctPOINTER * KernelPointer
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu", Os, Pointer, Size);
+    gcmkHEADER_ARG("Os=%p Pointer=%p Size=0x%zx", Os, Pointer, Size);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -3985,7 +3756,7 @@ gckOS_MapUserPointer(
 
     *KernelPointer = Pointer;
 
-    gcmkFOOTER_ARG("*KernelPointer=0x%X", *KernelPointer);
+    gcmkFOOTER_ARG("*KernelPointer=%p", *KernelPointer);
     return gcvSTATUS_OK;
 }
 
@@ -4021,7 +3792,7 @@ gckOS_UnmapUserPointer(
     IN gctPOINTER KernelPointer
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Pointer=0x%X Size=%lu KernelPointer=0x%X",
+    gcmkHEADER_ARG("Os=%p Pointer=%p Size=0x%zx KernelPointer=%p",
                    Os, Pointer, Size, KernelPointer);
 
     gcmkFOOTER_NO();
@@ -4056,7 +3827,7 @@ gckOS_QueryNeedCopy(
     OUT gctBOOL_PTR NeedCopy
     )
 {
-    gcmkHEADER_ARG("Os=0x%X ProcessID=%d", Os, ProcessID);
+    gcmkHEADER_ARG("Os=%p ProcessID=%d", Os, ProcessID);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -4102,9 +3873,9 @@ gckOS_CopyFromUserData(
     IN gctSIZE_T Size
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
+    gcmkHEADER_ARG("Os=%p KernelPointer=%p Pointer=%p Size=0x%zx",
                    Os, KernelPointer, Pointer, Size);
 
     /* Verify the arguments. */
@@ -4120,10 +3891,6 @@ gckOS_CopyFromUserData(
         gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
     }
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
     gcmkFOOTER();
@@ -4162,9 +3929,9 @@ gckOS_CopyToUserData(
     IN gctSIZE_T Size
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X KernelPointer=0x%X Pointer=0x%X Size=%lu",
+    gcmkHEADER_ARG("Os=%p KernelPointer=%p Pointer=%p Size=0x%zx",
                    Os, KernelPointer, Pointer, Size);
 
     /* Verify the arguments. */
@@ -4180,10 +3947,6 @@ gckOS_CopyToUserData(
         gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
     }
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
     gcmkFOOTER();
@@ -4218,14 +3981,19 @@ gckOS_WriteMemory(
     IN gctUINT32 Data
     )
 {
-    gceSTATUS status;
-    gcmkHEADER_ARG("Os=0x%X Address=0x%X Data=%u", Os, Address, Data);
+    gceSTATUS status = gcvSTATUS_OK;
+
+    gcmkHEADER_ARG("Os=%p Address=%p Data=%u", Os, Address, Data);
 
     /* Verify the arguments. */
     gcmkVERIFY_ARGUMENT(Address != gcvNULL);
 
     /* Write memory. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
+    if (access_ok(Address, 4))
+#else
     if (access_ok(VERIFY_WRITE, Address, 4))
+#endif
     {
         /* User address. */
         if (put_user(Data, (gctUINT32*)Address))
@@ -4233,133 +4001,56 @@ gckOS_WriteMemory(
             gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
         }
     }
-    else
+    else if (virt_addr_valid(Address) || is_vmalloc_addr(Address))
     {
         /* Kernel address. */
         *(gctUINT32 *)Address = Data;
     }
-
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
-OnError:
-    gcmkFOOTER();
-    return status;
-}
-
-gceSTATUS
-gckOS_ReadMappedPointer(
-    IN gckOS Os,
-    IN gctPOINTER Address,
-    IN gctUINT32_PTR Data
-    )
-{
-    gceSTATUS status;
-    gcmkHEADER_ARG("Os=0x%X Address=0x%X Data=%u", Os, Address, Data);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_ARGUMENT(Address != gcvNULL);
-
-    /* Write memory. */
-    if (access_ok(VERIFY_READ, Address, 4))
-    {
-        /* User address. */
-        if (get_user(*Data, (gctUINT32*)Address))
-        {
-            gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
-        }
-    }
     else
     {
-        /* Kernel address. */
-        *Data = *(gctUINT32_PTR)Address;
+        gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
     }
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     gcmkFOOTER();
     return status;
 }
 
-/*******************************************************************************
-**
-**  gckOS_MapUserMemory
-**
-**  Lock down a user buffer and return an DMA'able address to be used by the
-**  hardware to access it.
-**
-**  INPUT:
-**
-**      gctPOINTER Memory
-**          Pointer to memory to lock down.
-**
-**      gctSIZE_T Size
-**          Size in bytes of the memory to lock down.
-**
-**  OUTPUT:
-**
-**      gctPOINTER * Info
-**          Pointer to variable receiving the information record required by
-**          gckOS_UnmapUserMemory.
-**
-**      gctUINT32_PTR Address
-**          Pointer to a variable that will receive the address DMA'able by the
-**          hardware.
-*/
 gceSTATUS
-gckOS_MapUserMemory(
-    IN gckOS Os,
-    IN gceCORE Core,
-    IN gctPOINTER Memory,
-    IN gctUINT32 Physical,
-    IN gctSIZE_T Size,
-    OUT gctPOINTER * Info,
-    OUT gctUINT32_PTR Address
-    )
-{
-    return gcvSTATUS_NOT_SUPPORTED;
-}
-
-/*******************************************************************************
-**
-**  gckOS_UnmapUserMemory
-**
-**  Unlock a user buffer and that was previously locked down by
-**  gckOS_MapUserMemory.
-**
-**  INPUT:
-**
-**      gctPOINTER Memory
-**          Pointer to memory to unlock.
-**
-**      gctSIZE_T Size
-**          Size in bytes of the memory to unlock.
-**
-**      gctPOINTER Info
-**          Information record returned by gckOS_MapUserMemory.
-**
-**      gctUINT32_PTR Address
-**          The address returned by gckOS_MapUserMemory.
-**
-**  OUTPUT:
-**
-**      Nothing.
-*/
-gceSTATUS
-gckOS_UnmapUserMemory(
+gckOS_ReadMappedPointer(
     IN gckOS Os,
-    IN gceCORE Core,
-    IN gctPOINTER Memory,
-    IN gctSIZE_T Size,
-    IN gctPOINTER Info,
-    IN gctUINT32 Address
+    IN gctPOINTER Address,
+    IN gctUINT32_PTR Data
     )
 {
-    return gcvSTATUS_NOT_SUPPORTED;
+    gceSTATUS status = gcvSTATUS_OK;
+    gcmkHEADER_ARG("Os=%p Address=%p Data=%u", Os, Address, Data);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_ARGUMENT(Address != gcvNULL);
+
+    /* Write memory. */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 0, 0)
+    if (access_ok(Address, 4))
+#else
+    if (access_ok(VERIFY_READ, Address, 4))
+#endif
+    {
+        /* User address. */
+        if (get_user(*Data, (gctUINT32*)Address))
+        {
+            gcmkONERROR(gcvSTATUS_INVALID_ADDRESS);
+        }
+    }
+    else
+    {
+        /* Kernel address. */
+        *Data = *(gctUINT32_PTR)Address;
+    }
+
+OnError:
+    gcmkFOOTER();
+    return status;
 }
 
 /*******************************************************************************
@@ -4384,7 +4075,7 @@ gckOS_GetBaseAddress(
     OUT gctUINT32_PTR BaseAddress
     )
 {
-    gcmkHEADER_ARG("Os=0x%X", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -4412,7 +4103,7 @@ gckOS_SuspendInterruptEx(
     IN gceCORE Core
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+    gcmkHEADER_ARG("Os=%p Core=%d", Os, Core);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -4437,7 +4128,7 @@ gckOS_ResumeInterruptEx(
     IN gceCORE Core
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+    gcmkHEADER_ARG("Os=%p Core=%d", Os, Core);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -4455,7 +4146,7 @@ gckOS_MemCopy(
     IN gctSIZE_T Bytes
     )
 {
-    gcmkHEADER_ARG("Destination=0x%X Source=0x%X Bytes=%lu",
+    gcmkHEADER_ARG("Destination=%p Source=%p Bytes=0x%zx",
                    Destination, Source, Bytes);
 
     gcmkVERIFY_ARGUMENT(Destination != gcvNULL);
@@ -4474,7 +4165,7 @@ gckOS_ZeroMemory(
     IN gctSIZE_T Bytes
     )
 {
-    gcmkHEADER_ARG("Memory=0x%X Bytes=%lu", Memory, Bytes);
+    gcmkHEADER_ARG("Memory=%p Bytes=0x%zx", Memory, Bytes);
 
     gcmkVERIFY_ARGUMENT(Memory != gcvNULL);
     gcmkVERIFY_ARGUMENT(Bytes > 0);
@@ -4600,13 +4291,8 @@ gckOS_CacheClean(
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Os=0x%X ProcessID=%d Handle=0x%X Logical=%p Bytes=%lu",
-                   Os, ProcessID, Handle, Logical, Bytes);
-
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
+    gcmkHEADER_ARG("Os=%p ProcessID=%d Handle=%p Offset=0x%llx Logical=%p Bytes=0x%zx",
+                   Os, ProcessID, Handle, Offset, Logical, Bytes);
 
     gcmkONERROR(_CacheOperation(Os, ProcessID,
                                 Handle, Offset, Logical, Bytes,
@@ -4615,7 +4301,6 @@ gckOS_CacheClean(
 OnError:
     gcmkFOOTER();
     return status;
-
 }
 
 /*******************************************************************************
@@ -4636,9 +4321,6 @@ OnError:
 **      gctPHYS_ADDR Handle
 **          Physical address handle.  If gcvNULL it is video memory.
 **
-**      gctSIZE_T Offset
-**          Offset to this memory block.
-**
 **      gctPOINTER Logical
 **          Logical address to flush.
 **
@@ -4660,11 +4342,6 @@ gckOS_CacheInvalidate(
     gcmkHEADER_ARG("Os=%p ProcessID=%d Handle=%p Offset=0x%llx Logical=%p Bytes=0x%zx",
                    Os, ProcessID, Handle, Offset, Logical, Bytes);
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-
     gcmkONERROR(_CacheOperation(Os, ProcessID,
                                 Handle, Offset, Logical, Bytes,
                                 gcvCACHE_INVALIDATE));
@@ -4692,9 +4369,6 @@ OnError:
 **      gctPHYS_ADDR Handle
 **          Physical address handle.  If gcvNULL it is video memory.
 **
-**      gctSIZE_T Offset
-**          Offset to this memory block.
-**
 **      gctPOINTER Logical
 **          Logical address to flush.
 **
@@ -4716,11 +4390,6 @@ gckOS_CacheFlush(
     gcmkHEADER_ARG("Os=%p ProcessID=%d Handle=%p Offset=0x%llx Logical=%p Bytes=0x%zx",
                    Os, ProcessID, Handle, Offset, Logical, Bytes);
 
-    /* Verify the arguments. */
-    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
-    gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
-    gcmkVERIFY_ARGUMENT(Bytes > 0);
-
     gcmkONERROR(_CacheOperation(Os, ProcessID,
                                 Handle, Offset, Logical, Bytes,
                                 gcvCACHE_FLUSH));
@@ -4780,14 +4449,10 @@ gckOS_Broadcast(
     IN gceBROADCAST Reason
     )
 {
-    gceSTATUS status;
-#if gcdPOWER_SUSPEND_WHEN_IDLE
-    gceCHIPPOWERSTATE state = gcvPOWER_SUSPEND_BROADCAST;
-#else
-    gceCHIPPOWERSTATE state = gcvPOWER_IDLE_BROADCAST;
-#endif
+    gceSTATUS status = gcvSTATUS_OK;
+    gceCHIPPOWERSTATE state;
 
-    gcmkHEADER_ARG("Os=0x%X Hardware=0x%X Reason=%d", Os, Hardware, Reason);
+    gcmkHEADER_ARG("Os=%p Hardware=%p Reason=%d", Os, Hardware, Reason);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -4804,16 +4469,21 @@ gckOS_Broadcast(
 
         /* Put GPU OFF. */
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(Hardware,
-                                                gcvPOWER_OFF_BROADCAST));
+            gckHARDWARE_SetPowerState(Hardware,
+                                      gcvPOWER_OFF_BROADCAST));
         break;
 
     case gcvBROADCAST_GPU_IDLE:
         gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_OS, "GPU idle.");
+#if gcdPOWER_SUSPEND_WHEN_IDLE
+        state = gcvPOWER_SUSPEND_BROADCAST;
+#else
+        state = gcvPOWER_IDLE_BROADCAST;
+#endif
 
-        /* Put GPU IDLE. */
+        /* Put GPU IDLE or SUSPEND. */
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(Hardware, state));
+            gckHARDWARE_SetPowerState(Hardware, state));
 
         /* Add idle process DB. */
         gcmkONERROR(gckKERNEL_AddProcessDB(Hardware->kernel,
@@ -4833,7 +4503,7 @@ gckOS_Broadcast(
 
         /* Put GPU ON. */
         gcmkONERROR(
-            gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON_AUTO));
+            gckHARDWARE_SetPowerState(Hardware, gcvPOWER_ON_AUTO));
         break;
 
     case gcvBROADCAST_GPU_STUCK:
@@ -4866,10 +4536,6 @@ gckOS_Broadcast(
         break;
     }
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
     gcmkFOOTER();
@@ -4905,7 +4571,7 @@ gckOS_BroadcastHurry(
     IN gctUINT Urgency
     )
 {
-    gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Urgency=%u", Os, Hardware, Urgency);
+    gcmkHEADER_ARG("Os=%p Hardware=%p Urgency=%u", Os, Hardware, Urgency);
 
     /* Do whatever you need to do to speed up the GPU now. */
 
@@ -4944,7 +4610,7 @@ gckOS_BroadcastCalibrateSpeed(
     IN gctUINT Time
     )
 {
-    gcmkHEADER_ARG("Os=0x%x Hardware=0x%x Idle=%u Time=%u",
+    gcmkHEADER_ARG("Os=%p Hardware=%p Idle=%u Time=%u",
                    Os, Hardware, Idle, Time);
 
     /* Do whatever you need to do to callibrate the GPU speed. */
@@ -4980,10 +4646,10 @@ gckOS_CreateSemaphore(
     OUT gctPOINTER * Semaphore
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     struct semaphore *sem = gcvNULL;
 
-    gcmkHEADER_ARG("Os=0x%X", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -5002,10 +4668,6 @@ gckOS_CreateSemaphore(
     /* Return to caller. */
     *Semaphore = (gctPOINTER) sem;
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     /* Return the status. */
     gcmkFOOTER();
@@ -5036,7 +4698,7 @@ gckOS_AcquireSemaphore(
     IN gctPOINTER Semaphore
     )
 {
-    gcmkHEADER_ARG("Os=0x%08X Semaphore=0x%08X", Os, Semaphore);
+    gcmkHEADER_ARG("Os=%p Semaphore=%p", Os, Semaphore);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -5074,9 +4736,9 @@ gckOS_TryAcquireSemaphore(
     IN gctPOINTER Semaphore
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%x", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -5087,13 +4749,11 @@ gckOS_TryAcquireSemaphore(
     {
         /* Timeout. */
         status = gcvSTATUS_TIMEOUT;
-        gcmkFOOTER();
-        return status;
     }
 
     /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
+    gcmkFOOTER();
+    return status;
 }
 
 /*******************************************************************************
@@ -5120,7 +4780,7 @@ gckOS_ReleaseSemaphore(
     IN gctPOINTER Semaphore
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
+    gcmkHEADER_ARG("Os=%p Semaphore=%p", Os, Semaphore);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -5158,7 +4818,7 @@ gckOS_DestroySemaphore(
     IN gctPOINTER Semaphore
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Semaphore=0x%X", Os, Semaphore);
+    gcmkHEADER_ARG("Os=%p Semaphore=%p", Os, Semaphore);
 
      /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -5266,7 +4926,7 @@ gckOS_SetGPUPower(
     gctBOOL powerChange = gcvFALSE;
     gctBOOL clockChange = gcvFALSE;
 
-    gcmkHEADER_ARG("Os=0x%X Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
+    gcmkHEADER_ARG("Os=%p Core=%d Clock=%d Power=%d", Os, Core, Clock, Power);
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
 
     platform = Os->device->platform;
@@ -5356,7 +5016,7 @@ gckOS_ResetGPU(
     gceSTATUS status = gcvSTATUS_NOT_SUPPORTED;
     gcsPLATFORM * platform;
 
-    gcmkHEADER_ARG("Os=0x%X Core=%d", Os, Core);
+    gcmkHEADER_ARG("Os=%p Core=%d", Os, Core);
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
 
     platform = Os->device->platform;
@@ -5615,10 +5275,10 @@ gckOS_CreateSignal(
     OUT gctSIGNAL * Signal
     )
 {
-    gceSTATUS status;
-    gcsSIGNAL_PTR signal;
+    gceSTATUS status = gcvSTATUS_OK;
+    gcsSIGNAL_PTR signal = gcvNULL;
 
-    gcmkHEADER_ARG("Os=0x%X ManualReset=%d", Os, ManualReset);
+    gcmkHEADER_ARG("Os=%p ManualReset=%d", Os, ManualReset);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -5654,16 +5314,13 @@ gckOS_CreateSignal(
 
     *Signal = (gctSIGNAL)(gctUINTPTR_T)signal->id;
 
-    gcmkFOOTER_ARG("*Signal=0x%X", *Signal);
-    return gcvSTATUS_OK;
-
 OnError:
-    if (signal != gcvNULL)
+    if (gcmIS_ERROR(status) && signal)
     {
         kfree(signal);
     }
 
-    gcmkFOOTER_NO();
+    gcmkFOOTER_ARG("*Signal=%p", *Signal);
     return status;
 }
 
@@ -5691,12 +5348,12 @@ gckOS_DestroySignal(
     IN gctSIGNAL Signal
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     gcsSIGNAL_PTR signal;
     gctBOOL acquired = gcvFALSE;
     unsigned long flags = 0;
 
-    gcmkHEADER_ARG("Os=0x%X Signal=0x%X", Os, Signal);
+    gcmkHEADER_ARG("Os=%p Signal=%p", Os, Signal);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -5726,13 +5383,8 @@ gckOS_DestroySignal(
     }else{
         spin_unlock_irqrestore(&Os->signalLock, flags);
     }
-
     acquired = gcvFALSE;
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     if (acquired)
     {
@@ -5742,7 +5394,6 @@ OnError:
         }else{
             spin_unlock_irqrestore(&Os->signalLock, flags);
         }
-
     }
 
     gcmkFOOTER();
@@ -5789,7 +5440,7 @@ gckOS_Signal(
 #endif
     unsigned long flags = 0;
 
-    gcmkHEADER_ARG("Os=0x%X Signal=0x%X State=%d", Os, Signal, State);
+    gcmkHEADER_ARG("Os=%p Signal=%p State=%d", Os, Signal, State);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -5872,10 +5523,6 @@ gckOS_Signal(
 
     spin_unlock_irqrestore(&Os->signalLock, flags);
 
-    /* Success. */
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     gcmkFOOTER();
     return status;
@@ -5911,8 +5558,7 @@ gckOS_UserSignal(
 {
     gceSTATUS status;
 
-    gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=%d",
-                   Os, Signal, (gctINT32)(gctUINTPTR_T)Process);
+    gcmkHEADER_ARG("Os=%p Signal=%p Process=%p", Os, Signal, Process);
 
     /* Signal. */
     status = gckOS_Signal(Os, Signal, gcvTRUE);
@@ -5955,7 +5601,7 @@ gckOS_WaitSignal(
     gcsSIGNAL_PTR signal = gcvNULL;
     int done;
 
-    gcmkHEADER_ARG("Os=0x%X Signal=0x%X Wait=0x%08X", Os, Signal, Wait);
+    gcmkHEADER_ARG("Os=%p Signal=%p Wait=0x%08X", Os, Signal, Wait);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -6029,7 +5675,7 @@ gckOS_WaitSignal(
 
 OnError:
     /* Return status. */
-    gcmkFOOTER_ARG("Signal=0x%lX status=%d", Signal, status);
+    gcmkFOOTER();
     return status;
 }
 
@@ -6093,10 +5739,10 @@ gckOS_MapSignal(
     OUT gctSIGNAL * MappedSignal
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     gcsSIGNAL_PTR signal = gcvNULL;
     unsigned long flags = 0;
-    gcmkHEADER_ARG("Os=0x%X Signal=0x%X Process=0x%X", Os, Signal, Process);
+    gcmkHEADER_ARG("Os=%p Signal=%p Process=%p", Os, Signal, Process);
 
     gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
     gcmkVERIFY_ARGUMENT(MappedSignal != gcvNULL);
@@ -6113,16 +5759,10 @@ gckOS_MapSignal(
 
     *MappedSignal = (gctSIGNAL) Signal;
 
-    spin_unlock_irqrestore(&Os->signalLock, flags);
-
-    /* Success. */
-    gcmkFOOTER_ARG("*MappedSignal=0x%X", *MappedSignal);
-    return gcvSTATUS_OK;
-
 OnError:
     spin_unlock_irqrestore(&Os->signalLock, flags);
 
-    gcmkFOOTER_NO();
+    gcmkFOOTER_ARG("*MappedSignal=%p", *MappedSignal);
     return status;
 }
 
@@ -6290,7 +5930,7 @@ gckOS_CreateSemaphoreVG(
     gceSTATUS status;
     struct semaphore * newSemaphore;
 
-    gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
+    gcmkHEADER_ARG("Os=%p Semaphore=%p", Os, Semaphore);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
@@ -6327,7 +5967,7 @@ gckOS_IncrementSemaphore(
     IN gctSEMAPHORE Semaphore
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
+    gcmkHEADER_ARG("Os=%p Semaphore=%p", Os, Semaphore);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
@@ -6349,7 +5989,7 @@ gckOS_DecrementSemaphore(
     gceSTATUS status;
     gctINT result;
 
-    gcmkHEADER_ARG("Os=0x%X Semaphore=0x%x", Os, Semaphore);
+    gcmkHEADER_ARG("Os=%p Semaphore=%p", Os, Semaphore);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Semaphore != gcvNULL);
@@ -6392,7 +6032,7 @@ gckOS_StartThread(
     gceSTATUS status;
     struct task_struct * thread;
 
-    gcmkHEADER_ARG("Os=0x%X ", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(ThreadFunction != gcvNULL);
@@ -6436,7 +6076,7 @@ gckOS_StopThread(
     IN gctTHREAD Thread
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
+    gcmkHEADER_ARG("Os=%p Thread=%p", Os, Thread);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
@@ -6455,7 +6095,7 @@ gckOS_VerifyThread(
     IN gctTHREAD Thread
     )
 {
-    gcmkHEADER_ARG("Os=0x%X Thread=0x%x", Os, Thread);
+    gcmkHEADER_ARG("Os=%p Thread=%p", Os, Thread);
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Thread != gcvNULL);
@@ -6513,9 +6153,9 @@ gckOS_CreateTimer(
     OUT gctPOINTER * Timer
     )
 {
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
     gcsOSTIMER_PTR pointer;
-    gcmkHEADER_ARG("Os=0x%X Function=0x%X Data=0x%X", Os, Function, Data);
+    gcmkHEADER_ARG("Os=%p Function=0%p Data=%p", Os, Function, Data);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -6530,9 +6170,6 @@ gckOS_CreateTimer(
 
     *Timer = pointer;
 
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     gcmkFOOTER();
     return status;
@@ -6563,7 +6200,8 @@ gckOS_DestroyTimer(
     )
 {
     gcsOSTIMER_PTR timer;
-    gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
+
+    gcmkHEADER_ARG("Os=%p Timer=%p", Os, Timer);
 
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
@@ -6613,7 +6251,7 @@ gckOS_StartTimer(
 {
     gcsOSTIMER_PTR timer;
 
-    gcmkHEADER_ARG("Os=0x%X Timer=0x%X Delay=%u", Os, Timer, Delay);
+    gcmkHEADER_ARG("Os=%p Timer=%p Delay=%u", Os, Timer, Delay);
 
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
@@ -6666,7 +6304,7 @@ gckOS_StopTimer(
     )
 {
     gcsOSTIMER_PTR timer;
-    gcmkHEADER_ARG("Os=0x%X Timer=0x%X", Os, Timer);
+    gcmkHEADER_ARG("Os=%p Timer=%p", Os, Timer);
 
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Timer != gcvNULL);
@@ -6687,24 +6325,25 @@ gckOS_GetProcessNameByPid(
     )
 {
     struct task_struct *task;
+    gceSTATUS status = gcvSTATUS_OK;
 
     /* Get the task_struct of the task with pid. */
     rcu_read_lock();
 
     task = FIND_TASK_BY_PID(Pid);
-
-    if (task == gcvNULL)
+    if (task)
     {
-        rcu_read_unlock();
-        return gcvSTATUS_NOT_FOUND;
+        /* Get name of process. */
+        strncpy(String, task->comm, Length);
+    }
+    else
+    {
+        status = gcvSTATUS_NOT_FOUND;
     }
-
-    /* Get name of process. */
-    strncpy(String, task->comm, Length);
 
     rcu_read_unlock();
 
-    return gcvSTATUS_OK;
+    return status;
 }
 
 gceSTATUS
@@ -6712,7 +6351,7 @@ gckOS_DumpCallStack(
     IN gckOS Os
     )
 {
-    gcmkHEADER_ARG("Os=0x%X", Os);
+    gcmkHEADER_ARG("Os=%p", Os);
 
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
 
@@ -6766,6 +6405,7 @@ gckOS_CreateSyncTimeline(
     OUT gctHANDLE * Timeline
     )
 {
+    gceSTATUS status = gcvSTATUS_OK;
     struct viv_sync_timeline * timeline;
     char name[32];
 
@@ -6774,14 +6414,18 @@ gckOS_CreateSyncTimeline(
     /* Create viv sync timeline. */
     timeline = viv_sync_timeline_create(name, Os);
 
-    if (timeline == gcvNULL)
+    if (timeline)
+    {
+        *Timeline = (gctHANDLE)timeline;
+    }
+    else
     {
         /* Out of memory. */
-        return gcvSTATUS_OUT_OF_MEMORY;
+        status = gcvSTATUS_OUT_OF_MEMORY;
     }
 
-    *Timeline = (gctHANDLE) timeline;
-    return gcvSTATUS_OK;
+
+    return status;
 }
 
 gceSTATUS
@@ -6814,10 +6458,9 @@ gckOS_CreateNativeFence(
     struct sync_fence * fence;
     char name[32];
     gcsSIGNAL_PTR signal;
-    gceSTATUS status;
+    gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Timeline=0x%X Signal=%d",
-                   Os, Timeline, (gctUINT)(gctUINTPTR_T)Signal);
+    gcmkHEADER_ARG("Os=%p Timeline=%p Signal=%p", Os, Timeline, Signal);
 
     gcmkONERROR(
         _QueryIntegerId(&Os->signalDB,
@@ -6863,22 +6506,24 @@ gckOS_CreateNativeFence(
     sync_fence_install(fence, fd);
 
     *FenceFD = fd;
-    gcmkFOOTER_ARG("*FenceFD=%d", fd);
     return gcvSTATUS_OK;
 
 OnError:
-    /* Error roll back. */
-    if (pt)
+    if (gcmIS_ERROR(status))
     {
-        sync_pt_free(pt);
-    }
+        /* Error roll back. */
+        if (pt)
+        {
+            sync_pt_free(pt);
+        }
 
-    if (fd > 0)
-    {
-        put_unused_fd(fd);
+        if (fd > 0)
+        {
+            put_unused_fd(fd);
+        }
     }
 
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*FenceFD=%d", fd);
     return status;
 }
 
@@ -6902,10 +6547,9 @@ gckOS_WaitNativeFence(
 {
     struct sync_timeline * timeline;
     struct sync_fence * fence;
-    gctBOOL wait;
     gceSTATUS status = gcvSTATUS_OK;
 
-    gcmkHEADER_ARG("Os=0x%X Timeline=0x%X FenceFD=%d Timeout=%u",
+    gcmkHEADER_ARG("Os=%p Timeline=%p FenceFD=%d Timeout=%u",
                    Os, Timeline, FenceFD, Timeout);
 
     /* Get shortcut. */
@@ -6924,14 +6568,13 @@ gckOS_WaitNativeFence(
         /* Already signaled. */
         sync_fence_put(fence);
 
-        gcmkFOOTER_NO();
-        return gcvSTATUS_OK;
+        goto OnError;
     }
-
-    wait = gcvFALSE;
+    else
+    {
+        gctBOOL wait = gcvFALSE;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0)
-    {
         int i;
 
         for (i = 0; i < fence->num_fences; i++)
@@ -6946,87 +6589,79 @@ gckOS_WaitNativeFence(
                 break;
             }
         }
-    }
 #else
-    {
-        struct list_head *pos;
-        list_for_each(pos, &fence->pt_list_head)
         {
-            struct sync_pt * pt =
-            container_of(pos, struct sync_pt, pt_list);
-
-            /* Do not need to wait on same timeline. */
-            if (pt->parent != timeline)
+            struct list_head *pos;
+            list_for_each(pos, &fence->pt_list_head)
             {
-                wait = gcvTRUE;
-                break;
+                struct sync_pt * pt =
+                container_of(pos, struct sync_pt, pt_list);
+
+                /* Do not need to wait on same timeline. */
+                if (pt->parent != timeline)
+                {
+                    wait = gcvTRUE;
+                    break;
+                }
             }
         }
-    }
 #endif
 
-    if (wait)
-    {
-        int err;
-        long timeout = (Timeout == gcvINFINITE) ? - 1 : (long) Timeout;
-        err = sync_fence_wait(fence, timeout);
+        if (wait)
+        {
+            int err;
+            long timeout = (Timeout == gcvINFINITE) ? - 1 : (long) Timeout;
+            err = sync_fence_wait(fence, timeout);
 
-        /* Put the fence. */
-        sync_fence_put(fence);
+            /* Put the fence. */
+            sync_fence_put(fence);
 
-        switch (err)
-        {
-        case 0:
-            break;
-        case -ETIME:
-            status = gcvSTATUS_TIMEOUT;
-            break;
-        default:
-            gcmkONERROR(gcvSTATUS_GENERIC_IO);
-            break;
+            switch (err)
+            {
+            case 0:
+                break;
+            case -ETIME:
+                status = gcvSTATUS_TIMEOUT;
+                break;
+            default:
+                gcmkONERROR(gcvSTATUS_GENERIC_IO);
+                break;
+            }
         }
-    }
-    else
-    {
-        int err;
-        struct sync_fence_waiter *waiter;
-        waiter = (struct sync_fence_waiter *)kmalloc(
-                sizeof (struct sync_fence_waiter), gcdNOWARN | GFP_KERNEL);
-
-        /*
-         * schedule a callback to put the sync_fence. Otherwise after this function
-         * is returned, the caller may free it since it's signaled. Then there's
-         * be a real signal on a free'ed sync fence.
-         */
-        if (!waiter)
+        else
         {
-            sync_fence_put(fence);
-            gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
-        }
+            int err;
+            struct sync_fence_waiter *waiter;
+            waiter = (struct sync_fence_waiter *)kmalloc(
+                    sizeof (struct sync_fence_waiter), gcdNOWARN | GFP_KERNEL);
 
-        /* Schedule a waiter callback. */
-        sync_fence_waiter_init(waiter, _NativeFenceSignaled);
-        err = sync_fence_wait_async(fence, waiter);
+            if (!waiter)
+            {
+                sync_fence_put(fence);
+                gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
+            }
 
-        switch (err)
-        {
-        case 0:
-            /* Put fence in callback function. */
-            break;
-        case 1:
-            /* already signaled. */
-            sync_fence_put(fence);
-            break;
-        default:
-            sync_fence_put(fence);
-            gcmkONERROR(gcvSTATUS_GENERIC_IO);
-            break;
+            /* Schedule a waiter callback. */
+            sync_fence_waiter_init(waiter, _NativeFenceSignaled);
+            err = sync_fence_wait_async(fence, waiter);
+
+            switch (err)
+            {
+            case 0:
+                /* Put fence in callback function. */
+                break;
+            case 1:
+                /* already signaled. */
+                sync_fence_put(fence);
+                break;
+            default:
+                sync_fence_put(fence);
+                gcmkONERROR(gcvSTATUS_GENERIC_IO);
+                break;
+            }
         }
     }
 
-    gcmkFOOTER_NO();
-    return gcvSTATUS_OK;
-
 OnError:
     gcmkFOOTER();
     return status;
@@ -7276,8 +6911,7 @@ gckOS_WaitNativeFence(
     {
         struct dma_fence *f = fences[i];
 
-        if (f->context != timeline->context &&
-            !dma_fence_is_signaled(f))
+        if(!dma_fence_is_signaled(fence))
         {
             signed long ret;
             ret = dma_fence_wait_timeout(f, 1, timeout);
@@ -7329,7 +6963,7 @@ gckOS_AllocatePageArray(
     gctSIZE_T   bytes;
     gckALLOCATOR allocator;
 
-    gcmkHEADER_ARG("Os=0x%X Physical=0x%X PageCount=%u",
+    gcmkHEADER_ARG("Os=%p Physical=%p PageCount=%u",
                    Os, Physical, PageCount);
 
     /* Verify the arguments. */
@@ -7417,7 +7051,7 @@ gckOS_GPUPhysicalToCPUPhysical(
     )
 {
     gcsPLATFORM * platform;
-    gcmkHEADER_ARG("GPUPhysical=0x%X", GPUPhysical);
+    gcmkHEADER_ARG("Os=%p GPUPhysical=0x%x", Os, GPUPhysical);
 
     platform = Os->device->platform;
 
@@ -7431,39 +7065,15 @@ gckOS_GPUPhysicalToCPUPhysical(
         *CPUPhysical = GPUPhysical;
     }
 
-    gcmkFOOTER_NO();
+    gcmkFOOTER_ARG("CPUPhysical=0x%llx", gcmOPT_VALUE(CPUPhysical));
     return gcvSTATUS_OK;
 }
 
-gceSTATUS
-gckOS_PhysicalToPhysicalAddress(
-    IN gckOS Os,
-    IN gctPOINTER Physical,
-    IN gctUINT32 Offset,
-    OUT gctPHYS_ADDR_T * PhysicalAddress
-    )
-{
-    PLINUX_MDL mdl = (PLINUX_MDL)Physical;
-    gckALLOCATOR allocator = mdl->allocator;
-
-    if (allocator)
-    {
-        return allocator->ops->Physical(allocator, mdl, Offset, PhysicalAddress);
-    }
-
-    return gcvSTATUS_NOT_SUPPORTED;
-}
-
 static int fd_release(struct inode *inode, struct file *file)
 {
     gcsFDPRIVATE_PTR private = (gcsFDPRIVATE_PTR)file->private_data;
 
-    if (private && private->release)
-    {
-        return private->release(private);
-    }
-
-    return 0;
+    return (private && private->release) ? private->release(private) : 0;
 }
 
 static const struct file_operations fd_fops =
@@ -7496,39 +7106,35 @@ gceSTATUS
 gckOS_QueryOption(
     IN gckOS Os,
     IN gctCONST_STRING Option,
-    OUT gctUINT32 * Value
+    OUT gctUINT64 * Value
     )
 {
     gckGALDEVICE device = Os->device;
+    gceSTATUS status = gcvSTATUS_OK;
 
     if (!strcmp(Option, "physBase"))
     {
         *Value = device->physBase;
-        return gcvSTATUS_OK;
     }
     else if (!strcmp(Option, "physSize"))
     {
         *Value = device->physSize;
-        return gcvSTATUS_OK;
     }
     else if (!strcmp(Option, "mmu"))
     {
 #if gcdSECURITY
         *Value = 0;
 #else
-        *Value = device->args.mmu;
+        *Value = device->args.enableMmu;
 #endif
-        return gcvSTATUS_OK;
     }
     else if (!strcmp(Option, "contiguousSize"))
     {
         *Value = device->contiguousSize;
-        return gcvSTATUS_OK;
     }
     else if (!strcmp(Option, "contiguousBase"))
     {
-        *Value = (gctUINT32)device->contiguousBase;
-        return gcvSTATUS_OK;
+        *Value = device->contiguousBase;
     }
     else if (!strcmp(Option, "externalSize"))
     {
@@ -7543,35 +7149,53 @@ gckOS_QueryOption(
     else if (!strcmp(Option, "recovery"))
     {
         *Value = device->args.recovery;
-        return gcvSTATUS_OK;
     }
     else if (!strcmp(Option, "stuckDump"))
     {
         *Value = device->args.stuckDump;
-        return gcvSTATUS_OK;
     }
     else if (!strcmp(Option, "powerManagement"))
     {
         *Value = device->args.powerManagement;
-        return gcvSTATUS_OK;
     }
     else if (!strcmp(Option, "TA"))
     {
         *Value = 0;
-        return gcvSTATUS_OK;
     }
     else if (!strcmp(Option, "gpuProfiler"))
     {
         *Value = device->args.gpuProfiler;
-        return gcvSTATUS_OK;
+    }
+    else if (!strcmp(Option, "userClusterMask"))
+    {
+        *Value = device->args.userClusterMask;
+    }
+    else if (!strcmp(Option, "smallBatch"))
+    {
+        *Value = device->args.smallBatch;
+    }
+    else if (!strcmp(Option, "sRAMBases"))
+    {
+        memcpy(Value, device->args.sRAMBases, gcmSIZEOF(gctUINT64) * gcvSRAM_COUNT * gcvCORE_COUNT);
+    }
+    else if (!strcmp(Option, "sRAMSizes"))
+    {
+        memcpy(Value, device->args.sRAMSizes, gcmSIZEOF(gctUINT32) * gcvSRAM_COUNT * gcvCORE_COUNT);
+    }
+    else if (!strcmp(Option, "sRAMMode"))
+    {
+        *Value = device->args.sRAMMode;
     }
     else if (!strcmp(Option, "platformFlagBits"))
     {
         *Value = device->platform->flagBits;
-        return gcvSTATUS_OK;
+    }
+    else
+    {
+        status = gcvSTATUS_NOT_SUPPORTED;
     }
 
-    return gcvSTATUS_NOT_SUPPORTED;
+    return status;
 }
 
 gceSTATUS
@@ -7682,7 +7306,8 @@ gckOS_WrapMemory(
     IN gcsUSER_MEMORY_DESC_PTR Desc,
     OUT gctSIZE_T *Bytes,
     OUT gctPHYS_ADDR * Physical,
-    OUT gctBOOL *Contiguous
+    OUT gctBOOL *Contiguous,
+    OUT gctSIZE_T * PageCountCpu
     )
 {
     PLINUX_MDL mdl = gcvNULL;
@@ -7691,11 +7316,12 @@ gckOS_WrapMemory(
     gcsATTACH_DESC desc;
     gctSIZE_T bytes = 0;
 
-    gcmkHEADER_ARG("Os=0x%X ", Os);
+    gcmkHEADER_ARG("Os=%p ", Os);
 
     /* Verify the arguments. */
     gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
     gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
+    gcmkVERIFY_ARGUMENT(Desc != gcvNULL);
 
     mdl = _CreateMdl(Os);
     if (mdl == gcvNULL)
@@ -7777,6 +7403,11 @@ gckOS_WrapMemory(
 
     *Contiguous = mdl->contiguous;
 
+    if (PageCountCpu)
+    {
+        *PageCountCpu = mdl->numPages;
+    }
+
     /*
      * Add this to a global list.
      * Will be used by get physical address
@@ -7787,36 +7418,33 @@ gckOS_WrapMemory(
     mutex_unlock(&Os->mdlMutex);
 
     /* Success. */
-    gcmkFOOTER_ARG("*Physical=0x%X", *Physical);
-    return gcvSTATUS_OK;
+    status = gcvSTATUS_OK;
 
 OnError:
-    if (mdl != gcvNULL)
+    if (gcmIS_ERROR(status) && mdl)
     {
         /* Free the memory. */
         _DestroyMdl(mdl);
     }
 
     /* Return the status. */
-    gcmkFOOTER();
+    gcmkFOOTER_ARG("*Physical=%p", *Physical);
     return status;
 }
 
 gceSTATUS
 gckOS_GetPolicyID(
     IN gckOS Os,
-    IN gceSURF_TYPE Type,
+    IN gceVIDMEM_TYPE Type,
     OUT gctUINT32_PTR PolicyID,
     OUT gctUINT32_PTR AXIConfig
     )
 {
     gcsPLATFORM * platform = Os->device->platform;
+    gceSTATUS status = (platform && platform->ops->getPolicyID)
+                     ? platform->ops->getPolicyID(platform, Type, PolicyID, AXIConfig)
+                     : gcvSTATUS_NOT_SUPPORTED;
 
-    if (platform && platform->ops->getPolicyID)
-    {
-        return platform->ops->getPolicyID(platform, Type, PolicyID, AXIConfig);
-    }
-
-    return gcvSTATUS_NOT_SUPPORTED;
+    return status;
 }
 
index 6f63109..baa5c9c 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -84,11 +84,10 @@ struct _LINUX_MDL
 
     /* Size and covered page count. */
     size_t                  bytes;
-    gctINT                  numPages;
+    size_t                  numPages;
 
     gctBOOL                 contiguous;
     dma_addr_t              dmaHandle;
-
     gctBOOL                 cacheable;
 
     struct mutex            mapsMutex;
@@ -103,6 +102,8 @@ struct _LINUX_MDL
     uint                    gid;
 
     struct list_head        link;
+
+    gctBOOL                 pageUnit1M;
 };
 
 extern PLINUX_MDL_MAP
index b570195..01803f7 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 
 typedef struct _gcsMODULE_PARAMETERS
 {
-    gctINT  irqLine;
-    gctUINT registerMemBase;
-    gctUINT registerMemSize;
-    gctINT  irqLine2D;
-    gctUINT registerMemBase2D;
-    gctUINT registerMemSize2D;
-    gctINT  irqLineVG;
-    gctUINT registerMemBaseVG;
-    gctUINT registerMemSizeVG;
-    gctUINT contiguousSize;
-    gctUINT contiguousBase;
-    gctUINT contiguousRequested;
-    gctUINT externalSize;
-    gctUINT externalBase;
-    gctUINT bankSize;
-    gctINT  fastClear;
-    gceCOMPRESSION_OPTION compression;
-    gctINT  powerManagement;
-    gctINT  gpuProfiler;
-    gctINT  signal;
-    gctUINT baseAddress;
-    gctUINT physSize;
-    gctUINT logFileSize;
-    gctUINT recovery;
-    gctUINT stuckDump;
-    gctUINT showArgs;
-    gctUINT gpu3DMinClock;
-    gctBOOL registerMemMapped;
-    gctPOINTER registerMemAddress;
-    gctINT  irqs[gcvCORE_COUNT];
-    gctUINT registerBases[gcvCORE_COUNT];
-    gctUINT registerSizes[gcvCORE_COUNT];
-    gctUINT chipIDs[gcvCORE_COUNT];
+    gctINT                  irqs[gcvCORE_COUNT];
+    gctPHYS_ADDR_T          registerBases[gcvCORE_COUNT];
+    gctSIZE_T               registerSizes[gcvCORE_COUNT];
+    gctINT                  bars[gcvCORE_COUNT];
+
+    gctPOINTER              registerBasesMapped[gcvCORE_COUNT];
+
+    gctUINT                 chipIDs[gcvCORE_COUNT];
+
+    /* Contiguous memory pool. */
+    gctPHYS_ADDR_T          contiguousBase;
+    gctSIZE_T               contiguousSize;
+    gctBOOL                 contiguousRequested;
+
+    /* External memory pool. */
+    gctPHYS_ADDR_T          externalBase;
+    gctSIZE_T               externalSize;
+
+    /* SRAM. */
+    gctPHYS_ADDR_T          sRAMBases[gcvCORE_COUNT][gcvSRAM_COUNT];
+    gctUINT32               sRAMSizes[gcvCORE_COUNT][gcvSRAM_COUNT];
+    gctUINT32               sRAMMode;
+
+    gctPHYS_ADDR_T          baseAddress;
+    gctSIZE_T               physSize;
+    gctSIZE_T               bankSize;
+
+    gctUINT                 recovery;
+    gctINT                  powerManagement;
+
+    gctINT                  enableMmu;
+    gctINT                  fastClear;
+    gceCOMPRESSION_OPTION   compression;
+    gctUINT                 gpu3DMinClock;
+    gctUINT                 userClusterMask;
+    gctUINT                 smallBatch;
+
+    /* Debug or other information. */
+    gctUINT                 stuckDump;
+    gctINT                  gpuProfiler;
+
+    /* device type, 0 for char device, 1 for misc device. */
+    gctUINT                 deviceType;
+    gctUINT                 showArgs;
 }
 gcsMODULE_PARAMETERS;
 
-typedef struct soc_platform gcsPLATFORM;
+typedef struct _gcsPLATFORM gcsPLATFORM;
 
-typedef struct soc_platform_ops
+typedef struct _gcsPLATFORM_OPERATIONS
 {
 
     /*******************************************************************************
@@ -222,7 +233,7 @@ typedef struct soc_platform_ops
     gceSTATUS
     (*getCPUPhysical)(
         IN gcsPLATFORM * Platform,
-        IN gctUINT32 GPUPhysical,
+        IN gctPHYS_ADDR_T GPUPhysical,
         OUT gctPHYS_ADDR_T * CPUPhysical
         );
 
@@ -248,23 +259,6 @@ typedef struct soc_platform_ops
         IN gcsPLATFORM * Platform
         );
 
-    /*******************************************************************************
-    **
-    **  cache
-    **
-    **  Cache operation.
-    */
-    gceSTATUS
-    (*cache)(
-        IN gcsPLATFORM * Platform,
-        IN gctUINT32 ProcessID,
-        IN gctPHYS_ADDR Handle,
-        IN gctUINT32 Physical,
-        IN gctPOINTER Logical,
-        IN gctSIZE_T Bytes,
-        IN gceCACHEOPERATION Operation
-        );
-
     /*******************************************************************************
     **
     ** getPolicyID
@@ -273,35 +267,29 @@ typedef struct soc_platform_ops
     */
     gceSTATUS
     (*getPolicyID)(
-        IN gcsPLATFORM * Platform,
-        IN gceSURF_TYPE Type,
+        IN gcsPLATFORM *Platform,
+        IN gceVIDMEM_TYPE Type,
         OUT gctUINT32_PTR PolicyID,
         OUT gctUINT32_PTR AXIConfig
         );
 }
 gcsPLATFORM_OPERATIONS;
 
-struct soc_platform
+struct _gcsPLATFORM
 {
-#if USE_LINUX_PCIE
-    struct pci_dev* device;
-    struct pci_driver* driver;
-#else
-    struct platform_device* device;
-    struct platform_driver* driver;
-#endif
+    struct platform_device *device;
+    struct platform_driver *driver;
 
     const char *name;
     gcsPLATFORM_OPERATIONS* ops;
+
     /* PLATFORM specific flags */
     gctUINT32  flagBits;
+
+    void*                   priv;
 };
 
-#if USE_LINUX_PCIE
-int soc_platform_init(struct pci_driver *pdrv, gcsPLATFORM **platform);
-#else
-int soc_platform_init(struct platform_driver *pdrv, gcsPLATFORM **platform);
-#endif
-int soc_platform_terminate(gcsPLATFORM *platform);
+int gckPLATFORM_Init(struct platform_driver *pdrv, gcsPLATFORM **platform);
+int gckPLATFORM_Terminate(gcsPLATFORM *platform);
 
 #endif
index d0969ff..4bacdaf 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -99,10 +99,10 @@ gpu3d_allocate_secure_mem(
 
     memset(shm, 0, sizeof(TEEC_SharedMemory));
 
-    status = gckOS_AllocatePagedMemoryEx(
+    status = gckOS_AllocatePagedMemory(
                 Os,
                 gcvALLOC_FLAG_SECURITY,
-                bytes,
+                &bytes,
                 gcvNULL,
                 (gctPHYS_ADDR *)&handle);
 
@@ -112,7 +112,7 @@ gpu3d_allocate_secure_mem(
          return NULL;
     }
 
-    status = gckOS_PhysicalToPhysicalAddress(
+    status = gckOS_GetPhysicalFromHandle(
                 Os,
                 handle,
                 0,
index c0b17ce..135c135 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index b366a2f..c1367bc 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -366,8 +366,6 @@ struct dma_fence * viv_fence_create(struct viv_sync_timeline *timeline,
         fence->signal = NULL;
 
         dma_fence_signal_locked((struct dma_fence*)fence);
-        dma_fence_put((struct dma_fence*)fence);
-        fence = NULL;
     }
 
     return (struct dma_fence*)fence;
index d723e46..f83822d 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 1f522b6..7c9897a 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 #include "gc_hal_kernel_linux.h"
 #include "gc_hal_kernel_platform.h"
 
+/* Disable MSI for internal FPGA build except PPC */
+#if gcdFPGA_BUILD && !defined(CONFIG_PPC)
+#define USE_MSI     0
+#else
+#define USE_MSI     1
+#endif
+
+gceSTATUS
+_AdjustParam(
+    IN gcsPLATFORM *Platform,
+    OUT gcsMODULE_PARAMETERS *Args
+    );
+
+static struct _gcsPLATFORM_OPERATIONS default_ops =
+{
+    .adjustParam   = _AdjustParam,
+};
+
+#if USE_LINUX_PCIE
+
+#define MAX_PCIE_DEVICE 4
+#define MAX_PCIE_BAR    6
+
+struct _gcsPCIEInfo
+{
+    gctPOINTER bar[MAX_PCIE_BAR];
+    struct pci_dev *pdev;
+};
+
+struct _gcsPLATFORM_PCIE
+{
+    struct _gcsPLATFORM base;
+    struct _gcsPCIEInfo pcieInfo[MAX_PCIE_DEVICE];
+    unsigned int device_number;
+};
+
+
+struct _gcsPLATFORM_PCIE default_platform =
+{
+    .base =
+    {
+        .name = __FILE__,
+        .ops  = &default_ops,
+    },
+};
+
+#else
+
+static struct _gcsPLATFORM default_platform =
+{
+    .name = __FILE__,
+    .ops  = &default_ops,
+};
+#endif
 
 gceSTATUS
 _AdjustParam(
@@ -64,51 +118,114 @@ _AdjustParam(
     )
 {
 #if USE_LINUX_PCIE
-    struct pci_dev *pdev = Platform->device;
+    struct _gcsPLATFORM_PCIE *pcie_platform = (struct _gcsPLATFORM_PCIE *)Platform;
+    struct pci_dev *pdev = pcie_platform->pcieInfo[0].pdev;
     unsigned char   irqline = pdev->irq;
+    unsigned int i;
+    unsigned int devIndex, coreIndex = 0;
 
-    if ((Args->irqLine2D != -1) && (Args->irqLine2D != irqline))
+    if (Args->irqs[gcvCORE_2D] != -1)
     {
-        Args->irqLine2D = irqline;
+        Args->irqs[gcvCORE_2D] = irqline;
     }
-    if ((Args->irqLine != -1) && (Args->irqLine != irqline))
+    if (Args->irqs[gcvCORE_MAJOR] != -1)
     {
-        Args->irqLine = irqline;
+        Args->irqs[gcvCORE_MAJOR] = irqline;
     }
+    for (devIndex = 0; devIndex < pcie_platform->device_number; devIndex++)
+    {
+        struct pci_dev * pcieDev = pcie_platform->pcieInfo[devIndex].pdev;
+        for (i = 0; i < gcvCORE_COUNT; i++)
+        {
+            if (Args->bars[i] != -1)
+            {
+                Args->irqs[coreIndex] = pcieDev->irq;
+                Args->registerBasesMapped[coreIndex]    =
+                pcie_platform->pcieInfo[devIndex].bar[i] =
+                    (gctPOINTER)pci_iomap(pcieDev, Args->bars[i], Args->registerSizes[coreIndex]);
+                coreIndex++;
+            }
+        }
+    }
+    Args->contiguousRequested = gcvTRUE;
 #endif
     return gcvSTATUS_OK;
 }
 
-static struct soc_platform_ops default_ops =
-{
-    .adjustParam   = _AdjustParam,
-};
 
-static struct soc_platform default_platform =
-{
-    .name = __FILE__,
-    .ops  = &default_ops,
+#if USE_LINUX_PCIE
+static const struct pci_device_id vivpci_ids[] = {
+  {
+    .class = 0x000000,
+    .class_mask = 0x000000,
+    .vendor = 0x10ee,
+    .device = 0x7012,
+    .subvendor = PCI_ANY_ID,
+    .subdevice = PCI_ANY_ID,
+    .driver_data = 0
+  }, { /* End: all zeroes */ }
 };
 
-#if USE_LINUX_PCIE
+MODULE_DEVICE_TABLE(pci, vivpci_ids);
+
 
-int soc_platform_init(struct pci_driver *pdrv,
-            struct soc_platform **platform)
+static int gpu_sub_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-    *platform = &default_platform;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
+    static u64 dma_mask = DMA_BIT_MASK(40);
+#else
+    static u64 dma_mask = DMA_40BIT_MASK;
+#endif
+
+    gcmkPRINT("PCIE DRIVER PROBED");
+    if (pci_enable_device(pdev)) {
+        printk(KERN_ERR "galcore: pci_enable_device() failed.\n");
+    }
+
+    if (pci_set_dma_mask(pdev, dma_mask)) {
+        printk(KERN_ERR "galcore: Failed to set DMA mask.\n");
+    }
+
+    pci_set_master(pdev);
+
+    if (pci_request_regions(pdev, "galcore")) {
+        printk(KERN_ERR "galcore: Failed to get ownership of BAR region.\n");
+    }
+
+#if USE_MSI
+    if (pci_enable_msi(pdev)) {
+        printk(KERN_ERR "galcore: Failed to enable MSI.\n");
+    }
+#endif
+    default_platform.pcieInfo[default_platform.device_number++].pdev = pdev;
     return 0;
 }
 
-int soc_platform_terminate(struct soc_platform *platform)
+static void gpu_sub_remove(struct pci_dev *pdev)
 {
-    return 0;
+    pci_set_drvdata(pdev, NULL);
+#if USE_MSI
+    pci_disable_msi(pdev);
+#endif
+    pci_clear_master(pdev);
+    pci_release_regions(pdev);
+    pci_disable_device(pdev);
+    return;
 }
 
-#else
+static struct pci_driver gpu_pci_subdriver = {
+    .name = DEVICE_NAME,
+    .id_table = vivpci_ids,
+    .probe = gpu_sub_probe,
+    .remove = gpu_sub_remove
+};
+
+#endif
+
 static struct platform_device *default_dev;
 
-int soc_platform_init(struct platform_driver *pdrv,
-            struct soc_platform **platform)
+int gckPLATFORM_Init(struct platform_driver *pdrv,
+            struct _gcsPLATFORM **platform)
 {
     int ret;
     default_dev = platform_device_alloc(pdrv->driver.name, -1);
@@ -125,7 +242,12 @@ int soc_platform_init(struct platform_driver *pdrv,
         goto put_dev;
     }
 
-    *platform = &default_platform;
+    *platform = (gcsPLATFORM *)&default_platform;
+
+#if USE_LINUX_PCIE
+    ret = pci_register_driver(&gpu_pci_subdriver);
+#endif
+
     return 0;
 
 put_dev:
@@ -134,13 +256,32 @@ put_dev:
     return ret;
 }
 
-int soc_platform_terminate(struct soc_platform *platform)
+int gckPLATFORM_Terminate(struct _gcsPLATFORM *platform)
 {
     if (default_dev) {
         platform_device_unregister(default_dev);
         default_dev = NULL;
     }
 
+#if USE_LINUX_PCIE
+    {
+        unsigned int devIndex;
+        struct _gcsPLATFORM_PCIE *pcie_platform = (struct _gcsPLATFORM_PCIE *)platform;
+        for (devIndex = 0; devIndex < pcie_platform->device_number; devIndex++)
+        {
+            unsigned int i;
+            for (i = 0; i < MAX_PCIE_BAR; i++)
+            {
+                if (pcie_platform->pcieInfo[devIndex].bar[i] != 0)
+                {
+                    pci_iounmap(pcie_platform->pcieInfo[devIndex].pdev, pcie_platform->pcieInfo[devIndex]. bar[i]);
+                }
+            }
+        }
+
+        pci_unregister_driver(&gpu_pci_subdriver);
+    }
+#endif
+
     return 0;
 }
-#endif
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.config b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/default/gc_hal_kernel_platform_default.config
new file mode 100644 (file)
index 0000000..cef4f6f
--- /dev/null
@@ -0,0 +1,3 @@
+ifeq ($(USE_LINUX_PCIE), 1)
+EXTRA_CFLAGS +=-DgcdIRQ_SHARED
+endif
index a64004e..9c45dca 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -88,7 +88,9 @@
 #    include <linux/busfreq-imx6.h>
 #    include <linux/reset.h>
 #  else
-#    include <linux/busfreq-imx.h>
+#if !defined(IMX8_SCU_CONTROL)
+#      include <linux/busfreq-imx.h>
+#    endif
 #    include <linux/reset.h>
 #  endif
 #endif
@@ -136,93 +138,114 @@ struct platform_device *pdevice;
 #  include <linux/sched.h>
 #  include <linux/profile.h>
 
-static unsigned long timeout;
-struct task_struct *almostfail;
+struct task_struct *lowmem_deathpending;
 
 static int
-notif_func(struct notifier_block *self, unsigned long val, void *data)
+task_notify_func(struct notifier_block *self, unsigned long val, void *data);
+
+static struct notifier_block task_nb = {
+    .notifier_call  = task_notify_func,
+};
+
+static int
+task_notify_func(struct notifier_block *self, unsigned long val, void *data)
 {
     struct task_struct *task = data;
 
-    if (task == almostfail)
-        almostfail = NULL;
+    if (task == lowmem_deathpending)
+        lowmem_deathpending = NULL;
 
     return NOTIFY_DONE;
 }
 
-static struct notifier_block task_nb = {
-    .notifier_call  = notif_func,
-};
+extern struct task_struct *lowmem_deathpending;
+static unsigned long lowmem_deathpending_timeout;
 
-static int force_shrink_mem(IN gckKERNEL Kernel)
+static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel)
 {
-    struct task_struct *p = NULL;
+    struct task_struct *p;
     struct task_struct *selected = NULL;
-    int cur_size = 0;
-    int set_size = 0;
-    int oom_val = 0;
-    int mem_adj = 0;
-    int retVal = -1;
-
-    if (almostfail && time_before_eq(jiffies, timeout))
+    int tasksize;
+        int ret = -1;
+    int min_adj = 0;
+    int selected_tasksize = 0;
+    int selected_oom_adj;
+    /*
+     * If we already have a death outstanding, then
+     * bail out right away; indicating to vmscan
+     * that we have nothing further to offer on
+     * this pass.
+     *
+     */
+    if (lowmem_deathpending &&
+        time_before_eq(jiffies, lowmem_deathpending_timeout))
         return 0;
+    selected_oom_adj = min_adj;
 
     rcu_read_lock();
 
     for_each_process(p) {
-        gcuDATABASE_INFO info;
         struct mm_struct *mm;
         struct signal_struct *sig;
-
-        cur_size = 0;
+                gcuDATABASE_INFO info;
+        int oom_adj;
 
         task_lock(p);
-        sig = p->signal;
         mm = p->mm;
-        if (!sig || !mm) {
+        sig = p->signal;
+
+        if (!mm || !sig) {
             task_unlock(p);
             continue;
         }
-        oom_val = sig->oom_score_adj;
-        if (oom_val < 0) {
+
+        oom_adj = sig->oom_score_adj;
+
+        if (oom_adj < min_adj) {
             task_unlock(p);
             continue;
         }
+
+        tasksize = 0;
         task_unlock(p);
 
         rcu_read_unlock();
-        if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK){
-            cur_size += info.counters.bytes / PAGE_SIZE;
-        }
-        if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_CONTIGUOUS, &info) == gcvSTATUS_OK){
-            cur_size += info.counters.bytes / PAGE_SIZE;
+
+        if (gckKERNEL_QueryProcessDB(Kernel, p->pid, gcvFALSE, gcvDB_VIDEO_MEMORY, &info) == gcvSTATUS_OK) {
+            tasksize += info.counters.bytes / PAGE_SIZE;
         }
+
         rcu_read_lock();
 
-        if (cur_size <= 0) continue;
+        if (tasksize <= 0)
+            continue;
 
-        printk("<gpu> pid %d (%s), adj %d, size %d\n", p->pid, p->comm, oom_val, cur_size);
+        printk("<gpu> pid %d (%s), adj %d, size %d \n", p->pid, p->comm, oom_adj, tasksize);
 
         if (selected) {
-            if ((oom_val < mem_adj) || (oom_val == mem_adj && cur_size <= set_size)) continue;
+            if (oom_adj < selected_oom_adj)
+                continue;
+            if (oom_adj == selected_oom_adj &&
+                tasksize <= selected_tasksize)
+                continue;
         }
-        set_size = cur_size;
-        mem_adj = oom_val;
         selected = p;
+        selected_tasksize = tasksize;
+        selected_oom_adj = oom_adj;
     }
 
-    if (selected && mem_adj > 0) {
+    if (selected && selected_oom_adj > 0) {
         printk("<gpu> send sigkill to %d (%s), adj %d, size %d\n",
-                 selected->pid, selected->comm, mem_adj, set_size);
-        almostfail = selected;
-        timeout = jiffies + HZ;
+                 selected->pid, selected->comm,
+                 selected_oom_adj, selected_tasksize);
+        lowmem_deathpending = selected;
+        lowmem_deathpending_timeout = jiffies + HZ;
         force_sig(SIGKILL, selected);
-        retVal = 0;
+        ret = 0;
     }
 
     rcu_read_unlock();
-
-    return retVal;
+    return ret;
 }
 
 extern gckKERNEL
@@ -248,7 +271,7 @@ _ShrinkMemory(
 
     if (kernel != gcvNULL)
     {
-        if (force_shrink_mem(kernel) != 0)
+        if (force_contiguous_lowmem_shrink(kernel) != 0)
             status = gcvSTATUS_OUT_OF_MEMORY;
     }
     else
@@ -345,11 +368,13 @@ static ssize_t gpu3DMinClock_store(struct device_driver *dev, const char *buf, s
 
     return count;
 }
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
 static DRIVER_ATTR_RW(gpu3DMinClock);
 #else
 static DRIVER_ATTR(gpu3DMinClock, S_IRUGO | S_IWUSR, gpu3DMinClock_show, gpu3DMinClock_store);
 #endif
+
 #endif
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
@@ -503,6 +528,7 @@ static ssize_t gpu_govern_store(struct device_driver *dev, const char *buf, size
 
     return count;
 }
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
 static DRIVER_ATTR_RW(gpu_govern);
 #else
@@ -678,8 +704,7 @@ static int mxc_gpu_sub_bind(struct device *dev,
     return 0;
 }
 
-static void mxc_gpu_sub_unbind(struct device *dev, struct device *master,
-    void *data)
+static void mxc_gpu_sub_unbind(struct device *dev, struct device *master, void *data)
 {
 }
 
@@ -895,37 +920,37 @@ static int patch_param_imx6(struct platform_device *pdev,
     res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_3d");
 
     if (res)
-        args->irqLine = res->start;
+        args->irqs[gcvCORE_MAJOR] = res->start;
 
     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_3d");
 
     if (res) {
-        args->registerMemBase = res->start;
-        args->registerMemSize = res->end - res->start + 1;
+        args->registerBases[gcvCORE_MAJOR] = res->start;
+        args->registerSizes[gcvCORE_MAJOR] = res->end - res->start + 1;
     }
 
     res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_2d");
 
     if (res)
-        args->irqLine2D = res->start;
+        args->irqs[gcvCORE_2D] = res->start;
 
     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_2d");
 
     if (res) {
-        args->registerMemBase2D = res->start;
-        args->registerMemSize2D = res->end - res->start + 1;
+        args->registerBases[gcvCORE_2D] = res->start;
+        args->registerSizes[gcvCORE_2D] = res->end - res->start + 1;
     }
 
     res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq_vg");
 
     if (res)
-        args->irqLineVG = res->start;
+        args->irqs[gcvCORE_VG] = res->start;
 
     res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "iobase_vg");
 
     if (res) {
-        args->registerMemBaseVG = res->start;
-        args->registerMemSizeVG = res->end - res->start + 1;
+        args->registerBases[gcvCORE_VG] = res->start;
+        args->registerSizes[gcvCORE_VG] = res->end - res->start + 1;
     }
 
     return 0;
@@ -1419,6 +1444,7 @@ int set_clock(int gpu, int enable)
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
 #ifdef CONFIG_PM
+#ifdef CONFIG_PM_RUNTIME
 static int gpu_runtime_suspend(struct device *dev)
 {
     release_bus_freq(BUS_FREQ_HIGH);
@@ -1430,6 +1456,7 @@ static int gpu_runtime_resume(struct device *dev)
     request_bus_freq(BUS_FREQ_HIGH);
     return 0;
 }
+#endif
 
 static struct dev_pm_ops gpu_pm_ops;
 #endif
@@ -1449,7 +1476,7 @@ static int adjust_platform_driver(struct platform_driver *driver)
     memcpy(&gpu_pm_ops, driver->driver.pm, sizeof(struct dev_pm_ops));
 
     /* Add runtime PM callback. */
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_RUNTIME
     gpu_pm_ops.runtime_suspend = gpu_runtime_suspend;
     gpu_pm_ops.runtime_resume = gpu_runtime_resume;
     gpu_pm_ops.runtime_idle = NULL;
@@ -1586,7 +1613,7 @@ _Reset(
         return gcvSTATUS_INVALID_CONFIG;
 }
 
-struct soc_platform_ops imx_platform_ops =
+struct _gcsPLATFORM_OPERATIONS imx_platform_ops =
 {
     .adjustParam  = _AdjustParam,
     .getPower     = _GetPower,
@@ -1599,23 +1626,23 @@ struct soc_platform_ops imx_platform_ops =
 #endif
 };
 
-static struct soc_platform imx_platform =
+static struct _gcsPLATFORM imx_platform =
 {
     .name = __FILE__,
     .ops  = &imx_platform_ops,
 };
 
-int soc_platform_init(struct platform_driver *pdrv,
-            struct soc_platform **platform)
+int gckPLATFORM_Init(struct platform_driver *pdrv,
+            struct _gcsPLATFORM **platform)
 {
 #ifdef IMX_GPU_SUBSYSTEM
     if (of_find_compatible_node(NULL, NULL, "fsl,imx8-gpu-ss")) {
         use_imx_gpu_subsystem = 1;
-    }
 
-    if (of_find_compatible_node(NULL, NULL, "fsl,imx8x-gpu")) {
-        printk(KERN_ERR "Incorrect device-tree, please update dtb.");
-        return -EINVAL;
+        if (!of_find_compatible_node(NULL, NULL, "fsl,imx8-gpu")) {
+            printk(KERN_ERR "Incorrect device-tree, please update dtb.");
+            return -EINVAL;
+        }
     }
 #endif
 
@@ -1630,12 +1657,11 @@ int soc_platform_init(struct platform_driver *pdrv,
     return 0;
 }
 
-int soc_platform_terminate(struct soc_platform *platform)
+int gckPLATFORM_Terminate(struct _gcsPLATFORM *platform)
 {
 #ifdef IMX_GPU_SUBSYSTEM
     unregister_mxc_gpu_sub_driver();
 #endif
-
     free_priv();
     return 0;
 }
index 7b677e4..c7dd9e7 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index a29513b..8d00456 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index b5369bd..8fb08a7 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -196,7 +196,6 @@ _IdentifyHardwareByDatabase(
                   Hardware->customerID);
         gcmkONERROR(gcvSTATUS_NOT_FOUND);
     }
-
     /* Success. */
     gcmkFOOTER();
     return gcvSTATUS_OK;
@@ -678,7 +677,7 @@ gctaHARDWARE_SetMMU(
     gctaOS_WriteRegister(
         Hardware->ta->os, Hardware->ta->core,
         0x003A0,
-        (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  23:16) - (0 ?
  23:16) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -687,10 +686,8 @@ gctaHARDWARE_SetMMU(
  23:16))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)((secureSafeAddress >> 32) & 0xFFFFFFFF)) & ((gctUINT32) ((((1 ?
  23:16) - (0 ?
  23:16) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 23:16) - (0 ?
- 23:16) + 1))))))) << (0 ?
- 23:16))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 23:16) - (0 ? 23:16) + 1))))))) << (0 ? 23:16)))
+      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  31:31) - (0 ?
  31:31) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -699,20 +696,18 @@ gctaHARDWARE_SetMMU(
  31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  31:31) - (0 ?
  31:31) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))))
-      | (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
+      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  7:0) - (0 ?
  7:0) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
  7:0) - (0 ?
  7:0) + 1))))))) << (0 ?
- 7:0))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)((nonSecureSafeAddress >> 32) & 0xFFFFFFFF)) & ((gctUINT32) ((((1 ?
+ 7:0))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)((secureSafeAddress >> 32) & 0xFFFFFFFF)) & ((gctUINT32) ((((1 ?
  7:0) - (0 ?
  7:0) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ?
- 7:0) - (0 ?
- 7:0) + 1))))))) << (0 ?
- 7:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
+ ~0U : (~(~0U << ((1 ? 7:0) - (0 ? 7:0) + 1))))))) << (0 ? 7:0)))
+      | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
  15:15) - (0 ?
  15:15) + 1) == 32) ?
  ~0U : (~(~0U << ((1 ?
@@ -721,7 +716,7 @@ gctaHARDWARE_SetMMU(
  15:15))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
  15:15) - (0 ?
  15:15) + 1) == 32) ?
- ~0U : (~(~0U << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))))
+ ~0U : (~(~0U << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15)))
         );
 
     /* Execute prepared command sequence. */
index 2ae926a..6e7c8bd 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
index 396712e..8cad46c 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
 /* Page offset definitions. */
 #define gcdMMU_OFFSET_4K_BITS       (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_4K_BITS)
 #define gcdMMU_OFFSET_4K_MASK       ((1U << gcdMMU_OFFSET_4K_BITS) - 1)
-#define gcdMMU_OFFSET_16K_BITS      (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_16K_BITS)
-#define gcdMMU_OFFSET_16K_MASK      ((1U << gcdMMU_OFFSET_16K_BITS) - 1)
+#define gcdMMU_OFFSET_64K_BITS      (32 - gcdMMU_MTLB_BITS - gcdMMU_STLB_64K_BITS)
+#define gcdMMU_OFFSET_64K_MASK      ((1U << gcdMMU_OFFSET_64K_BITS) - 1)
 
 #define gcdMMU_MTLB_PRESENT         0x00000001
 #define gcdMMU_MTLB_EXCEPTION       0x00000002
-#define gcdMMU_MTLB_4K_PAGE         0x00000000
+#define gcdMMU_MTLB_4K_PAGE         (0 << 2)
 
 #define gcdMMU_STLB_PRESENT         0x00000001
 #define gcdMMU_STLB_EXCEPTION       0x00000002
 #define gcdMMU_STLB_SECURITY        (1 << 4)
-#define gcdMMU_STLB_4K_PAGE         0x00000000
 
 #define gcdUSE_MMU_EXCEPTION        1
 
index 07f21b1..c333947 100644 (file)
@@ -2,7 +2,7 @@
 *
 *    The MIT License (MIT)
 *
-*    Copyright (c) 2014 - 2018 Vivante Corporation
+*    Copyright (c) 2014 - 2019 Vivante Corporation
 *
 *    Permission is hereby granted, free of charge, to any person obtaining a
 *    copy of this software and associated documentation files (the "Software"),
@@ -26,7 +26,7 @@
 *
 *    The GPL License (GPL)
 *
-*    Copyright (C) 2014 - 2018 Vivante Corporation
+*    Copyright (C) 2014 - 2019 Vivante Corporation
 *
 *    This program is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU General Public License
@@ -152,7 +152,7 @@ gctaOS_FreeSecurityMemory(
     OUT gctPOINTER Physical
     )
 {
-    gckOS_FreeNonPagedMemory(Os->os, Bytes, (gctPHYS_ADDR)Physical, Logical);
+    gckOS_FreeNonPagedMemory(Os->os, (gctPHYS_ADDR)Physical, Logical, Bytes);
     return gcvSTATUS_OK;
 }
 
@@ -182,7 +182,7 @@ gctaOS_FreeNonSecurityMemory(
     OUT gctPOINTER Physical
     )
 {
-    gckOS_FreeNonPagedMemory(Os->os, Bytes, (gctPHYS_ADDR)Physical, Logical);
+    gckOS_FreeNonPagedMemory(Os->os, (gctPHYS_ADDR)Physical, Logical, Bytes);
     return gcvSTATUS_OK;
 }