]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'drm-next' of git://people.freedesktop.org/~robclark/linux into drm...
authorDave Airlie <airlied@redhat.com>
Wed, 28 Aug 2013 04:27:15 +0000 (14:27 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 28 Aug 2013 04:27:15 +0000 (14:27 +1000)
Merge the MSM driver from Rob Clark
* 'drm-next' of git://people.freedesktop.org/~robclark/linux:
  drm/msm: add basic hangcheck/recovery mechanism
  drm/msm: add a3xx gpu support
  drm/msm: add register definitions for gpu
  drm/msm: basic KMS driver for snapdragon
  drm/msm: add register definitions

47 files changed:
drivers/gpu/drm/Kconfig
drivers/gpu/drm/Makefile
drivers/gpu/drm/msm/Kconfig [new file with mode: 0644]
drivers/gpu/drm/msm/Makefile [new file with mode: 0644]
drivers/gpu/drm/msm/NOTES [new file with mode: 0644]
drivers/gpu/drm/msm/adreno/a2xx.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/adreno/a3xx.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/adreno/a3xx_gpu.c [new file with mode: 0644]
drivers/gpu/drm/msm/adreno/a3xx_gpu.h [new file with mode: 0644]
drivers/gpu/drm/msm/adreno/adreno_common.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/adreno/adreno_gpu.c [new file with mode: 0644]
drivers/gpu/drm/msm/adreno/adreno_gpu.h [new file with mode: 0644]
drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/dsi/dsi.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/dsi/mmss_cc.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/dsi/sfpb.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/hdmi/hdmi.c [new file with mode: 0644]
drivers/gpu/drm/msm/hdmi/hdmi.h [new file with mode: 0644]
drivers/gpu/drm/msm/hdmi/hdmi.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/hdmi/hdmi_connector.c [new file with mode: 0644]
drivers/gpu/drm/msm/hdmi/hdmi_i2c.c [new file with mode: 0644]
drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c [new file with mode: 0644]
drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c [new file with mode: 0644]
drivers/gpu/drm/msm/hdmi/qfprom.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/mdp4/mdp4.xml.h [new file with mode: 0644]
drivers/gpu/drm/msm/mdp4/mdp4_crtc.c [new file with mode: 0644]
drivers/gpu/drm/msm/mdp4/mdp4_dtv_encoder.c [new file with mode: 0644]
drivers/gpu/drm/msm/mdp4/mdp4_format.c [new file with mode: 0644]
drivers/gpu/drm/msm/mdp4/mdp4_irq.c [new file with mode: 0644]
drivers/gpu/drm/msm/mdp4/mdp4_kms.c [new file with mode: 0644]
drivers/gpu/drm/msm/mdp4/mdp4_kms.h [new file with mode: 0644]
drivers/gpu/drm/msm/mdp4/mdp4_plane.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_connector.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_connector.h [new file with mode: 0644]
drivers/gpu/drm/msm/msm_drv.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_drv.h [new file with mode: 0644]
drivers/gpu/drm/msm/msm_fb.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_fbdev.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_gem.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_gem.h [new file with mode: 0644]
drivers/gpu/drm/msm/msm_gem_submit.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_gpu.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_gpu.h [new file with mode: 0644]
drivers/gpu/drm/msm/msm_ringbuffer.c [new file with mode: 0644]
drivers/gpu/drm/msm/msm_ringbuffer.h [new file with mode: 0644]
include/uapi/drm/Kbuild
include/uapi/drm/msm_drm.h [new file with mode: 0644]

index 626bc0cb1046b97062fd0fff0fca1d67c835c195..39573c5f7518881392732e68db6f7c4c72bbf262 100644 (file)
@@ -223,3 +223,5 @@ source "drivers/gpu/drm/omapdrm/Kconfig"
 source "drivers/gpu/drm/tilcdc/Kconfig"
 
 source "drivers/gpu/drm/qxl/Kconfig"
+
+source "drivers/gpu/drm/msm/Kconfig"
index 7b2343a2f5ebd5d9648dfccf59e05b4565bb9c8f..f089adfe70eed3daa21f08b81fcb6d9911ea45c6 100644 (file)
@@ -54,4 +54,5 @@ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)       += tilcdc/
 obj-$(CONFIG_DRM_QXL) += qxl/
+obj-$(CONFIG_DRM_MSM) += msm/
 obj-y                  += i2c/
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
new file mode 100644 (file)
index 0000000..a06c19c
--- /dev/null
@@ -0,0 +1,34 @@
+
+config DRM_MSM
+       tristate "MSM DRM"
+       depends on DRM
+       depends on ARCH_MSM
+       depends on ARCH_MSM8960
+       select DRM_KMS_HELPER
+       select SHMEM
+       select TMPFS
+       default y
+       help
+         DRM/KMS driver for MSM/snapdragon.
+
+config DRM_MSM_FBDEV
+       bool "Enable legacy fbdev support for MSM modesetting driver"
+       depends on DRM_MSM
+       select FB_SYS_FILLRECT
+       select FB_SYS_COPYAREA
+       select FB_SYS_IMAGEBLIT
+       select FB_SYS_FOPS
+       default y
+       help
+         Choose this option if you have a need for the legacy fbdev
+         support. Note that this support also provide the linux console
+         support on top of the MSM modesetting driver.
+
+config DRM_MSM_REGISTER_LOGGING
+       bool "MSM DRM register logging"
+       depends on DRM_MSM
+       default n
+       help
+         Compile in support for logging register reads/writes in a format
+         that can be parsed by envytools demsm tool.  If enabled, register
+         logging can be switched on via msm.reglog=y module param.
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
new file mode 100644 (file)
index 0000000..439dfb5
--- /dev/null
@@ -0,0 +1,30 @@
+ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/msm
+ifeq (, $(findstring -W,$(EXTRA_CFLAGS)))
+       ccflags-y += -Werror
+endif
+
+msm-y := \
+       adreno/adreno_gpu.o \
+       adreno/a3xx_gpu.o \
+       hdmi/hdmi.o \
+       hdmi/hdmi_connector.o \
+       hdmi/hdmi_i2c.o \
+       hdmi/hdmi_phy_8960.o \
+       hdmi/hdmi_phy_8x60.o \
+       mdp4/mdp4_crtc.o \
+       mdp4/mdp4_dtv_encoder.o \
+       mdp4/mdp4_format.o \
+       mdp4/mdp4_irq.o \
+       mdp4/mdp4_kms.o \
+       mdp4/mdp4_plane.o \
+       msm_connector.o \
+       msm_drv.o \
+       msm_fb.o \
+       msm_gem.o \
+       msm_gem_submit.o \
+       msm_gpu.o \
+       msm_ringbuffer.o
+
+msm-$(CONFIG_DRM_MSM_FBDEV) += msm_fbdev.o
+
+obj-$(CONFIG_DRM_MSM)  += msm.o
diff --git a/drivers/gpu/drm/msm/NOTES b/drivers/gpu/drm/msm/NOTES
new file mode 100644 (file)
index 0000000..e036f6c
--- /dev/null
@@ -0,0 +1,69 @@
+NOTES about msm drm/kms driver:
+
+In the current snapdragon SoC's, we have (at least) 3 different
+display controller blocks at play:
+ + MDP3 - ?? seems to be what is on geeksphone peak device
+ + MDP4 - S3 (APQ8060, touchpad), S4-pro (APQ8064, nexus4 & ifc6410)
+ + MDSS - snapdragon 800
+
+(I don't have a completely clear picture on which display controller
+maps to which part #)
+
+Plus a handful of blocks around them for HDMI/DSI/etc output.
+
+And on gpu side of things:
+ + zero, one, or two 2d cores (z180)
+ + and either a2xx or a3xx 3d core.
+
+But, HDMI/DSI/etc blocks seem like they can be shared across multiple
+display controller blocks.  And I for sure don't want to have to deal
+with N different kms devices from xf86-video-freedreno.  Plus, it
+seems like we can do some clever tricks like use GPU to trigger
+pageflip after rendering completes (ie. have the kms/crtc code build
+up gpu cmdstream to update scanout and write FLUSH register after).
+
+So, the approach is one drm driver, with some modularity.  Different
+'struct msm_kms' implementations, depending on display controller.
+And one or more 'struct msm_gpu' for the various different gpu sub-
+modules.
+
+(Second part is not implemented yet.  So far this is just basic KMS
+driver, and not exposing any custom ioctls to userspace for now.)
+
+The kms module provides the plane, crtc, and encoder objects, and
+loads whatever connectors are appropriate.
+
+For MDP4, the mapping is:
+
+  plane   -> PIPE{RGBn,VGn}              \
+  crtc    -> OVLP{n} + DMA{P,S,E} (??)   |-> MDP "device"
+  encoder -> DTV/LCDC/DSI (within MDP4)  /
+  connector -> HDMI/DSI/etc              --> other device(s)
+
+Since the irq's that drm core mostly cares about are vblank/framedone,
+we'll let msm_mdp4_kms provide the irq install/uninstall/etc functions
+and treat the MDP4 block's irq as "the" irq.  Even though the connectors
+may have their own irqs which they install themselves.  For this reason
+the display controller is the "master" device.
+
+Each connector probably ends up being a separate device, just for the
+logistics of finding/mapping io region, irq, etc.  Idealy we would
+have a better way than just stashing the platform device in a global
+(ie. like DT super-node.. but I don't have any snapdragon hw yet that
+is using DT).
+
+Note that so far I've not been able to get any docs on the hw, and it
+seems that access to such docs would prevent me from working on the
+freedreno gallium driver.  So there may be some mistakes in register
+names (I had to invent a few, since no sufficient hint was given in
+the downstream android fbdev driver), bitfield sizes, etc.  My current
+state of understanding the registers is given in the envytools rnndb
+files at:
+
+  https://github.com/freedreno/envytools/tree/master/rnndb
+  (the mdp4/hdmi/dsi directories)
+
+These files are used both for a parser tool (in the same tree) to
+parse logged register reads/writes (both from downstream android fbdev
+driver, and this driver with register logging enabled), as well as to
+generate the register level headers.
diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h
new file mode 100644 (file)
index 0000000..3546386
--- /dev/null
@@ -0,0 +1,1438 @@
+#ifndef A2XX_XML
+#define A2XX_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml              (    327 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml           (  30005 bytes, from 2013-07-19 21:30:48)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml       (   8983 bytes, from 2013-07-24 01:38:36)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9712 bytes, from 2013-05-26 15:22:37)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51415 bytes, from 2013-08-03 14:26:05)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+enum a2xx_rb_dither_type {
+       DITHER_PIXEL = 0,
+       DITHER_SUBPIXEL = 1,
+};
+
+enum a2xx_colorformatx {
+       COLORX_4_4_4_4 = 0,
+       COLORX_1_5_5_5 = 1,
+       COLORX_5_6_5 = 2,
+       COLORX_8 = 3,
+       COLORX_8_8 = 4,
+       COLORX_8_8_8_8 = 5,
+       COLORX_S8_8_8_8 = 6,
+       COLORX_16_FLOAT = 7,
+       COLORX_16_16_FLOAT = 8,
+       COLORX_16_16_16_16_FLOAT = 9,
+       COLORX_32_FLOAT = 10,
+       COLORX_32_32_FLOAT = 11,
+       COLORX_32_32_32_32_FLOAT = 12,
+       COLORX_2_3_3 = 13,
+       COLORX_8_8_8 = 14,
+};
+
+enum a2xx_sq_surfaceformat {
+       FMT_1_REVERSE = 0,
+       FMT_1 = 1,
+       FMT_8 = 2,
+       FMT_1_5_5_5 = 3,
+       FMT_5_6_5 = 4,
+       FMT_6_5_5 = 5,
+       FMT_8_8_8_8 = 6,
+       FMT_2_10_10_10 = 7,
+       FMT_8_A = 8,
+       FMT_8_B = 9,
+       FMT_8_8 = 10,
+       FMT_Cr_Y1_Cb_Y0 = 11,
+       FMT_Y1_Cr_Y0_Cb = 12,
+       FMT_5_5_5_1 = 13,
+       FMT_8_8_8_8_A = 14,
+       FMT_4_4_4_4 = 15,
+       FMT_10_11_11 = 16,
+       FMT_11_11_10 = 17,
+       FMT_DXT1 = 18,
+       FMT_DXT2_3 = 19,
+       FMT_DXT4_5 = 20,
+       FMT_24_8 = 22,
+       FMT_24_8_FLOAT = 23,
+       FMT_16 = 24,
+       FMT_16_16 = 25,
+       FMT_16_16_16_16 = 26,
+       FMT_16_EXPAND = 27,
+       FMT_16_16_EXPAND = 28,
+       FMT_16_16_16_16_EXPAND = 29,
+       FMT_16_FLOAT = 30,
+       FMT_16_16_FLOAT = 31,
+       FMT_16_16_16_16_FLOAT = 32,
+       FMT_32 = 33,
+       FMT_32_32 = 34,
+       FMT_32_32_32_32 = 35,
+       FMT_32_FLOAT = 36,
+       FMT_32_32_FLOAT = 37,
+       FMT_32_32_32_32_FLOAT = 38,
+       FMT_32_AS_8 = 39,
+       FMT_32_AS_8_8 = 40,
+       FMT_16_MPEG = 41,
+       FMT_16_16_MPEG = 42,
+       FMT_8_INTERLACED = 43,
+       FMT_32_AS_8_INTERLACED = 44,
+       FMT_32_AS_8_8_INTERLACED = 45,
+       FMT_16_INTERLACED = 46,
+       FMT_16_MPEG_INTERLACED = 47,
+       FMT_16_16_MPEG_INTERLACED = 48,
+       FMT_DXN = 49,
+       FMT_8_8_8_8_AS_16_16_16_16 = 50,
+       FMT_DXT1_AS_16_16_16_16 = 51,
+       FMT_DXT2_3_AS_16_16_16_16 = 52,
+       FMT_DXT4_5_AS_16_16_16_16 = 53,
+       FMT_2_10_10_10_AS_16_16_16_16 = 54,
+       FMT_10_11_11_AS_16_16_16_16 = 55,
+       FMT_11_11_10_AS_16_16_16_16 = 56,
+       FMT_32_32_32_FLOAT = 57,
+       FMT_DXT3A = 58,
+       FMT_DXT5A = 59,
+       FMT_CTX1 = 60,
+       FMT_DXT3A_AS_1_1_1_1 = 61,
+};
+
+enum a2xx_sq_ps_vtx_mode {
+       POSITION_1_VECTOR = 0,
+       POSITION_2_VECTORS_UNUSED = 1,
+       POSITION_2_VECTORS_SPRITE = 2,
+       POSITION_2_VECTORS_EDGE = 3,
+       POSITION_2_VECTORS_KILL = 4,
+       POSITION_2_VECTORS_SPRITE_KILL = 5,
+       POSITION_2_VECTORS_EDGE_KILL = 6,
+       MULTIPASS = 7,
+};
+
+enum a2xx_sq_sample_cntl {
+       CENTROIDS_ONLY = 0,
+       CENTERS_ONLY = 1,
+       CENTROIDS_AND_CENTERS = 2,
+};
+
+enum a2xx_dx_clip_space {
+       DXCLIP_OPENGL = 0,
+       DXCLIP_DIRECTX = 1,
+};
+
+enum a2xx_pa_su_sc_polymode {
+       POLY_DISABLED = 0,
+       POLY_DUALMODE = 1,
+};
+
+enum a2xx_rb_edram_mode {
+       EDRAM_NOP = 0,
+       COLOR_DEPTH = 4,
+       DEPTH_ONLY = 5,
+       EDRAM_COPY = 6,
+};
+
+enum a2xx_pa_sc_pattern_bit_order {
+       LITTLE = 0,
+       BIG = 1,
+};
+
+enum a2xx_pa_sc_auto_reset_cntl {
+       NEVER = 0,
+       EACH_PRIMITIVE = 1,
+       EACH_PACKET = 2,
+};
+
+enum a2xx_pa_pixcenter {
+       PIXCENTER_D3D = 0,
+       PIXCENTER_OGL = 1,
+};
+
+enum a2xx_pa_roundmode {
+       TRUNCATE = 0,
+       ROUND = 1,
+       ROUNDTOEVEN = 2,
+       ROUNDTOODD = 3,
+};
+
+enum a2xx_pa_quantmode {
+       ONE_SIXTEENTH = 0,
+       ONE_EIGTH = 1,
+       ONE_QUARTER = 2,
+       ONE_HALF = 3,
+       ONE = 4,
+};
+
+enum a2xx_rb_copy_sample_select {
+       SAMPLE_0 = 0,
+       SAMPLE_1 = 1,
+       SAMPLE_2 = 2,
+       SAMPLE_3 = 3,
+       SAMPLE_01 = 4,
+       SAMPLE_23 = 5,
+       SAMPLE_0123 = 6,
+};
+
+enum sq_tex_clamp {
+       SQ_TEX_WRAP = 0,
+       SQ_TEX_MIRROR = 1,
+       SQ_TEX_CLAMP_LAST_TEXEL = 2,
+       SQ_TEX_MIRROR_ONCE_LAST_TEXEL = 3,
+       SQ_TEX_CLAMP_HALF_BORDER = 4,
+       SQ_TEX_MIRROR_ONCE_HALF_BORDER = 5,
+       SQ_TEX_CLAMP_BORDER = 6,
+       SQ_TEX_MIRROR_ONCE_BORDER = 7,
+};
+
+enum sq_tex_swiz {
+       SQ_TEX_X = 0,
+       SQ_TEX_Y = 1,
+       SQ_TEX_Z = 2,
+       SQ_TEX_W = 3,
+       SQ_TEX_ZERO = 4,
+       SQ_TEX_ONE = 5,
+};
+
+enum sq_tex_filter {
+       SQ_TEX_FILTER_POINT = 0,
+       SQ_TEX_FILTER_BILINEAR = 1,
+       SQ_TEX_FILTER_BICUBIC = 2,
+};
+
+#define REG_A2XX_RBBM_PATCH_RELEASE                            0x00000001
+
+#define REG_A2XX_RBBM_CNTL                                     0x0000003b
+
+#define REG_A2XX_RBBM_SOFT_RESET                               0x0000003c
+
+#define REG_A2XX_CP_PFP_UCODE_ADDR                             0x000000c0
+
+#define REG_A2XX_CP_PFP_UCODE_DATA                             0x000000c1
+
+#define REG_A2XX_RBBM_PERFCOUNTER1_SELECT                      0x00000395
+
+#define REG_A2XX_RBBM_PERFCOUNTER1_LO                          0x00000397
+
+#define REG_A2XX_RBBM_PERFCOUNTER1_HI                          0x00000398
+
+#define REG_A2XX_RBBM_DEBUG                                    0x0000039b
+
+#define REG_A2XX_RBBM_PM_OVERRIDE1                             0x0000039c
+
+#define REG_A2XX_RBBM_PM_OVERRIDE2                             0x0000039d
+
+#define REG_A2XX_RBBM_DEBUG_OUT                                        0x000003a0
+
+#define REG_A2XX_RBBM_DEBUG_CNTL                               0x000003a1
+
+#define REG_A2XX_RBBM_READ_ERROR                               0x000003b3
+
+#define REG_A2XX_RBBM_INT_CNTL                                 0x000003b4
+
+#define REG_A2XX_RBBM_INT_STATUS                               0x000003b5
+
+#define REG_A2XX_RBBM_INT_ACK                                  0x000003b6
+
+#define REG_A2XX_MASTER_INT_SIGNAL                             0x000003b7
+
+#define REG_A2XX_RBBM_PERIPHID1                                        0x000003f9
+
+#define REG_A2XX_RBBM_PERIPHID2                                        0x000003fa
+
+#define REG_A2XX_CP_PERFMON_CNTL                               0x00000444
+
+#define REG_A2XX_CP_PERFCOUNTER_SELECT                         0x00000445
+
+#define REG_A2XX_CP_PERFCOUNTER_LO                             0x00000446
+
+#define REG_A2XX_CP_PERFCOUNTER_HI                             0x00000447
+
+#define REG_A2XX_CP_ST_BASE                                    0x0000044d
+
+#define REG_A2XX_CP_ST_BUFSZ                                   0x0000044e
+
+#define REG_A2XX_CP_IB1_BASE                                   0x00000458
+
+#define REG_A2XX_CP_IB1_BUFSZ                                  0x00000459
+
+#define REG_A2XX_CP_IB2_BASE                                   0x0000045a
+
+#define REG_A2XX_CP_IB2_BUFSZ                                  0x0000045b
+
+#define REG_A2XX_CP_STAT                                       0x0000047f
+
+#define REG_A2XX_RBBM_STATUS                                   0x000005d0
+#define A2XX_RBBM_STATUS_CMDFIFO_AVAIL__MASK                   0x0000001f
+#define A2XX_RBBM_STATUS_CMDFIFO_AVAIL__SHIFT                  0
+static inline uint32_t A2XX_RBBM_STATUS_CMDFIFO_AVAIL(uint32_t val)
+{
+       return ((val) << A2XX_RBBM_STATUS_CMDFIFO_AVAIL__SHIFT) & A2XX_RBBM_STATUS_CMDFIFO_AVAIL__MASK;
+}
+#define A2XX_RBBM_STATUS_TC_BUSY                               0x00000020
+#define A2XX_RBBM_STATUS_HIRQ_PENDING                          0x00000100
+#define A2XX_RBBM_STATUS_CPRQ_PENDING                          0x00000200
+#define A2XX_RBBM_STATUS_CFRQ_PENDING                          0x00000400
+#define A2XX_RBBM_STATUS_PFRQ_PENDING                          0x00000800
+#define A2XX_RBBM_STATUS_VGT_BUSY_NO_DMA                       0x00001000
+#define A2XX_RBBM_STATUS_RBBM_WU_BUSY                          0x00004000
+#define A2XX_RBBM_STATUS_CP_NRT_BUSY                           0x00010000
+#define A2XX_RBBM_STATUS_MH_BUSY                               0x00040000
+#define A2XX_RBBM_STATUS_MH_COHERENCY_BUSY                     0x00080000
+#define A2XX_RBBM_STATUS_SX_BUSY                               0x00200000
+#define A2XX_RBBM_STATUS_TPC_BUSY                              0x00400000
+#define A2XX_RBBM_STATUS_SC_CNTX_BUSY                          0x01000000
+#define A2XX_RBBM_STATUS_PA_BUSY                               0x02000000
+#define A2XX_RBBM_STATUS_VGT_BUSY                              0x04000000
+#define A2XX_RBBM_STATUS_SQ_CNTX17_BUSY                                0x08000000
+#define A2XX_RBBM_STATUS_SQ_CNTX0_BUSY                         0x10000000
+#define A2XX_RBBM_STATUS_RB_CNTX_BUSY                          0x40000000
+#define A2XX_RBBM_STATUS_GUI_ACTIVE                            0x80000000
+
+#define REG_A2XX_A220_VSC_BIN_SIZE                             0x00000c01
+#define A2XX_A220_VSC_BIN_SIZE_WIDTH__MASK                     0x0000001f
+#define A2XX_A220_VSC_BIN_SIZE_WIDTH__SHIFT                    0
+static inline uint32_t A2XX_A220_VSC_BIN_SIZE_WIDTH(uint32_t val)
+{
+       return ((val >> 5) << A2XX_A220_VSC_BIN_SIZE_WIDTH__SHIFT) & A2XX_A220_VSC_BIN_SIZE_WIDTH__MASK;
+}
+#define A2XX_A220_VSC_BIN_SIZE_HEIGHT__MASK                    0x000003e0
+#define A2XX_A220_VSC_BIN_SIZE_HEIGHT__SHIFT                   5
+static inline uint32_t A2XX_A220_VSC_BIN_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val >> 5) << A2XX_A220_VSC_BIN_SIZE_HEIGHT__SHIFT) & A2XX_A220_VSC_BIN_SIZE_HEIGHT__MASK;
+}
+
+static inline uint32_t REG_A2XX_VSC_PIPE(uint32_t i0) { return 0x00000c06 + 0x3*i0; }
+
+static inline uint32_t REG_A2XX_VSC_PIPE_CONFIG(uint32_t i0) { return 0x00000c06 + 0x3*i0; }
+
+static inline uint32_t REG_A2XX_VSC_PIPE_DATA_ADDRESS(uint32_t i0) { return 0x00000c07 + 0x3*i0; }
+
+static inline uint32_t REG_A2XX_VSC_PIPE_DATA_LENGTH(uint32_t i0) { return 0x00000c08 + 0x3*i0; }
+
+#define REG_A2XX_PC_DEBUG_CNTL                                 0x00000c38
+
+#define REG_A2XX_PC_DEBUG_DATA                                 0x00000c39
+
+#define REG_A2XX_PA_SC_VIZ_QUERY_STATUS                                0x00000c44
+
+#define REG_A2XX_GRAS_DEBUG_CNTL                               0x00000c80
+
+#define REG_A2XX_PA_SU_DEBUG_CNTL                              0x00000c80
+
+#define REG_A2XX_GRAS_DEBUG_DATA                               0x00000c81
+
+#define REG_A2XX_PA_SU_DEBUG_DATA                              0x00000c81
+
+#define REG_A2XX_PA_SU_FACE_DATA                               0x00000c86
+
+#define REG_A2XX_SQ_GPR_MANAGEMENT                             0x00000d00
+
+#define REG_A2XX_SQ_FLOW_CONTROL                               0x00000d01
+
+#define REG_A2XX_SQ_INST_STORE_MANAGMENT                       0x00000d02
+
+#define REG_A2XX_SQ_DEBUG_MISC                                 0x00000d05
+
+#define REG_A2XX_SQ_INT_CNTL                                   0x00000d34
+
+#define REG_A2XX_SQ_INT_STATUS                                 0x00000d35
+
+#define REG_A2XX_SQ_INT_ACK                                    0x00000d36
+
+#define REG_A2XX_SQ_DEBUG_INPUT_FSM                            0x00000dae
+
+#define REG_A2XX_SQ_DEBUG_CONST_MGR_FSM                                0x00000daf
+
+#define REG_A2XX_SQ_DEBUG_TP_FSM                               0x00000db0
+
+#define REG_A2XX_SQ_DEBUG_FSM_ALU_0                            0x00000db1
+
+#define REG_A2XX_SQ_DEBUG_FSM_ALU_1                            0x00000db2
+
+#define REG_A2XX_SQ_DEBUG_EXP_ALLOC                            0x00000db3
+
+#define REG_A2XX_SQ_DEBUG_PTR_BUFF                             0x00000db4
+
+#define REG_A2XX_SQ_DEBUG_GPR_VTX                              0x00000db5
+
+#define REG_A2XX_SQ_DEBUG_GPR_PIX                              0x00000db6
+
+#define REG_A2XX_SQ_DEBUG_TB_STATUS_SEL                                0x00000db7
+
+#define REG_A2XX_SQ_DEBUG_VTX_TB_0                             0x00000db8
+
+#define REG_A2XX_SQ_DEBUG_VTX_TB_1                             0x00000db9
+
+#define REG_A2XX_SQ_DEBUG_VTX_TB_STATUS_REG                    0x00000dba
+
+#define REG_A2XX_SQ_DEBUG_VTX_TB_STATE_MEM                     0x00000dbb
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_0                             0x00000dbc
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_0                  0x00000dbd
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_1                  0x00000dbe
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_2                  0x00000dbf
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATUS_REG_3                  0x00000dc0
+
+#define REG_A2XX_SQ_DEBUG_PIX_TB_STATE_MEM                     0x00000dc1
+
+#define REG_A2XX_TC_CNTL_STATUS                                        0x00000e00
+#define A2XX_TC_CNTL_STATUS_L2_INVALIDATE                      0x00000001
+
+#define REG_A2XX_TP0_CHICKEN                                   0x00000e1e
+
+#define REG_A2XX_RB_BC_CONTROL                                 0x00000f01
+#define A2XX_RB_BC_CONTROL_ACCUM_LINEAR_MODE_ENABLE            0x00000001
+#define A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__MASK          0x00000006
+#define A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__SHIFT         1
+static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT(uint32_t val)
+{
+       return ((val) << A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT__MASK;
+}
+#define A2XX_RB_BC_CONTROL_DISABLE_EDRAM_CAM                   0x00000008
+#define A2XX_RB_BC_CONTROL_DISABLE_EZ_FAST_CONTEXT_SWITCH      0x00000010
+#define A2XX_RB_BC_CONTROL_DISABLE_EZ_NULL_ZCMD_DROP           0x00000020
+#define A2XX_RB_BC_CONTROL_DISABLE_LZ_NULL_ZCMD_DROP           0x00000040
+#define A2XX_RB_BC_CONTROL_ENABLE_AZ_THROTTLE                  0x00000080
+#define A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__MASK             0x00001f00
+#define A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__SHIFT            8
+static inline uint32_t A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT(uint32_t val)
+{
+       return ((val) << A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__SHIFT) & A2XX_RB_BC_CONTROL_AZ_THROTTLE_COUNT__MASK;
+}
+#define A2XX_RB_BC_CONTROL_ENABLE_CRC_UPDATE                   0x00004000
+#define A2XX_RB_BC_CONTROL_CRC_MODE                            0x00008000
+#define A2XX_RB_BC_CONTROL_DISABLE_SAMPLE_COUNTERS             0x00010000
+#define A2XX_RB_BC_CONTROL_DISABLE_ACCUM                       0x00020000
+#define A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__MASK              0x003c0000
+#define A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__SHIFT             18
+static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK(uint32_t val)
+{
+       return ((val) << A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_ALLOC_MASK__MASK;
+}
+#define A2XX_RB_BC_CONTROL_LINEAR_PERFORMANCE_ENABLE           0x00400000
+#define A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__MASK         0x07800000
+#define A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__SHIFT                23
+static inline uint32_t A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT(uint32_t val)
+{
+       return ((val) << A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__SHIFT) & A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT__MASK;
+}
+#define A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__MASK     0x18000000
+#define A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__SHIFT    27
+static inline uint32_t A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT(uint32_t val)
+{
+       return ((val) << A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__SHIFT) & A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT__MASK;
+}
+#define A2XX_RB_BC_CONTROL_MEM_EXPORT_LINEAR_MODE_ENABLE       0x20000000
+#define A2XX_RB_BC_CONTROL_CRC_SYSTEM                          0x40000000
+#define A2XX_RB_BC_CONTROL_RESERVED6                           0x80000000
+
+#define REG_A2XX_RB_EDRAM_INFO                                 0x00000f02
+
+#define REG_A2XX_RB_DEBUG_CNTL                                 0x00000f26
+
+#define REG_A2XX_RB_DEBUG_DATA                                 0x00000f27
+
+#define REG_A2XX_RB_SURFACE_INFO                               0x00002000
+
+#define REG_A2XX_RB_COLOR_INFO                                 0x00002001
+#define A2XX_RB_COLOR_INFO_FORMAT__MASK                                0x0000000f
+#define A2XX_RB_COLOR_INFO_FORMAT__SHIFT                       0
+static inline uint32_t A2XX_RB_COLOR_INFO_FORMAT(enum a2xx_colorformatx val)
+{
+       return ((val) << A2XX_RB_COLOR_INFO_FORMAT__SHIFT) & A2XX_RB_COLOR_INFO_FORMAT__MASK;
+}
+#define A2XX_RB_COLOR_INFO_ROUND_MODE__MASK                    0x00000030
+#define A2XX_RB_COLOR_INFO_ROUND_MODE__SHIFT                   4
+static inline uint32_t A2XX_RB_COLOR_INFO_ROUND_MODE(uint32_t val)
+{
+       return ((val) << A2XX_RB_COLOR_INFO_ROUND_MODE__SHIFT) & A2XX_RB_COLOR_INFO_ROUND_MODE__MASK;
+}
+#define A2XX_RB_COLOR_INFO_LINEAR                              0x00000040
+#define A2XX_RB_COLOR_INFO_ENDIAN__MASK                                0x00000180
+#define A2XX_RB_COLOR_INFO_ENDIAN__SHIFT                       7
+static inline uint32_t A2XX_RB_COLOR_INFO_ENDIAN(uint32_t val)
+{
+       return ((val) << A2XX_RB_COLOR_INFO_ENDIAN__SHIFT) & A2XX_RB_COLOR_INFO_ENDIAN__MASK;
+}
+#define A2XX_RB_COLOR_INFO_SWAP__MASK                          0x00000600
+#define A2XX_RB_COLOR_INFO_SWAP__SHIFT                         9
+static inline uint32_t A2XX_RB_COLOR_INFO_SWAP(uint32_t val)
+{
+       return ((val) << A2XX_RB_COLOR_INFO_SWAP__SHIFT) & A2XX_RB_COLOR_INFO_SWAP__MASK;
+}
+#define A2XX_RB_COLOR_INFO_BASE__MASK                          0xfffff000
+#define A2XX_RB_COLOR_INFO_BASE__SHIFT                         12
+static inline uint32_t A2XX_RB_COLOR_INFO_BASE(uint32_t val)
+{
+       return ((val >> 10) << A2XX_RB_COLOR_INFO_BASE__SHIFT) & A2XX_RB_COLOR_INFO_BASE__MASK;
+}
+
+#define REG_A2XX_RB_DEPTH_INFO                                 0x00002002
+#define A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK                  0x00000001
+#define A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT                 0
+static inline uint32_t A2XX_RB_DEPTH_INFO_DEPTH_FORMAT(enum adreno_rb_depth_format val)
+{
+       return ((val) << A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT) & A2XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK;
+}
+#define A2XX_RB_DEPTH_INFO_DEPTH_BASE__MASK                    0xfffff000
+#define A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT                   12
+static inline uint32_t A2XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val)
+{
+       return ((val >> 10) << A2XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A2XX_RB_DEPTH_INFO_DEPTH_BASE__MASK;
+}
+
+#define REG_A2XX_A225_RB_COLOR_INFO3                           0x00002005
+
+#define REG_A2XX_COHER_DEST_BASE_0                             0x00002006
+
+#define REG_A2XX_PA_SC_SCREEN_SCISSOR_TL                       0x0000200e
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_WINDOW_OFFSET_DISABLE     0x80000000
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_X__MASK                   0x00007fff
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_X__SHIFT                  0
+static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_TL_X(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_TL_X__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_TL_X__MASK;
+}
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__MASK                   0x7fff0000
+#define A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__SHIFT                  16
+static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_TL_Y(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_TL_Y__MASK;
+}
+
+#define REG_A2XX_PA_SC_SCREEN_SCISSOR_BR                       0x0000200f
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_WINDOW_OFFSET_DISABLE     0x80000000
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_X__MASK                   0x00007fff
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_X__SHIFT                  0
+static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_BR_X(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_BR_X__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_BR_X__MASK;
+}
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__MASK                   0x7fff0000
+#define A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__SHIFT                  16
+static inline uint32_t A2XX_PA_SC_SCREEN_SCISSOR_BR_Y(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__SHIFT) & A2XX_PA_SC_SCREEN_SCISSOR_BR_Y__MASK;
+}
+
+#define REG_A2XX_PA_SC_WINDOW_OFFSET                           0x00002080
+#define A2XX_PA_SC_WINDOW_OFFSET_X__MASK                       0x00007fff
+#define A2XX_PA_SC_WINDOW_OFFSET_X__SHIFT                      0
+static inline uint32_t A2XX_PA_SC_WINDOW_OFFSET_X(int32_t val)
+{
+       return ((val) << A2XX_PA_SC_WINDOW_OFFSET_X__SHIFT) & A2XX_PA_SC_WINDOW_OFFSET_X__MASK;
+}
+#define A2XX_PA_SC_WINDOW_OFFSET_Y__MASK                       0x7fff0000
+#define A2XX_PA_SC_WINDOW_OFFSET_Y__SHIFT                      16
+static inline uint32_t A2XX_PA_SC_WINDOW_OFFSET_Y(int32_t val)
+{
+       return ((val) << A2XX_PA_SC_WINDOW_OFFSET_Y__SHIFT) & A2XX_PA_SC_WINDOW_OFFSET_Y__MASK;
+}
+#define A2XX_PA_SC_WINDOW_OFFSET_DISABLE                       0x80000000
+
+#define REG_A2XX_PA_SC_WINDOW_SCISSOR_TL                       0x00002081
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_WINDOW_OFFSET_DISABLE     0x80000000
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_X__MASK                   0x00007fff
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_X__SHIFT                  0
+static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_TL_X(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_TL_X__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_TL_X__MASK;
+}
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__MASK                   0x7fff0000
+#define A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__SHIFT                  16
+static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_TL_Y(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_TL_Y__MASK;
+}
+
+#define REG_A2XX_PA_SC_WINDOW_SCISSOR_BR                       0x00002082
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_WINDOW_OFFSET_DISABLE     0x80000000
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_X__MASK                   0x00007fff
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_X__SHIFT                  0
+static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_BR_X(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_BR_X__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_BR_X__MASK;
+}
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__MASK                   0x7fff0000
+#define A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__SHIFT                  16
+static inline uint32_t A2XX_PA_SC_WINDOW_SCISSOR_BR_Y(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__SHIFT) & A2XX_PA_SC_WINDOW_SCISSOR_BR_Y__MASK;
+}
+
+#define REG_A2XX_UNKNOWN_2010                                  0x00002010
+
+#define REG_A2XX_VGT_MAX_VTX_INDX                              0x00002100
+
+#define REG_A2XX_VGT_MIN_VTX_INDX                              0x00002101
+
+#define REG_A2XX_VGT_INDX_OFFSET                               0x00002102
+
+#define REG_A2XX_A225_PC_MULTI_PRIM_IB_RESET_INDX              0x00002103
+
+#define REG_A2XX_RB_COLOR_MASK                                 0x00002104
+#define A2XX_RB_COLOR_MASK_WRITE_RED                           0x00000001
+#define A2XX_RB_COLOR_MASK_WRITE_GREEN                         0x00000002
+#define A2XX_RB_COLOR_MASK_WRITE_BLUE                          0x00000004
+#define A2XX_RB_COLOR_MASK_WRITE_ALPHA                         0x00000008
+
+#define REG_A2XX_RB_BLEND_RED                                  0x00002105
+
+#define REG_A2XX_RB_BLEND_GREEN                                        0x00002106
+
+#define REG_A2XX_RB_BLEND_BLUE                                 0x00002107
+
+#define REG_A2XX_RB_BLEND_ALPHA                                        0x00002108
+
+#define REG_A2XX_RB_FOG_COLOR                                  0x00002109
+
+#define REG_A2XX_RB_STENCILREFMASK_BF                          0x0000210c
+#define A2XX_RB_STENCILREFMASK_BF_STENCILREF__MASK             0x000000ff
+#define A2XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT            0
+static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILREF(uint32_t val)
+{
+       return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILREF__MASK;
+}
+#define A2XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK            0x0000ff00
+#define A2XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT           8
+static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILMASK(uint32_t val)
+{
+       return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK;
+}
+#define A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK       0x00ff0000
+#define A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT      16
+static inline uint32_t A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(uint32_t val)
+{
+       return ((val) << A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT) & A2XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK;
+}
+
+#define REG_A2XX_RB_STENCILREFMASK                             0x0000210d
+#define A2XX_RB_STENCILREFMASK_STENCILREF__MASK                        0x000000ff
+#define A2XX_RB_STENCILREFMASK_STENCILREF__SHIFT               0
+static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILREF(uint32_t val)
+{
+       return ((val) << A2XX_RB_STENCILREFMASK_STENCILREF__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILREF__MASK;
+}
+#define A2XX_RB_STENCILREFMASK_STENCILMASK__MASK               0x0000ff00
+#define A2XX_RB_STENCILREFMASK_STENCILMASK__SHIFT              8
+static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILMASK(uint32_t val)
+{
+       return ((val) << A2XX_RB_STENCILREFMASK_STENCILMASK__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILMASK__MASK;
+}
+#define A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK          0x00ff0000
+#define A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT         16
+static inline uint32_t A2XX_RB_STENCILREFMASK_STENCILWRITEMASK(uint32_t val)
+{
+       return ((val) << A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT) & A2XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK;
+}
+
+#define REG_A2XX_RB_ALPHA_REF                                  0x0000210e
+
+#define REG_A2XX_PA_CL_VPORT_XSCALE                            0x0000210f
+#define A2XX_PA_CL_VPORT_XSCALE__MASK                          0xffffffff
+#define A2XX_PA_CL_VPORT_XSCALE__SHIFT                         0
+static inline uint32_t A2XX_PA_CL_VPORT_XSCALE(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_VPORT_XSCALE__SHIFT) & A2XX_PA_CL_VPORT_XSCALE__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_XOFFSET                           0x00002110
+#define A2XX_PA_CL_VPORT_XOFFSET__MASK                         0xffffffff
+#define A2XX_PA_CL_VPORT_XOFFSET__SHIFT                                0
+static inline uint32_t A2XX_PA_CL_VPORT_XOFFSET(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_VPORT_XOFFSET__SHIFT) & A2XX_PA_CL_VPORT_XOFFSET__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_YSCALE                            0x00002111
+#define A2XX_PA_CL_VPORT_YSCALE__MASK                          0xffffffff
+#define A2XX_PA_CL_VPORT_YSCALE__SHIFT                         0
+static inline uint32_t A2XX_PA_CL_VPORT_YSCALE(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_VPORT_YSCALE__SHIFT) & A2XX_PA_CL_VPORT_YSCALE__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_YOFFSET                           0x00002112
+#define A2XX_PA_CL_VPORT_YOFFSET__MASK                         0xffffffff
+#define A2XX_PA_CL_VPORT_YOFFSET__SHIFT                                0
+static inline uint32_t A2XX_PA_CL_VPORT_YOFFSET(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_VPORT_YOFFSET__SHIFT) & A2XX_PA_CL_VPORT_YOFFSET__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_ZSCALE                            0x00002113
+#define A2XX_PA_CL_VPORT_ZSCALE__MASK                          0xffffffff
+#define A2XX_PA_CL_VPORT_ZSCALE__SHIFT                         0
+static inline uint32_t A2XX_PA_CL_VPORT_ZSCALE(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_VPORT_ZSCALE__SHIFT) & A2XX_PA_CL_VPORT_ZSCALE__MASK;
+}
+
+#define REG_A2XX_PA_CL_VPORT_ZOFFSET                           0x00002114
+#define A2XX_PA_CL_VPORT_ZOFFSET__MASK                         0xffffffff
+#define A2XX_PA_CL_VPORT_ZOFFSET__SHIFT                                0
+static inline uint32_t A2XX_PA_CL_VPORT_ZOFFSET(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_VPORT_ZOFFSET__SHIFT) & A2XX_PA_CL_VPORT_ZOFFSET__MASK;
+}
+
+#define REG_A2XX_SQ_PROGRAM_CNTL                               0x00002180
+#define A2XX_SQ_PROGRAM_CNTL_VS_REGS__MASK                     0x000000ff
+#define A2XX_SQ_PROGRAM_CNTL_VS_REGS__SHIFT                    0
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_REGS(uint32_t val)
+{
+       return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_REGS__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_REGS__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_PS_REGS__MASK                     0x0000ff00
+#define A2XX_SQ_PROGRAM_CNTL_PS_REGS__SHIFT                    8
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_PS_REGS(uint32_t val)
+{
+       return ((val) << A2XX_SQ_PROGRAM_CNTL_PS_REGS__SHIFT) & A2XX_SQ_PROGRAM_CNTL_PS_REGS__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_VS_RESOURCE                       0x00010000
+#define A2XX_SQ_PROGRAM_CNTL_PS_RESOURCE                       0x00020000
+#define A2XX_SQ_PROGRAM_CNTL_PARAM_GEN                         0x00040000
+#define A2XX_SQ_PROGRAM_CNTL_GEN_INDEX_PIX                     0x00080000
+#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__MASK             0x00f00000
+#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__SHIFT            20
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT(uint32_t val)
+{
+       return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_COUNT__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__MASK              0x07000000
+#define A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__SHIFT             24
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE(enum a2xx_sq_ps_vtx_mode val)
+{
+       return ((val) << A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__SHIFT) & A2XX_SQ_PROGRAM_CNTL_VS_EXPORT_MODE__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__MASK              0x78000000
+#define A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__SHIFT             27
+static inline uint32_t A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE(uint32_t val)
+{
+       return ((val) << A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__SHIFT) & A2XX_SQ_PROGRAM_CNTL_PS_EXPORT_MODE__MASK;
+}
+#define A2XX_SQ_PROGRAM_CNTL_GEN_INDEX_VTX                     0x80000000
+
+#define REG_A2XX_SQ_CONTEXT_MISC                               0x00002181
+#define A2XX_SQ_CONTEXT_MISC_INST_PRED_OPTIMIZE                        0x00000001
+#define A2XX_SQ_CONTEXT_MISC_SC_OUTPUT_SCREEN_XY               0x00000002
+#define A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__MASK              0x0000000c
+#define A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__SHIFT             2
+static inline uint32_t A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL(enum a2xx_sq_sample_cntl val)
+{
+       return ((val) << A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__SHIFT) & A2XX_SQ_CONTEXT_MISC_SC_SAMPLE_CNTL__MASK;
+}
+#define A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__MASK               0x0000ff00
+#define A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__SHIFT              8
+static inline uint32_t A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS(uint32_t val)
+{
+       return ((val) << A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__SHIFT) & A2XX_SQ_CONTEXT_MISC_PARAM_GEN_POS__MASK;
+}
+#define A2XX_SQ_CONTEXT_MISC_PERFCOUNTER_REF                   0x00010000
+#define A2XX_SQ_CONTEXT_MISC_YEILD_OPTIMIZE                    0x00020000
+#define A2XX_SQ_CONTEXT_MISC_TX_CACHE_SEL                      0x00040000
+
+#define REG_A2XX_SQ_INTERPOLATOR_CNTL                          0x00002182
+
+#define REG_A2XX_SQ_WRAPPING_0                                 0x00002183
+
+#define REG_A2XX_SQ_WRAPPING_1                                 0x00002184
+
+#define REG_A2XX_SQ_PS_PROGRAM                                 0x000021f6
+
+#define REG_A2XX_SQ_VS_PROGRAM                                 0x000021f7
+
+#define REG_A2XX_RB_DEPTHCONTROL                               0x00002200
+#define A2XX_RB_DEPTHCONTROL_STENCIL_ENABLE                    0x00000001
+#define A2XX_RB_DEPTHCONTROL_Z_ENABLE                          0x00000002
+#define A2XX_RB_DEPTHCONTROL_Z_WRITE_ENABLE                    0x00000004
+#define A2XX_RB_DEPTHCONTROL_EARLY_Z_ENABLE                    0x00000008
+#define A2XX_RB_DEPTHCONTROL_ZFUNC__MASK                       0x00000070
+#define A2XX_RB_DEPTHCONTROL_ZFUNC__SHIFT                      4
+static inline uint32_t A2XX_RB_DEPTHCONTROL_ZFUNC(enum adreno_compare_func val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_ZFUNC__SHIFT) & A2XX_RB_DEPTHCONTROL_ZFUNC__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_BACKFACE_ENABLE                   0x00000080
+#define A2XX_RB_DEPTHCONTROL_STENCILFUNC__MASK                 0x00000700
+#define A2XX_RB_DEPTHCONTROL_STENCILFUNC__SHIFT                        8
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFUNC(enum adreno_compare_func val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFUNC__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFUNC__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILFAIL__MASK                 0x00003800
+#define A2XX_RB_DEPTHCONTROL_STENCILFAIL__SHIFT                        11
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFAIL(enum adreno_stencil_op val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFAIL__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFAIL__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILZPASS__MASK                        0x0001c000
+#define A2XX_RB_DEPTHCONTROL_STENCILZPASS__SHIFT               14
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZPASS(enum adreno_stencil_op val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZPASS__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZPASS__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL__MASK                        0x000e0000
+#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL__SHIFT               17
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZFAIL(enum adreno_stencil_op val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZFAIL__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZFAIL__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__MASK              0x00700000
+#define A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__SHIFT             20
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF(enum adreno_compare_func val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFUNC_BF__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__MASK              0x03800000
+#define A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__SHIFT             23
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF(enum adreno_stencil_op val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILFAIL_BF__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__MASK             0x1c000000
+#define A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__SHIFT            26
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF(enum adreno_stencil_op val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZPASS_BF__MASK;
+}
+#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__MASK             0xe0000000
+#define A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__SHIFT            29
+static inline uint32_t A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF(enum adreno_stencil_op val)
+{
+       return ((val) << A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__SHIFT) & A2XX_RB_DEPTHCONTROL_STENCILZFAIL_BF__MASK;
+}
+
+#define REG_A2XX_RB_BLEND_CONTROL                              0x00002201
+#define A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__MASK             0x0000001f
+#define A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__SHIFT            0
+static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND(enum adreno_rb_blend_factor val)
+{
+       return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_SRCBLEND__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__MASK             0x000000e0
+#define A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__SHIFT            5
+static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN(enum adreno_rb_blend_opcode val)
+{
+       return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_COMB_FCN__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__MASK            0x00001f00
+#define A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__SHIFT           8
+static inline uint32_t A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND(enum adreno_rb_blend_factor val)
+{
+       return ((val) << A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_COLOR_DESTBLEND__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__MASK             0x001f0000
+#define A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__SHIFT            16
+static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND(enum adreno_rb_blend_factor val)
+{
+       return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_SRCBLEND__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__MASK             0x00e00000
+#define A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__SHIFT            21
+static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN(enum adreno_rb_blend_opcode val)
+{
+       return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_COMB_FCN__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__MASK            0x1f000000
+#define A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__SHIFT           24
+static inline uint32_t A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND(enum adreno_rb_blend_factor val)
+{
+       return ((val) << A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__SHIFT) & A2XX_RB_BLEND_CONTROL_ALPHA_DESTBLEND__MASK;
+}
+#define A2XX_RB_BLEND_CONTROL_BLEND_FORCE_ENABLE               0x20000000
+#define A2XX_RB_BLEND_CONTROL_BLEND_FORCE                      0x40000000
+
+#define REG_A2XX_RB_COLORCONTROL                               0x00002202
+#define A2XX_RB_COLORCONTROL_ALPHA_FUNC__MASK                  0x00000007
+#define A2XX_RB_COLORCONTROL_ALPHA_FUNC__SHIFT                 0
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_FUNC(enum adreno_compare_func val)
+{
+       return ((val) << A2XX_RB_COLORCONTROL_ALPHA_FUNC__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_FUNC__MASK;
+}
+#define A2XX_RB_COLORCONTROL_ALPHA_TEST_ENABLE                 0x00000008
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_ENABLE              0x00000010
+#define A2XX_RB_COLORCONTROL_BLEND_DISABLE                     0x00000020
+#define A2XX_RB_COLORCONTROL_VOB_ENABLE                                0x00000040
+#define A2XX_RB_COLORCONTROL_VS_EXPORTS_FOG                    0x00000080
+#define A2XX_RB_COLORCONTROL_ROP_CODE__MASK                    0x00000f00
+#define A2XX_RB_COLORCONTROL_ROP_CODE__SHIFT                   8
+static inline uint32_t A2XX_RB_COLORCONTROL_ROP_CODE(uint32_t val)
+{
+       return ((val) << A2XX_RB_COLORCONTROL_ROP_CODE__SHIFT) & A2XX_RB_COLORCONTROL_ROP_CODE__MASK;
+}
+#define A2XX_RB_COLORCONTROL_DITHER_MODE__MASK                 0x00003000
+#define A2XX_RB_COLORCONTROL_DITHER_MODE__SHIFT                        12
+static inline uint32_t A2XX_RB_COLORCONTROL_DITHER_MODE(enum adreno_rb_dither_mode val)
+{
+       return ((val) << A2XX_RB_COLORCONTROL_DITHER_MODE__SHIFT) & A2XX_RB_COLORCONTROL_DITHER_MODE__MASK;
+}
+#define A2XX_RB_COLORCONTROL_DITHER_TYPE__MASK                 0x0000c000
+#define A2XX_RB_COLORCONTROL_DITHER_TYPE__SHIFT                        14
+static inline uint32_t A2XX_RB_COLORCONTROL_DITHER_TYPE(enum a2xx_rb_dither_type val)
+{
+       return ((val) << A2XX_RB_COLORCONTROL_DITHER_TYPE__SHIFT) & A2XX_RB_COLORCONTROL_DITHER_TYPE__MASK;
+}
+#define A2XX_RB_COLORCONTROL_PIXEL_FOG                         0x00010000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__MASK       0x03000000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__SHIFT      24
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0(uint32_t val)
+{
+       return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET0__MASK;
+}
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__MASK       0x0c000000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__SHIFT      26
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1(uint32_t val)
+{
+       return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET1__MASK;
+}
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__MASK       0x30000000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__SHIFT      28
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2(uint32_t val)
+{
+       return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET2__MASK;
+}
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__MASK       0xc0000000
+#define A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__SHIFT      30
+static inline uint32_t A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3(uint32_t val)
+{
+       return ((val) << A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__SHIFT) & A2XX_RB_COLORCONTROL_ALPHA_TO_MASK_OFFSET3__MASK;
+}
+
+#define REG_A2XX_VGT_CURRENT_BIN_ID_MAX                                0x00002203
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__MASK               0x00000007
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__SHIFT              0
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN(uint32_t val)
+{
+       return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_COLUMN__MASK;
+}
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__MASK                  0x00000038
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__SHIFT                 3
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_ROW(uint32_t val)
+{
+       return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_ROW__MASK;
+}
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__MASK      0x000001c0
+#define A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__SHIFT     6
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK(uint32_t val)
+{
+       return ((val) << A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MAX_GUARD_BAND_MASK__MASK;
+}
+
+#define REG_A2XX_PA_CL_CLIP_CNTL                               0x00002204
+#define A2XX_PA_CL_CLIP_CNTL_CLIP_DISABLE                      0x00010000
+#define A2XX_PA_CL_CLIP_CNTL_BOUNDARY_EDGE_FLAG_ENA            0x00040000
+#define A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__MASK           0x00080000
+#define A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__SHIFT          19
+static inline uint32_t A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF(enum a2xx_dx_clip_space val)
+{
+       return ((val) << A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__SHIFT) & A2XX_PA_CL_CLIP_CNTL_DX_CLIP_SPACE_DEF__MASK;
+}
+#define A2XX_PA_CL_CLIP_CNTL_DIS_CLIP_ERR_DETECT               0x00100000
+#define A2XX_PA_CL_CLIP_CNTL_VTX_KILL_OR                       0x00200000
+#define A2XX_PA_CL_CLIP_CNTL_XY_NAN_RETAIN                     0x00400000
+#define A2XX_PA_CL_CLIP_CNTL_Z_NAN_RETAIN                      0x00800000
+#define A2XX_PA_CL_CLIP_CNTL_W_NAN_RETAIN                      0x01000000
+
+#define REG_A2XX_PA_SU_SC_MODE_CNTL                            0x00002205
+#define A2XX_PA_SU_SC_MODE_CNTL_CULL_FRONT                     0x00000001
+#define A2XX_PA_SU_SC_MODE_CNTL_CULL_BACK                      0x00000002
+#define A2XX_PA_SU_SC_MODE_CNTL_FACE                           0x00000004
+#define A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__MASK                 0x00000018
+#define A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__SHIFT                        3
+static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_POLYMODE(enum a2xx_pa_su_sc_polymode val)
+{
+       return ((val) << A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_POLYMODE__MASK;
+}
+#define A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__MASK              0x000000e0
+#define A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__SHIFT             5
+static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE(enum adreno_pa_su_sc_draw val)
+{
+       return ((val) << A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_FRONT_PTYPE__MASK;
+}
+#define A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__MASK               0x00000700
+#define A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__SHIFT              8
+static inline uint32_t A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE(enum adreno_pa_su_sc_draw val)
+{
+       return ((val) << A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__SHIFT) & A2XX_PA_SU_SC_MODE_CNTL_BACK_PTYPE__MASK;
+}
+#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_FRONT_ENABLE       0x00000800
+#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_BACK_ENABLE                0x00001000
+#define A2XX_PA_SU_SC_MODE_CNTL_POLY_OFFSET_PARA_ENABLE                0x00002000
+#define A2XX_PA_SU_SC_MODE_CNTL_MSAA_ENABLE                    0x00008000
+#define A2XX_PA_SU_SC_MODE_CNTL_VTX_WINDOW_OFFSET_ENABLE       0x00010000
+#define A2XX_PA_SU_SC_MODE_CNTL_LINE_STIPPLE_ENABLE            0x00040000
+#define A2XX_PA_SU_SC_MODE_CNTL_PROVOKING_VTX_LAST             0x00080000
+#define A2XX_PA_SU_SC_MODE_CNTL_PERSP_CORR_DIS                 0x00100000
+#define A2XX_PA_SU_SC_MODE_CNTL_MULTI_PRIM_IB_ENA              0x00200000
+#define A2XX_PA_SU_SC_MODE_CNTL_QUAD_ORDER_ENABLE              0x00800000
+#define A2XX_PA_SU_SC_MODE_CNTL_WAIT_RB_IDLE_ALL_TRI           0x02000000
+#define A2XX_PA_SU_SC_MODE_CNTL_WAIT_RB_IDLE_FIRST_TRI_NEW_STATE       0x04000000
+#define A2XX_PA_SU_SC_MODE_CNTL_CLAMPED_FACENESS               0x10000000
+#define A2XX_PA_SU_SC_MODE_CNTL_ZERO_AREA_FACENESS             0x20000000
+#define A2XX_PA_SU_SC_MODE_CNTL_FACE_KILL_ENABLE               0x40000000
+#define A2XX_PA_SU_SC_MODE_CNTL_FACE_WRITE_ENABLE              0x80000000
+
+#define REG_A2XX_PA_CL_VTE_CNTL                                        0x00002206
+#define A2XX_PA_CL_VTE_CNTL_VPORT_X_SCALE_ENA                  0x00000001
+#define A2XX_PA_CL_VTE_CNTL_VPORT_X_OFFSET_ENA                 0x00000002
+#define A2XX_PA_CL_VTE_CNTL_VPORT_Y_SCALE_ENA                  0x00000004
+#define A2XX_PA_CL_VTE_CNTL_VPORT_Y_OFFSET_ENA                 0x00000008
+#define A2XX_PA_CL_VTE_CNTL_VPORT_Z_SCALE_ENA                  0x00000010
+#define A2XX_PA_CL_VTE_CNTL_VPORT_Z_OFFSET_ENA                 0x00000020
+#define A2XX_PA_CL_VTE_CNTL_VTX_XY_FMT                         0x00000100
+#define A2XX_PA_CL_VTE_CNTL_VTX_Z_FMT                          0x00000200
+#define A2XX_PA_CL_VTE_CNTL_VTX_W0_FMT                         0x00000400
+#define A2XX_PA_CL_VTE_CNTL_PERFCOUNTER_REF                    0x00000800
+
+#define REG_A2XX_VGT_CURRENT_BIN_ID_MIN                                0x00002207
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__MASK               0x00000007
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__SHIFT              0
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN(uint32_t val)
+{
+       return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_COLUMN__MASK;
+}
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__MASK                  0x00000038
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__SHIFT                 3
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_ROW(uint32_t val)
+{
+       return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_ROW__MASK;
+}
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__MASK      0x000001c0
+#define A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__SHIFT     6
+static inline uint32_t A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK(uint32_t val)
+{
+       return ((val) << A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__SHIFT) & A2XX_VGT_CURRENT_BIN_ID_MIN_GUARD_BAND_MASK__MASK;
+}
+
+#define REG_A2XX_RB_MODECONTROL                                        0x00002208
+#define A2XX_RB_MODECONTROL_EDRAM_MODE__MASK                   0x00000007
+#define A2XX_RB_MODECONTROL_EDRAM_MODE__SHIFT                  0
+static inline uint32_t A2XX_RB_MODECONTROL_EDRAM_MODE(enum a2xx_rb_edram_mode val)
+{
+       return ((val) << A2XX_RB_MODECONTROL_EDRAM_MODE__SHIFT) & A2XX_RB_MODECONTROL_EDRAM_MODE__MASK;
+}
+
+#define REG_A2XX_A220_RB_LRZ_VSC_CONTROL                       0x00002209
+
+#define REG_A2XX_RB_SAMPLE_POS                                 0x0000220a
+
+#define REG_A2XX_CLEAR_COLOR                                   0x0000220b
+#define A2XX_CLEAR_COLOR_RED__MASK                             0x000000ff
+#define A2XX_CLEAR_COLOR_RED__SHIFT                            0
+static inline uint32_t A2XX_CLEAR_COLOR_RED(uint32_t val)
+{
+       return ((val) << A2XX_CLEAR_COLOR_RED__SHIFT) & A2XX_CLEAR_COLOR_RED__MASK;
+}
+#define A2XX_CLEAR_COLOR_GREEN__MASK                           0x0000ff00
+#define A2XX_CLEAR_COLOR_GREEN__SHIFT                          8
+static inline uint32_t A2XX_CLEAR_COLOR_GREEN(uint32_t val)
+{
+       return ((val) << A2XX_CLEAR_COLOR_GREEN__SHIFT) & A2XX_CLEAR_COLOR_GREEN__MASK;
+}
+#define A2XX_CLEAR_COLOR_BLUE__MASK                            0x00ff0000
+#define A2XX_CLEAR_COLOR_BLUE__SHIFT                           16
+static inline uint32_t A2XX_CLEAR_COLOR_BLUE(uint32_t val)
+{
+       return ((val) << A2XX_CLEAR_COLOR_BLUE__SHIFT) & A2XX_CLEAR_COLOR_BLUE__MASK;
+}
+#define A2XX_CLEAR_COLOR_ALPHA__MASK                           0xff000000
+#define A2XX_CLEAR_COLOR_ALPHA__SHIFT                          24
+static inline uint32_t A2XX_CLEAR_COLOR_ALPHA(uint32_t val)
+{
+       return ((val) << A2XX_CLEAR_COLOR_ALPHA__SHIFT) & A2XX_CLEAR_COLOR_ALPHA__MASK;
+}
+
+#define REG_A2XX_A220_GRAS_CONTROL                             0x00002210
+
+#define REG_A2XX_PA_SU_POINT_SIZE                              0x00002280
+#define A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK                     0x0000ffff
+#define A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT                    0
+static inline uint32_t A2XX_PA_SU_POINT_SIZE_HEIGHT(float val)
+{
+       return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_HEIGHT__SHIFT) & A2XX_PA_SU_POINT_SIZE_HEIGHT__MASK;
+}
+#define A2XX_PA_SU_POINT_SIZE_WIDTH__MASK                      0xffff0000
+#define A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT                     16
+static inline uint32_t A2XX_PA_SU_POINT_SIZE_WIDTH(float val)
+{
+       return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_SIZE_WIDTH__SHIFT) & A2XX_PA_SU_POINT_SIZE_WIDTH__MASK;
+}
+
+#define REG_A2XX_PA_SU_POINT_MINMAX                            0x00002281
+#define A2XX_PA_SU_POINT_MINMAX_MIN__MASK                      0x0000ffff
+#define A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT                     0
+static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MIN(float val)
+{
+       return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MIN__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MIN__MASK;
+}
+#define A2XX_PA_SU_POINT_MINMAX_MAX__MASK                      0xffff0000
+#define A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT                     16
+static inline uint32_t A2XX_PA_SU_POINT_MINMAX_MAX(float val)
+{
+       return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_POINT_MINMAX_MAX__SHIFT) & A2XX_PA_SU_POINT_MINMAX_MAX__MASK;
+}
+
+#define REG_A2XX_PA_SU_LINE_CNTL                               0x00002282
+#define A2XX_PA_SU_LINE_CNTL_WIDTH__MASK                       0x0000ffff
+#define A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT                      0
+static inline uint32_t A2XX_PA_SU_LINE_CNTL_WIDTH(float val)
+{
+       return ((((uint32_t)(val * 8.0))) << A2XX_PA_SU_LINE_CNTL_WIDTH__SHIFT) & A2XX_PA_SU_LINE_CNTL_WIDTH__MASK;
+}
+
+#define REG_A2XX_PA_SC_LINE_STIPPLE                            0x00002283
+#define A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__MASK             0x0000ffff
+#define A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__SHIFT            0
+static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_LINE_PATTERN__MASK;
+}
+#define A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__MASK             0x00ff0000
+#define A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__SHIFT            16
+static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_REPEAT_COUNT__MASK;
+}
+#define A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__MASK                0x10000000
+#define A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__SHIFT       28
+static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER(enum a2xx_pa_sc_pattern_bit_order val)
+{
+       return ((val) << A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_PATTERN_BIT_ORDER__MASK;
+}
+#define A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__MASK          0x60000000
+#define A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__SHIFT         29
+static inline uint32_t A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL(enum a2xx_pa_sc_auto_reset_cntl val)
+{
+       return ((val) << A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__SHIFT) & A2XX_PA_SC_LINE_STIPPLE_AUTO_RESET_CNTL__MASK;
+}
+
+#define REG_A2XX_PA_SC_VIZ_QUERY                               0x00002293
+
+#define REG_A2XX_VGT_ENHANCE                                   0x00002294
+
+#define REG_A2XX_PA_SC_LINE_CNTL                               0x00002300
+#define A2XX_PA_SC_LINE_CNTL_BRES_CNTL__MASK                   0x0000ffff
+#define A2XX_PA_SC_LINE_CNTL_BRES_CNTL__SHIFT                  0
+static inline uint32_t A2XX_PA_SC_LINE_CNTL_BRES_CNTL(uint32_t val)
+{
+       return ((val) << A2XX_PA_SC_LINE_CNTL_BRES_CNTL__SHIFT) & A2XX_PA_SC_LINE_CNTL_BRES_CNTL__MASK;
+}
+#define A2XX_PA_SC_LINE_CNTL_USE_BRES_CNTL                     0x00000100
+#define A2XX_PA_SC_LINE_CNTL_EXPAND_LINE_WIDTH                 0x00000200
+#define A2XX_PA_SC_LINE_CNTL_LAST_PIXEL                                0x00000400
+
+#define REG_A2XX_PA_SC_AA_CONFIG                               0x00002301
+
+#define REG_A2XX_PA_SU_VTX_CNTL                                        0x00002302
+#define A2XX_PA_SU_VTX_CNTL_PIX_CENTER__MASK                   0x00000001
+#define A2XX_PA_SU_VTX_CNTL_PIX_CENTER__SHIFT                  0
+static inline uint32_t A2XX_PA_SU_VTX_CNTL_PIX_CENTER(enum a2xx_pa_pixcenter val)
+{
+       return ((val) << A2XX_PA_SU_VTX_CNTL_PIX_CENTER__SHIFT) & A2XX_PA_SU_VTX_CNTL_PIX_CENTER__MASK;
+}
+#define A2XX_PA_SU_VTX_CNTL_ROUND_MODE__MASK                   0x00000006
+#define A2XX_PA_SU_VTX_CNTL_ROUND_MODE__SHIFT                  1
+static inline uint32_t A2XX_PA_SU_VTX_CNTL_ROUND_MODE(enum a2xx_pa_roundmode val)
+{
+       return ((val) << A2XX_PA_SU_VTX_CNTL_ROUND_MODE__SHIFT) & A2XX_PA_SU_VTX_CNTL_ROUND_MODE__MASK;
+}
+#define A2XX_PA_SU_VTX_CNTL_QUANT_MODE__MASK                   0x00000380
+#define A2XX_PA_SU_VTX_CNTL_QUANT_MODE__SHIFT                  7
+static inline uint32_t A2XX_PA_SU_VTX_CNTL_QUANT_MODE(enum a2xx_pa_quantmode val)
+{
+       return ((val) << A2XX_PA_SU_VTX_CNTL_QUANT_MODE__SHIFT) & A2XX_PA_SU_VTX_CNTL_QUANT_MODE__MASK;
+}
+
+#define REG_A2XX_PA_CL_GB_VERT_CLIP_ADJ                                0x00002303
+#define A2XX_PA_CL_GB_VERT_CLIP_ADJ__MASK                      0xffffffff
+#define A2XX_PA_CL_GB_VERT_CLIP_ADJ__SHIFT                     0
+static inline uint32_t A2XX_PA_CL_GB_VERT_CLIP_ADJ(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_GB_VERT_CLIP_ADJ__SHIFT) & A2XX_PA_CL_GB_VERT_CLIP_ADJ__MASK;
+}
+
+#define REG_A2XX_PA_CL_GB_VERT_DISC_ADJ                                0x00002304
+#define A2XX_PA_CL_GB_VERT_DISC_ADJ__MASK                      0xffffffff
+#define A2XX_PA_CL_GB_VERT_DISC_ADJ__SHIFT                     0
+static inline uint32_t A2XX_PA_CL_GB_VERT_DISC_ADJ(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_GB_VERT_DISC_ADJ__SHIFT) & A2XX_PA_CL_GB_VERT_DISC_ADJ__MASK;
+}
+
+#define REG_A2XX_PA_CL_GB_HORZ_CLIP_ADJ                                0x00002305
+#define A2XX_PA_CL_GB_HORZ_CLIP_ADJ__MASK                      0xffffffff
+#define A2XX_PA_CL_GB_HORZ_CLIP_ADJ__SHIFT                     0
+static inline uint32_t A2XX_PA_CL_GB_HORZ_CLIP_ADJ(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_GB_HORZ_CLIP_ADJ__SHIFT) & A2XX_PA_CL_GB_HORZ_CLIP_ADJ__MASK;
+}
+
+#define REG_A2XX_PA_CL_GB_HORZ_DISC_ADJ                                0x00002306
+#define A2XX_PA_CL_GB_HORZ_DISC_ADJ__MASK                      0xffffffff
+#define A2XX_PA_CL_GB_HORZ_DISC_ADJ__SHIFT                     0
+static inline uint32_t A2XX_PA_CL_GB_HORZ_DISC_ADJ(float val)
+{
+       return ((fui(val)) << A2XX_PA_CL_GB_HORZ_DISC_ADJ__SHIFT) & A2XX_PA_CL_GB_HORZ_DISC_ADJ__MASK;
+}
+
+#define REG_A2XX_SQ_VS_CONST                                   0x00002307
+#define A2XX_SQ_VS_CONST_BASE__MASK                            0x000001ff
+#define A2XX_SQ_VS_CONST_BASE__SHIFT                           0
+static inline uint32_t A2XX_SQ_VS_CONST_BASE(uint32_t val)
+{
+       return ((val) << A2XX_SQ_VS_CONST_BASE__SHIFT) & A2XX_SQ_VS_CONST_BASE__MASK;
+}
+#define A2XX_SQ_VS_CONST_SIZE__MASK                            0x001ff000
+#define A2XX_SQ_VS_CONST_SIZE__SHIFT                           12
+static inline uint32_t A2XX_SQ_VS_CONST_SIZE(uint32_t val)
+{
+       return ((val) << A2XX_SQ_VS_CONST_SIZE__SHIFT) & A2XX_SQ_VS_CONST_SIZE__MASK;
+}
+
+#define REG_A2XX_SQ_PS_CONST                                   0x00002308
+#define A2XX_SQ_PS_CONST_BASE__MASK                            0x000001ff
+#define A2XX_SQ_PS_CONST_BASE__SHIFT                           0
+static inline uint32_t A2XX_SQ_PS_CONST_BASE(uint32_t val)
+{
+       return ((val) << A2XX_SQ_PS_CONST_BASE__SHIFT) & A2XX_SQ_PS_CONST_BASE__MASK;
+}
+#define A2XX_SQ_PS_CONST_SIZE__MASK                            0x001ff000
+#define A2XX_SQ_PS_CONST_SIZE__SHIFT                           12
+static inline uint32_t A2XX_SQ_PS_CONST_SIZE(uint32_t val)
+{
+       return ((val) << A2XX_SQ_PS_CONST_SIZE__SHIFT) & A2XX_SQ_PS_CONST_SIZE__MASK;
+}
+
+#define REG_A2XX_SQ_DEBUG_MISC_0                               0x00002309
+
+#define REG_A2XX_SQ_DEBUG_MISC_1                               0x0000230a
+
+#define REG_A2XX_PA_SC_AA_MASK                                 0x00002312
+
+#define REG_A2XX_VGT_VERTEX_REUSE_BLOCK_CNTL                   0x00002316
+
+#define REG_A2XX_VGT_OUT_DEALLOC_CNTL                          0x00002317
+
+#define REG_A2XX_RB_COPY_CONTROL                               0x00002318
+#define A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__MASK          0x00000007
+#define A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__SHIFT         0
+static inline uint32_t A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT(enum a2xx_rb_copy_sample_select val)
+{
+       return ((val) << A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__SHIFT) & A2XX_RB_COPY_CONTROL_COPY_SAMPLE_SELECT__MASK;
+}
+#define A2XX_RB_COPY_CONTROL_DEPTH_CLEAR_ENABLE                        0x00000008
+#define A2XX_RB_COPY_CONTROL_CLEAR_MASK__MASK                  0x000000f0
+#define A2XX_RB_COPY_CONTROL_CLEAR_MASK__SHIFT                 4
+static inline uint32_t A2XX_RB_COPY_CONTROL_CLEAR_MASK(uint32_t val)
+{
+       return ((val) << A2XX_RB_COPY_CONTROL_CLEAR_MASK__SHIFT) & A2XX_RB_COPY_CONTROL_CLEAR_MASK__MASK;
+}
+
+#define REG_A2XX_RB_COPY_DEST_BASE                             0x00002319
+
+#define REG_A2XX_RB_COPY_DEST_PITCH                            0x0000231a
+#define A2XX_RB_COPY_DEST_PITCH__MASK                          0xffffffff
+#define A2XX_RB_COPY_DEST_PITCH__SHIFT                         0
+static inline uint32_t A2XX_RB_COPY_DEST_PITCH(uint32_t val)
+{
+       return ((val >> 5) << A2XX_RB_COPY_DEST_PITCH__SHIFT) & A2XX_RB_COPY_DEST_PITCH__MASK;
+}
+
+#define REG_A2XX_RB_COPY_DEST_INFO                             0x0000231b
+#define A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__MASK               0x00000007
+#define A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__SHIFT              0
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN(enum adreno_rb_surface_endian val)
+{
+       return ((val) << A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__SHIFT) & A2XX_RB_COPY_DEST_INFO_DEST_ENDIAN__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_LINEAR                          0x00000008
+#define A2XX_RB_COPY_DEST_INFO_FORMAT__MASK                    0x000000f0
+#define A2XX_RB_COPY_DEST_INFO_FORMAT__SHIFT                   4
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_FORMAT(enum a2xx_colorformatx val)
+{
+       return ((val) << A2XX_RB_COPY_DEST_INFO_FORMAT__SHIFT) & A2XX_RB_COPY_DEST_INFO_FORMAT__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_SWAP__MASK                      0x00000300
+#define A2XX_RB_COPY_DEST_INFO_SWAP__SHIFT                     8
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_SWAP(uint32_t val)
+{
+       return ((val) << A2XX_RB_COPY_DEST_INFO_SWAP__SHIFT) & A2XX_RB_COPY_DEST_INFO_SWAP__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK               0x00000c00
+#define A2XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT              10
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_DITHER_MODE(enum adreno_rb_dither_mode val)
+{
+       return ((val) << A2XX_RB_COPY_DEST_INFO_DITHER_MODE__SHIFT) & A2XX_RB_COPY_DEST_INFO_DITHER_MODE__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__MASK               0x00003000
+#define A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__SHIFT              12
+static inline uint32_t A2XX_RB_COPY_DEST_INFO_DITHER_TYPE(enum a2xx_rb_dither_type val)
+{
+       return ((val) << A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__SHIFT) & A2XX_RB_COPY_DEST_INFO_DITHER_TYPE__MASK;
+}
+#define A2XX_RB_COPY_DEST_INFO_WRITE_RED                       0x00004000
+#define A2XX_RB_COPY_DEST_INFO_WRITE_GREEN                     0x00008000
+#define A2XX_RB_COPY_DEST_INFO_WRITE_BLUE                      0x00010000
+#define A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA                     0x00020000
+
+#define REG_A2XX_RB_COPY_DEST_OFFSET                           0x0000231c
+#define A2XX_RB_COPY_DEST_OFFSET_X__MASK                       0x00001fff
+#define A2XX_RB_COPY_DEST_OFFSET_X__SHIFT                      0
+static inline uint32_t A2XX_RB_COPY_DEST_OFFSET_X(uint32_t val)
+{
+       return ((val) << A2XX_RB_COPY_DEST_OFFSET_X__SHIFT) & A2XX_RB_COPY_DEST_OFFSET_X__MASK;
+}
+#define A2XX_RB_COPY_DEST_OFFSET_Y__MASK                       0x03ffe000
+#define A2XX_RB_COPY_DEST_OFFSET_Y__SHIFT                      13
+static inline uint32_t A2XX_RB_COPY_DEST_OFFSET_Y(uint32_t val)
+{
+       return ((val) << A2XX_RB_COPY_DEST_OFFSET_Y__SHIFT) & A2XX_RB_COPY_DEST_OFFSET_Y__MASK;
+}
+
+#define REG_A2XX_RB_DEPTH_CLEAR                                        0x0000231d
+
+#define REG_A2XX_RB_SAMPLE_COUNT_CTL                           0x00002324
+
+#define REG_A2XX_RB_COLOR_DEST_MASK                            0x00002326
+
+#define REG_A2XX_A225_GRAS_UCP0X                               0x00002340
+
+#define REG_A2XX_A225_GRAS_UCP5W                               0x00002357
+
+#define REG_A2XX_A225_GRAS_UCP_ENABLED                         0x00002360
+
+#define REG_A2XX_PA_SU_POLY_OFFSET_FRONT_SCALE                 0x00002380
+
+#define REG_A2XX_PA_SU_POLY_OFFSET_BACK_OFFSET                 0x00002383
+
+#define REG_A2XX_SQ_CONSTANT_0                                 0x00004000
+
+#define REG_A2XX_SQ_FETCH_0                                    0x00004800
+
+#define REG_A2XX_SQ_CF_BOOLEANS                                        0x00004900
+
+#define REG_A2XX_SQ_CF_LOOP                                    0x00004908
+
+#define REG_A2XX_COHER_SIZE_PM4                                        0x00000a29
+
+#define REG_A2XX_COHER_BASE_PM4                                        0x00000a2a
+
+#define REG_A2XX_COHER_STATUS_PM4                              0x00000a2b
+
+#define REG_A2XX_SQ_TEX_0                                      0x00000000
+#define A2XX_SQ_TEX_0_CLAMP_X__MASK                            0x00001c00
+#define A2XX_SQ_TEX_0_CLAMP_X__SHIFT                           10
+static inline uint32_t A2XX_SQ_TEX_0_CLAMP_X(enum sq_tex_clamp val)
+{
+       return ((val) << A2XX_SQ_TEX_0_CLAMP_X__SHIFT) & A2XX_SQ_TEX_0_CLAMP_X__MASK;
+}
+#define A2XX_SQ_TEX_0_CLAMP_Y__MASK                            0x0000e000
+#define A2XX_SQ_TEX_0_CLAMP_Y__SHIFT                           13
+static inline uint32_t A2XX_SQ_TEX_0_CLAMP_Y(enum sq_tex_clamp val)
+{
+       return ((val) << A2XX_SQ_TEX_0_CLAMP_Y__SHIFT) & A2XX_SQ_TEX_0_CLAMP_Y__MASK;
+}
+#define A2XX_SQ_TEX_0_CLAMP_Z__MASK                            0x00070000
+#define A2XX_SQ_TEX_0_CLAMP_Z__SHIFT                           16
+static inline uint32_t A2XX_SQ_TEX_0_CLAMP_Z(enum sq_tex_clamp val)
+{
+       return ((val) << A2XX_SQ_TEX_0_CLAMP_Z__SHIFT) & A2XX_SQ_TEX_0_CLAMP_Z__MASK;
+}
+#define A2XX_SQ_TEX_0_PITCH__MASK                              0xffc00000
+#define A2XX_SQ_TEX_0_PITCH__SHIFT                             22
+static inline uint32_t A2XX_SQ_TEX_0_PITCH(uint32_t val)
+{
+       return ((val >> 5) << A2XX_SQ_TEX_0_PITCH__SHIFT) & A2XX_SQ_TEX_0_PITCH__MASK;
+}
+
+#define REG_A2XX_SQ_TEX_1                                      0x00000001
+
+#define REG_A2XX_SQ_TEX_2                                      0x00000002
+#define A2XX_SQ_TEX_2_WIDTH__MASK                              0x00001fff
+#define A2XX_SQ_TEX_2_WIDTH__SHIFT                             0
+static inline uint32_t A2XX_SQ_TEX_2_WIDTH(uint32_t val)
+{
+       return ((val) << A2XX_SQ_TEX_2_WIDTH__SHIFT) & A2XX_SQ_TEX_2_WIDTH__MASK;
+}
+#define A2XX_SQ_TEX_2_HEIGHT__MASK                             0x03ffe000
+#define A2XX_SQ_TEX_2_HEIGHT__SHIFT                            13
+static inline uint32_t A2XX_SQ_TEX_2_HEIGHT(uint32_t val)
+{
+       return ((val) << A2XX_SQ_TEX_2_HEIGHT__SHIFT) & A2XX_SQ_TEX_2_HEIGHT__MASK;
+}
+
+#define REG_A2XX_SQ_TEX_3                                      0x00000003
+#define A2XX_SQ_TEX_3_SWIZ_X__MASK                             0x0000000e
+#define A2XX_SQ_TEX_3_SWIZ_X__SHIFT                            1
+static inline uint32_t A2XX_SQ_TEX_3_SWIZ_X(enum sq_tex_swiz val)
+{
+       return ((val) << A2XX_SQ_TEX_3_SWIZ_X__SHIFT) & A2XX_SQ_TEX_3_SWIZ_X__MASK;
+}
+#define A2XX_SQ_TEX_3_SWIZ_Y__MASK                             0x00000070
+#define A2XX_SQ_TEX_3_SWIZ_Y__SHIFT                            4
+static inline uint32_t A2XX_SQ_TEX_3_SWIZ_Y(enum sq_tex_swiz val)
+{
+       return ((val) << A2XX_SQ_TEX_3_SWIZ_Y__SHIFT) & A2XX_SQ_TEX_3_SWIZ_Y__MASK;
+}
+#define A2XX_SQ_TEX_3_SWIZ_Z__MASK                             0x00000380
+#define A2XX_SQ_TEX_3_SWIZ_Z__SHIFT                            7
+static inline uint32_t A2XX_SQ_TEX_3_SWIZ_Z(enum sq_tex_swiz val)
+{
+       return ((val) << A2XX_SQ_TEX_3_SWIZ_Z__SHIFT) & A2XX_SQ_TEX_3_SWIZ_Z__MASK;
+}
+#define A2XX_SQ_TEX_3_SWIZ_W__MASK                             0x00001c00
+#define A2XX_SQ_TEX_3_SWIZ_W__SHIFT                            10
+static inline uint32_t A2XX_SQ_TEX_3_SWIZ_W(enum sq_tex_swiz val)
+{
+       return ((val) << A2XX_SQ_TEX_3_SWIZ_W__SHIFT) & A2XX_SQ_TEX_3_SWIZ_W__MASK;
+}
+#define A2XX_SQ_TEX_3_XY_MAG_FILTER__MASK                      0x00180000
+#define A2XX_SQ_TEX_3_XY_MAG_FILTER__SHIFT                     19
+static inline uint32_t A2XX_SQ_TEX_3_XY_MAG_FILTER(enum sq_tex_filter val)
+{
+       return ((val) << A2XX_SQ_TEX_3_XY_MAG_FILTER__SHIFT) & A2XX_SQ_TEX_3_XY_MAG_FILTER__MASK;
+}
+#define A2XX_SQ_TEX_3_XY_MIN_FILTER__MASK                      0x00600000
+#define A2XX_SQ_TEX_3_XY_MIN_FILTER__SHIFT                     21
+static inline uint32_t A2XX_SQ_TEX_3_XY_MIN_FILTER(enum sq_tex_filter val)
+{
+       return ((val) << A2XX_SQ_TEX_3_XY_MIN_FILTER__SHIFT) & A2XX_SQ_TEX_3_XY_MIN_FILTER__MASK;
+}
+
+
+#endif /* A2XX_XML */
diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h
new file mode 100644 (file)
index 0000000..d183516
--- /dev/null
@@ -0,0 +1,2193 @@
+#ifndef A3XX_XML
+#define A3XX_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml              (    327 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml           (  30005 bytes, from 2013-07-19 21:30:48)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml       (   8983 bytes, from 2013-07-24 01:38:36)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9712 bytes, from 2013-05-26 15:22:37)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51415 bytes, from 2013-08-03 14:26:05)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+enum a3xx_render_mode {
+       RB_RENDERING_PASS = 0,
+       RB_TILING_PASS = 1,
+       RB_RESOLVE_PASS = 2,
+};
+
+enum a3xx_tile_mode {
+       LINEAR = 0,
+       TILE_32X32 = 2,
+};
+
+enum a3xx_threadmode {
+       MULTI = 0,
+       SINGLE = 1,
+};
+
+enum a3xx_instrbuffermode {
+       BUFFER = 1,
+};
+
+enum a3xx_threadsize {
+       TWO_QUADS = 0,
+       FOUR_QUADS = 1,
+};
+
+enum a3xx_state_block_id {
+       HLSQ_BLOCK_ID_TP_TEX = 2,
+       HLSQ_BLOCK_ID_TP_MIPMAP = 3,
+       HLSQ_BLOCK_ID_SP_VS = 4,
+       HLSQ_BLOCK_ID_SP_FS = 6,
+};
+
+enum a3xx_cache_opcode {
+       INVALIDATE = 1,
+};
+
+enum a3xx_vtx_fmt {
+       VFMT_FLOAT_32 = 0,
+       VFMT_FLOAT_32_32 = 1,
+       VFMT_FLOAT_32_32_32 = 2,
+       VFMT_FLOAT_32_32_32_32 = 3,
+       VFMT_FLOAT_16 = 4,
+       VFMT_FLOAT_16_16 = 5,
+       VFMT_FLOAT_16_16_16 = 6,
+       VFMT_FLOAT_16_16_16_16 = 7,
+       VFMT_FIXED_32 = 8,
+       VFMT_FIXED_32_32 = 9,
+       VFMT_FIXED_32_32_32 = 10,
+       VFMT_FIXED_32_32_32_32 = 11,
+       VFMT_SHORT_16 = 16,
+       VFMT_SHORT_16_16 = 17,
+       VFMT_SHORT_16_16_16 = 18,
+       VFMT_SHORT_16_16_16_16 = 19,
+       VFMT_USHORT_16 = 20,
+       VFMT_USHORT_16_16 = 21,
+       VFMT_USHORT_16_16_16 = 22,
+       VFMT_USHORT_16_16_16_16 = 23,
+       VFMT_NORM_SHORT_16 = 24,
+       VFMT_NORM_SHORT_16_16 = 25,
+       VFMT_NORM_SHORT_16_16_16 = 26,
+       VFMT_NORM_SHORT_16_16_16_16 = 27,
+       VFMT_NORM_USHORT_16 = 28,
+       VFMT_NORM_USHORT_16_16 = 29,
+       VFMT_NORM_USHORT_16_16_16 = 30,
+       VFMT_NORM_USHORT_16_16_16_16 = 31,
+       VFMT_UBYTE_8 = 40,
+       VFMT_UBYTE_8_8 = 41,
+       VFMT_UBYTE_8_8_8 = 42,
+       VFMT_UBYTE_8_8_8_8 = 43,
+       VFMT_NORM_UBYTE_8 = 44,
+       VFMT_NORM_UBYTE_8_8 = 45,
+       VFMT_NORM_UBYTE_8_8_8 = 46,
+       VFMT_NORM_UBYTE_8_8_8_8 = 47,
+       VFMT_BYTE_8 = 48,
+       VFMT_BYTE_8_8 = 49,
+       VFMT_BYTE_8_8_8 = 50,
+       VFMT_BYTE_8_8_8_8 = 51,
+       VFMT_NORM_BYTE_8 = 52,
+       VFMT_NORM_BYTE_8_8 = 53,
+       VFMT_NORM_BYTE_8_8_8 = 54,
+       VFMT_NORM_BYTE_8_8_8_8 = 55,
+       VFMT_UINT_10_10_10_2 = 60,
+       VFMT_NORM_UINT_10_10_10_2 = 61,
+       VFMT_INT_10_10_10_2 = 62,
+       VFMT_NORM_INT_10_10_10_2 = 63,
+};
+
+enum a3xx_tex_fmt {
+       TFMT_NORM_USHORT_565 = 4,
+       TFMT_NORM_USHORT_5551 = 6,
+       TFMT_NORM_USHORT_4444 = 7,
+       TFMT_NORM_UINT_X8Z24 = 10,
+       TFMT_NORM_UINT_NV12_UV_TILED = 17,
+       TFMT_NORM_UINT_NV12_Y_TILED = 19,
+       TFMT_NORM_UINT_NV12_UV = 21,
+       TFMT_NORM_UINT_NV12_Y = 23,
+       TFMT_NORM_UINT_I420_Y = 24,
+       TFMT_NORM_UINT_I420_U = 26,
+       TFMT_NORM_UINT_I420_V = 27,
+       TFMT_NORM_UINT_2_10_10_10 = 41,
+       TFMT_NORM_UINT_A8 = 44,
+       TFMT_NORM_UINT_L8_A8 = 47,
+       TFMT_NORM_UINT_8 = 48,
+       TFMT_NORM_UINT_8_8 = 49,
+       TFMT_NORM_UINT_8_8_8 = 50,
+       TFMT_NORM_UINT_8_8_8_8 = 51,
+       TFMT_FLOAT_16 = 64,
+       TFMT_FLOAT_16_16 = 65,
+       TFMT_FLOAT_16_16_16_16 = 67,
+       TFMT_FLOAT_32 = 84,
+       TFMT_FLOAT_32_32 = 85,
+       TFMT_FLOAT_32_32_32_32 = 87,
+};
+
+enum a3xx_tex_fetchsize {
+       TFETCH_DISABLE = 0,
+       TFETCH_1_BYTE = 1,
+       TFETCH_2_BYTE = 2,
+       TFETCH_4_BYTE = 3,
+       TFETCH_8_BYTE = 4,
+       TFETCH_16_BYTE = 5,
+};
+
+enum a3xx_color_fmt {
+       RB_R8G8B8_UNORM = 4,
+       RB_R8G8B8A8_UNORM = 8,
+       RB_Z16_UNORM = 12,
+       RB_A8_UNORM = 20,
+};
+
+enum a3xx_color_swap {
+       WZYX = 0,
+       WXYZ = 1,
+       ZYXW = 2,
+       XYZW = 3,
+};
+
+enum a3xx_msaa_samples {
+       MSAA_ONE = 0,
+       MSAA_TWO = 1,
+       MSAA_FOUR = 2,
+};
+
+enum a3xx_sp_perfcounter_select {
+       SP_FS_CFLOW_INSTRUCTIONS = 12,
+       SP_FS_FULL_ALU_INSTRUCTIONS = 14,
+       SP0_ICL1_MISSES = 26,
+       SP_ALU_ACTIVE_CYCLES = 29,
+};
+
+enum adreno_rb_copy_control_mode {
+       RB_COPY_RESOLVE = 1,
+       RB_COPY_DEPTH_STENCIL = 5,
+};
+
+enum a3xx_tex_filter {
+       A3XX_TEX_NEAREST = 0,
+       A3XX_TEX_LINEAR = 1,
+};
+
+enum a3xx_tex_clamp {
+       A3XX_TEX_REPEAT = 0,
+       A3XX_TEX_CLAMP_TO_EDGE = 1,
+       A3XX_TEX_MIRROR_REPEAT = 2,
+       A3XX_TEX_CLAMP_NONE = 3,
+};
+
+enum a3xx_tex_swiz {
+       A3XX_TEX_X = 0,
+       A3XX_TEX_Y = 1,
+       A3XX_TEX_Z = 2,
+       A3XX_TEX_W = 3,
+       A3XX_TEX_ZERO = 4,
+       A3XX_TEX_ONE = 5,
+};
+
+enum a3xx_tex_type {
+       A3XX_TEX_1D = 0,
+       A3XX_TEX_2D = 1,
+       A3XX_TEX_CUBE = 2,
+       A3XX_TEX_3D = 3,
+};
+
+#define A3XX_INT0_RBBM_GPU_IDLE                                        0x00000001
+#define A3XX_INT0_RBBM_AHB_ERROR                               0x00000002
+#define A3XX_INT0_RBBM_REG_TIMEOUT                             0x00000004
+#define A3XX_INT0_RBBM_ME_MS_TIMEOUT                           0x00000008
+#define A3XX_INT0_RBBM_PFP_MS_TIMEOUT                          0x00000010
+#define A3XX_INT0_RBBM_ATB_BUS_OVERFLOW                                0x00000020
+#define A3XX_INT0_VFD_ERROR                                    0x00000040
+#define A3XX_INT0_CP_SW_INT                                    0x00000080
+#define A3XX_INT0_CP_T0_PACKET_IN_IB                           0x00000100
+#define A3XX_INT0_CP_OPCODE_ERROR                              0x00000200
+#define A3XX_INT0_CP_RESERVED_BIT_ERROR                                0x00000400
+#define A3XX_INT0_CP_HW_FAULT                                  0x00000800
+#define A3XX_INT0_CP_DMA                                       0x00001000
+#define A3XX_INT0_CP_IB2_INT                                   0x00002000
+#define A3XX_INT0_CP_IB1_INT                                   0x00004000
+#define A3XX_INT0_CP_RB_INT                                    0x00008000
+#define A3XX_INT0_CP_REG_PROTECT_FAULT                         0x00010000
+#define A3XX_INT0_CP_RB_DONE_TS                                        0x00020000
+#define A3XX_INT0_CP_VS_DONE_TS                                        0x00040000
+#define A3XX_INT0_CP_PS_DONE_TS                                        0x00080000
+#define A3XX_INT0_CACHE_FLUSH_TS                               0x00100000
+#define A3XX_INT0_CP_AHB_ERROR_HALT                            0x00200000
+#define A3XX_INT0_MISC_HANG_DETECT                             0x01000000
+#define A3XX_INT0_UCHE_OOB_ACCESS                              0x02000000
+#define REG_A3XX_RBBM_HW_VERSION                               0x00000000
+
+#define REG_A3XX_RBBM_HW_RELEASE                               0x00000001
+
+#define REG_A3XX_RBBM_HW_CONFIGURATION                         0x00000002
+
+#define REG_A3XX_RBBM_CLOCK_CTL                                        0x00000010
+
+#define REG_A3XX_RBBM_SP_HYST_CNT                              0x00000012
+
+#define REG_A3XX_RBBM_SW_RESET_CMD                             0x00000018
+
+#define REG_A3XX_RBBM_AHB_CTL0                                 0x00000020
+
+#define REG_A3XX_RBBM_AHB_CTL1                                 0x00000021
+
+#define REG_A3XX_RBBM_AHB_CMD                                  0x00000022
+
+#define REG_A3XX_RBBM_AHB_ERROR_STATUS                         0x00000027
+
+#define REG_A3XX_RBBM_GPR0_CTL                                 0x0000002e
+
+#define REG_A3XX_RBBM_STATUS                                   0x00000030
+#define A3XX_RBBM_STATUS_HI_BUSY                               0x00000001
+#define A3XX_RBBM_STATUS_CP_ME_BUSY                            0x00000002
+#define A3XX_RBBM_STATUS_CP_PFP_BUSY                           0x00000004
+#define A3XX_RBBM_STATUS_CP_NRT_BUSY                           0x00004000
+#define A3XX_RBBM_STATUS_VBIF_BUSY                             0x00008000
+#define A3XX_RBBM_STATUS_TSE_BUSY                              0x00010000
+#define A3XX_RBBM_STATUS_RAS_BUSY                              0x00020000
+#define A3XX_RBBM_STATUS_RB_BUSY                               0x00040000
+#define A3XX_RBBM_STATUS_PC_DCALL_BUSY                         0x00080000
+#define A3XX_RBBM_STATUS_PC_VSD_BUSY                           0x00100000
+#define A3XX_RBBM_STATUS_VFD_BUSY                              0x00200000
+#define A3XX_RBBM_STATUS_VPC_BUSY                              0x00400000
+#define A3XX_RBBM_STATUS_UCHE_BUSY                             0x00800000
+#define A3XX_RBBM_STATUS_SP_BUSY                               0x01000000
+#define A3XX_RBBM_STATUS_TPL1_BUSY                             0x02000000
+#define A3XX_RBBM_STATUS_MARB_BUSY                             0x04000000
+#define A3XX_RBBM_STATUS_VSC_BUSY                              0x08000000
+#define A3XX_RBBM_STATUS_ARB_BUSY                              0x10000000
+#define A3XX_RBBM_STATUS_HLSQ_BUSY                             0x20000000
+#define A3XX_RBBM_STATUS_GPU_BUSY_NOHC                         0x40000000
+#define A3XX_RBBM_STATUS_GPU_BUSY                              0x80000000
+
+#define REG_A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL                     0x00000033
+
+#define REG_A3XX_RBBM_INTERFACE_HANG_INT_CTL                   0x00000050
+
+#define REG_A3XX_RBBM_INTERFACE_HANG_MASK_CTL0                 0x00000051
+
+#define REG_A3XX_RBBM_INTERFACE_HANG_MASK_CTL1                 0x00000054
+
+#define REG_A3XX_RBBM_INTERFACE_HANG_MASK_CTL2                 0x00000057
+
+#define REG_A3XX_RBBM_INTERFACE_HANG_MASK_CTL3                 0x0000005a
+
+#define REG_A3XX_RBBM_INT_CLEAR_CMD                            0x00000061
+
+#define REG_A3XX_RBBM_INT_0_MASK                               0x00000063
+
+#define REG_A3XX_RBBM_INT_0_STATUS                             0x00000064
+
+#define REG_A3XX_RBBM_PERFCTR_CTL                              0x00000080
+
+#define REG_A3XX_RBBM_PERFCTR_LOAD_CMD0                                0x00000081
+
+#define REG_A3XX_RBBM_PERFCTR_LOAD_CMD1                                0x00000082
+
+#define REG_A3XX_RBBM_PERFCTR_LOAD_VALUE_LO                    0x00000084
+
+#define REG_A3XX_RBBM_PERFCTR_LOAD_VALUE_HI                    0x00000085
+
+#define REG_A3XX_RBBM_PERFCOUNTER0_SELECT                      0x00000086
+
+#define REG_A3XX_RBBM_PERFCOUNTER1_SELECT                      0x00000087
+
+#define REG_A3XX_RBBM_GPU_BUSY_MASKED                          0x00000088
+
+#define REG_A3XX_RBBM_PERFCTR_CP_0_LO                          0x00000090
+
+#define REG_A3XX_RBBM_PERFCTR_CP_0_HI                          0x00000091
+
+#define REG_A3XX_RBBM_PERFCTR_RBBM_0_LO                                0x00000092
+
+#define REG_A3XX_RBBM_PERFCTR_RBBM_0_HI                                0x00000093
+
+#define REG_A3XX_RBBM_PERFCTR_RBBM_1_LO                                0x00000094
+
+#define REG_A3XX_RBBM_PERFCTR_RBBM_1_HI                                0x00000095
+
+#define REG_A3XX_RBBM_PERFCTR_PC_0_LO                          0x00000096
+
+#define REG_A3XX_RBBM_PERFCTR_PC_0_HI                          0x00000097
+
+#define REG_A3XX_RBBM_PERFCTR_PC_1_LO                          0x00000098
+
+#define REG_A3XX_RBBM_PERFCTR_PC_1_HI                          0x00000099
+
+#define REG_A3XX_RBBM_PERFCTR_PC_2_LO                          0x0000009a
+
+#define REG_A3XX_RBBM_PERFCTR_PC_2_HI                          0x0000009b
+
+#define REG_A3XX_RBBM_PERFCTR_PC_3_LO                          0x0000009c
+
+#define REG_A3XX_RBBM_PERFCTR_PC_3_HI                          0x0000009d
+
+#define REG_A3XX_RBBM_PERFCTR_VFD_0_LO                         0x0000009e
+
+#define REG_A3XX_RBBM_PERFCTR_VFD_0_HI                         0x0000009f
+
+#define REG_A3XX_RBBM_PERFCTR_VFD_1_LO                         0x000000a0
+
+#define REG_A3XX_RBBM_PERFCTR_VFD_1_HI                         0x000000a1
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_0_LO                                0x000000a2
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_0_HI                                0x000000a3
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_1_LO                                0x000000a4
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_1_HI                                0x000000a5
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_2_LO                                0x000000a6
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_2_HI                                0x000000a7
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_3_LO                                0x000000a8
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_3_HI                                0x000000a9
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_4_LO                                0x000000aa
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_4_HI                                0x000000ab
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_5_LO                                0x000000ac
+
+#define REG_A3XX_RBBM_PERFCTR_HLSQ_5_HI                                0x000000ad
+
+#define REG_A3XX_RBBM_PERFCTR_VPC_0_LO                         0x000000ae
+
+#define REG_A3XX_RBBM_PERFCTR_VPC_0_HI                         0x000000af
+
+#define REG_A3XX_RBBM_PERFCTR_VPC_1_LO                         0x000000b0
+
+#define REG_A3XX_RBBM_PERFCTR_VPC_1_HI                         0x000000b1
+
+#define REG_A3XX_RBBM_PERFCTR_TSE_0_LO                         0x000000b2
+
+#define REG_A3XX_RBBM_PERFCTR_TSE_0_HI                         0x000000b3
+
+#define REG_A3XX_RBBM_PERFCTR_TSE_1_LO                         0x000000b4
+
+#define REG_A3XX_RBBM_PERFCTR_TSE_1_HI                         0x000000b5
+
+#define REG_A3XX_RBBM_PERFCTR_RAS_0_LO                         0x000000b6
+
+#define REG_A3XX_RBBM_PERFCTR_RAS_0_HI                         0x000000b7
+
+#define REG_A3XX_RBBM_PERFCTR_RAS_1_LO                         0x000000b8
+
+#define REG_A3XX_RBBM_PERFCTR_RAS_1_HI                         0x000000b9
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_0_LO                                0x000000ba
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_0_HI                                0x000000bb
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_1_LO                                0x000000bc
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_1_HI                                0x000000bd
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_2_LO                                0x000000be
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_2_HI                                0x000000bf
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_3_LO                                0x000000c0
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_3_HI                                0x000000c1
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_4_LO                                0x000000c2
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_4_HI                                0x000000c3
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_5_LO                                0x000000c4
+
+#define REG_A3XX_RBBM_PERFCTR_UCHE_5_HI                                0x000000c5
+
+#define REG_A3XX_RBBM_PERFCTR_TP_0_LO                          0x000000c6
+
+#define REG_A3XX_RBBM_PERFCTR_TP_0_HI                          0x000000c7
+
+#define REG_A3XX_RBBM_PERFCTR_TP_1_LO                          0x000000c8
+
+#define REG_A3XX_RBBM_PERFCTR_TP_1_HI                          0x000000c9
+
+#define REG_A3XX_RBBM_PERFCTR_TP_2_LO                          0x000000ca
+
+#define REG_A3XX_RBBM_PERFCTR_TP_2_HI                          0x000000cb
+
+#define REG_A3XX_RBBM_PERFCTR_TP_3_LO                          0x000000cc
+
+#define REG_A3XX_RBBM_PERFCTR_TP_3_HI                          0x000000cd
+
+#define REG_A3XX_RBBM_PERFCTR_TP_4_LO                          0x000000ce
+
+#define REG_A3XX_RBBM_PERFCTR_TP_4_HI                          0x000000cf
+
+#define REG_A3XX_RBBM_PERFCTR_TP_5_LO                          0x000000d0
+
+#define REG_A3XX_RBBM_PERFCTR_TP_5_HI                          0x000000d1
+
+#define REG_A3XX_RBBM_PERFCTR_SP_0_LO                          0x000000d2
+
+#define REG_A3XX_RBBM_PERFCTR_SP_0_HI                          0x000000d3
+
+#define REG_A3XX_RBBM_PERFCTR_SP_1_LO                          0x000000d4
+
+#define REG_A3XX_RBBM_PERFCTR_SP_1_HI                          0x000000d5
+
+#define REG_A3XX_RBBM_PERFCTR_SP_2_LO                          0x000000d6
+
+#define REG_A3XX_RBBM_PERFCTR_SP_2_HI                          0x000000d7
+
+#define REG_A3XX_RBBM_PERFCTR_SP_3_LO                          0x000000d8
+
+#define REG_A3XX_RBBM_PERFCTR_SP_3_HI                          0x000000d9
+
+#define REG_A3XX_RBBM_PERFCTR_SP_4_LO                          0x000000da
+
+#define REG_A3XX_RBBM_PERFCTR_SP_4_HI                          0x000000db
+
+#define REG_A3XX_RBBM_PERFCTR_SP_5_LO                          0x000000dc
+
+#define REG_A3XX_RBBM_PERFCTR_SP_5_HI                          0x000000dd
+
+#define REG_A3XX_RBBM_PERFCTR_SP_6_LO                          0x000000de
+
+#define REG_A3XX_RBBM_PERFCTR_SP_6_HI                          0x000000df
+
+#define REG_A3XX_RBBM_PERFCTR_SP_7_LO                          0x000000e0
+
+#define REG_A3XX_RBBM_PERFCTR_SP_7_HI                          0x000000e1
+
+#define REG_A3XX_RBBM_PERFCTR_RB_0_LO                          0x000000e2
+
+#define REG_A3XX_RBBM_PERFCTR_RB_0_HI                          0x000000e3
+
+#define REG_A3XX_RBBM_PERFCTR_RB_1_LO                          0x000000e4
+
+#define REG_A3XX_RBBM_PERFCTR_RB_1_HI                          0x000000e5
+
+#define REG_A3XX_RBBM_PERFCTR_PWR_0_LO                         0x000000ea
+
+#define REG_A3XX_RBBM_PERFCTR_PWR_0_HI                         0x000000eb
+
+#define REG_A3XX_RBBM_PERFCTR_PWR_1_LO                         0x000000ec
+
+#define REG_A3XX_RBBM_PERFCTR_PWR_1_HI                         0x000000ed
+
+#define REG_A3XX_RBBM_RBBM_CTL                                 0x00000100
+
+#define REG_A3XX_RBBM_DEBUG_BUS_CTL                            0x00000111
+
+#define REG_A3XX_RBBM_DEBUG_BUS_DATA_STATUS                    0x00000112
+
+#define REG_A3XX_CP_PFP_UCODE_ADDR                             0x000001c9
+
+#define REG_A3XX_CP_PFP_UCODE_DATA                             0x000001ca
+
+#define REG_A3XX_CP_ROQ_ADDR                                   0x000001cc
+
+#define REG_A3XX_CP_ROQ_DATA                                   0x000001cd
+
+#define REG_A3XX_CP_MERCIU_ADDR                                        0x000001d1
+
+#define REG_A3XX_CP_MERCIU_DATA                                        0x000001d2
+
+#define REG_A3XX_CP_MERCIU_DATA2                               0x000001d3
+
+#define REG_A3XX_CP_MEQ_ADDR                                   0x000001da
+
+#define REG_A3XX_CP_MEQ_DATA                                   0x000001db
+
+#define REG_A3XX_CP_PERFCOUNTER_SELECT                         0x00000445
+
+#define REG_A3XX_CP_HW_FAULT                                   0x0000045c
+
+#define REG_A3XX_CP_PROTECT_CTRL                               0x0000045e
+
+#define REG_A3XX_CP_PROTECT_STATUS                             0x0000045f
+
+static inline uint32_t REG_A3XX_CP_PROTECT(uint32_t i0) { return 0x00000460 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_CP_PROTECT_REG(uint32_t i0) { return 0x00000460 + 0x1*i0; }
+
+#define REG_A3XX_CP_AHB_FAULT                                  0x0000054d
+
+#define REG_A3XX_GRAS_CL_CLIP_CNTL                             0x00002040
+#define A3XX_GRAS_CL_CLIP_CNTL_IJ_PERSP_CENTER                 0x00001000
+#define A3XX_GRAS_CL_CLIP_CNTL_CLIP_DISABLE                    0x00010000
+#define A3XX_GRAS_CL_CLIP_CNTL_ZFAR_CLIP_DISABLE               0x00020000
+#define A3XX_GRAS_CL_CLIP_CNTL_VP_CLIP_CODE_IGNORE             0x00080000
+#define A3XX_GRAS_CL_CLIP_CNTL_VP_XFORM_DISABLE                        0x00100000
+#define A3XX_GRAS_CL_CLIP_CNTL_PERSP_DIVISION_DISABLE          0x00200000
+
+#define REG_A3XX_GRAS_CL_GB_CLIP_ADJ                           0x00002044
+#define A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ__MASK                    0x000003ff
+#define A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ__SHIFT                   0
+static inline uint32_t A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ__SHIFT) & A3XX_GRAS_CL_GB_CLIP_ADJ_HORZ__MASK;
+}
+#define A3XX_GRAS_CL_GB_CLIP_ADJ_VERT__MASK                    0x000ffc00
+#define A3XX_GRAS_CL_GB_CLIP_ADJ_VERT__SHIFT                   10
+static inline uint32_t A3XX_GRAS_CL_GB_CLIP_ADJ_VERT(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_CL_GB_CLIP_ADJ_VERT__SHIFT) & A3XX_GRAS_CL_GB_CLIP_ADJ_VERT__MASK;
+}
+
+#define REG_A3XX_GRAS_CL_VPORT_XOFFSET                         0x00002048
+#define A3XX_GRAS_CL_VPORT_XOFFSET__MASK                       0xffffffff
+#define A3XX_GRAS_CL_VPORT_XOFFSET__SHIFT                      0
+static inline uint32_t A3XX_GRAS_CL_VPORT_XOFFSET(float val)
+{
+       return ((fui(val)) << A3XX_GRAS_CL_VPORT_XOFFSET__SHIFT) & A3XX_GRAS_CL_VPORT_XOFFSET__MASK;
+}
+
+#define REG_A3XX_GRAS_CL_VPORT_XSCALE                          0x00002049
+#define A3XX_GRAS_CL_VPORT_XSCALE__MASK                                0xffffffff
+#define A3XX_GRAS_CL_VPORT_XSCALE__SHIFT                       0
+static inline uint32_t A3XX_GRAS_CL_VPORT_XSCALE(float val)
+{
+       return ((fui(val)) << A3XX_GRAS_CL_VPORT_XSCALE__SHIFT) & A3XX_GRAS_CL_VPORT_XSCALE__MASK;
+}
+
+#define REG_A3XX_GRAS_CL_VPORT_YOFFSET                         0x0000204a
+#define A3XX_GRAS_CL_VPORT_YOFFSET__MASK                       0xffffffff
+#define A3XX_GRAS_CL_VPORT_YOFFSET__SHIFT                      0
+static inline uint32_t A3XX_GRAS_CL_VPORT_YOFFSET(float val)
+{
+       return ((fui(val)) << A3XX_GRAS_CL_VPORT_YOFFSET__SHIFT) & A3XX_GRAS_CL_VPORT_YOFFSET__MASK;
+}
+
+#define REG_A3XX_GRAS_CL_VPORT_YSCALE                          0x0000204b
+#define A3XX_GRAS_CL_VPORT_YSCALE__MASK                                0xffffffff
+#define A3XX_GRAS_CL_VPORT_YSCALE__SHIFT                       0
+static inline uint32_t A3XX_GRAS_CL_VPORT_YSCALE(float val)
+{
+       return ((fui(val)) << A3XX_GRAS_CL_VPORT_YSCALE__SHIFT) & A3XX_GRAS_CL_VPORT_YSCALE__MASK;
+}
+
+#define REG_A3XX_GRAS_CL_VPORT_ZOFFSET                         0x0000204c
+#define A3XX_GRAS_CL_VPORT_ZOFFSET__MASK                       0xffffffff
+#define A3XX_GRAS_CL_VPORT_ZOFFSET__SHIFT                      0
+static inline uint32_t A3XX_GRAS_CL_VPORT_ZOFFSET(float val)
+{
+       return ((fui(val)) << A3XX_GRAS_CL_VPORT_ZOFFSET__SHIFT) & A3XX_GRAS_CL_VPORT_ZOFFSET__MASK;
+}
+
+#define REG_A3XX_GRAS_CL_VPORT_ZSCALE                          0x0000204d
+#define A3XX_GRAS_CL_VPORT_ZSCALE__MASK                                0xffffffff
+#define A3XX_GRAS_CL_VPORT_ZSCALE__SHIFT                       0
+static inline uint32_t A3XX_GRAS_CL_VPORT_ZSCALE(float val)
+{
+       return ((fui(val)) << A3XX_GRAS_CL_VPORT_ZSCALE__SHIFT) & A3XX_GRAS_CL_VPORT_ZSCALE__MASK;
+}
+
+#define REG_A3XX_GRAS_SU_POINT_MINMAX                          0x00002068
+
+#define REG_A3XX_GRAS_SU_POINT_SIZE                            0x00002069
+
+#define REG_A3XX_GRAS_SU_POLY_OFFSET_SCALE                     0x0000206c
+#define A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK               0x00ffffff
+#define A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT              0
+static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL(float val)
+{
+       return ((((uint32_t)(val * 40.0))) << A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_SCALE_VAL__MASK;
+}
+
+#define REG_A3XX_GRAS_SU_POLY_OFFSET_OFFSET                    0x0000206d
+#define A3XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK                  0xffffffff
+#define A3XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT                 0
+static inline uint32_t A3XX_GRAS_SU_POLY_OFFSET_OFFSET(float val)
+{
+       return ((((uint32_t)(val * 44.0))) << A3XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A3XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK;
+}
+
+#define REG_A3XX_GRAS_SU_MODE_CONTROL                          0x00002070
+#define A3XX_GRAS_SU_MODE_CONTROL_CULL_FRONT                   0x00000001
+#define A3XX_GRAS_SU_MODE_CONTROL_CULL_BACK                    0x00000002
+#define A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK          0x000007fc
+#define A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT         2
+static inline uint32_t A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A3XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK;
+}
+#define A3XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET                  0x00000800
+
+#define REG_A3XX_GRAS_SC_CONTROL                               0x00002072
+#define A3XX_GRAS_SC_CONTROL_RENDER_MODE__MASK                 0x000000f0
+#define A3XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT                        4
+static inline uint32_t A3XX_GRAS_SC_CONTROL_RENDER_MODE(enum a3xx_render_mode val)
+{
+       return ((val) << A3XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT) & A3XX_GRAS_SC_CONTROL_RENDER_MODE__MASK;
+}
+#define A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK                        0x00000f00
+#define A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT               8
+static inline uint32_t A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES(enum a3xx_msaa_samples val)
+{
+       return ((val) << A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT) & A3XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK;
+}
+#define A3XX_GRAS_SC_CONTROL_RASTER_MODE__MASK                 0x0000f000
+#define A3XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT                        12
+static inline uint32_t A3XX_GRAS_SC_CONTROL_RASTER_MODE(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT) & A3XX_GRAS_SC_CONTROL_RASTER_MODE__MASK;
+}
+
+#define REG_A3XX_GRAS_SC_SCREEN_SCISSOR_TL                     0x00002074
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_TL_WINDOW_OFFSET_DISABLE   0x80000000
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X__MASK                 0x00007fff
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X__SHIFT                        0
+static inline uint32_t A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X__SHIFT) & A3XX_GRAS_SC_SCREEN_SCISSOR_TL_X__MASK;
+}
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y__MASK                 0x7fff0000
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y__SHIFT                        16
+static inline uint32_t A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y__SHIFT) & A3XX_GRAS_SC_SCREEN_SCISSOR_TL_Y__MASK;
+}
+
+#define REG_A3XX_GRAS_SC_SCREEN_SCISSOR_BR                     0x00002075
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_BR_WINDOW_OFFSET_DISABLE   0x80000000
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X__MASK                 0x00007fff
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X__SHIFT                        0
+static inline uint32_t A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X__SHIFT) & A3XX_GRAS_SC_SCREEN_SCISSOR_BR_X__MASK;
+}
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y__MASK                 0x7fff0000
+#define A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y__SHIFT                        16
+static inline uint32_t A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y__SHIFT) & A3XX_GRAS_SC_SCREEN_SCISSOR_BR_Y__MASK;
+}
+
+#define REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL                     0x00002079
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_TL_WINDOW_OFFSET_DISABLE   0x80000000
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X__MASK                 0x00007fff
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X__SHIFT                        0
+static inline uint32_t A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X__SHIFT) & A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X__MASK;
+}
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__MASK                 0x7fff0000
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__SHIFT                        16
+static inline uint32_t A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__SHIFT) & A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__MASK;
+}
+
+#define REG_A3XX_GRAS_SC_WINDOW_SCISSOR_BR                     0x0000207a
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_BR_WINDOW_OFFSET_DISABLE   0x80000000
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X__MASK                 0x00007fff
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X__SHIFT                        0
+static inline uint32_t A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X__SHIFT) & A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X__MASK;
+}
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y__MASK                 0x7fff0000
+#define A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y__SHIFT                        16
+static inline uint32_t A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(uint32_t val)
+{
+       return ((val) << A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y__SHIFT) & A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y__MASK;
+}
+
+#define REG_A3XX_RB_MODE_CONTROL                               0x000020c0
+#define A3XX_RB_MODE_CONTROL_GMEM_BYPASS                       0x00000080
+#define A3XX_RB_MODE_CONTROL_RENDER_MODE__MASK                 0x00000700
+#define A3XX_RB_MODE_CONTROL_RENDER_MODE__SHIFT                        8
+static inline uint32_t A3XX_RB_MODE_CONTROL_RENDER_MODE(enum a3xx_render_mode val)
+{
+       return ((val) << A3XX_RB_MODE_CONTROL_RENDER_MODE__SHIFT) & A3XX_RB_MODE_CONTROL_RENDER_MODE__MASK;
+}
+#define A3XX_RB_MODE_CONTROL_MARB_CACHE_SPLIT_MODE             0x00008000
+#define A3XX_RB_MODE_CONTROL_PACKER_TIMER_ENABLE               0x00010000
+
+#define REG_A3XX_RB_RENDER_CONTROL                             0x000020c1
+#define A3XX_RB_RENDER_CONTROL_BIN_WIDTH__MASK                 0x00000ff0
+#define A3XX_RB_RENDER_CONTROL_BIN_WIDTH__SHIFT                        4
+static inline uint32_t A3XX_RB_RENDER_CONTROL_BIN_WIDTH(uint32_t val)
+{
+       return ((val >> 5) << A3XX_RB_RENDER_CONTROL_BIN_WIDTH__SHIFT) & A3XX_RB_RENDER_CONTROL_BIN_WIDTH__MASK;
+}
+#define A3XX_RB_RENDER_CONTROL_DISABLE_COLOR_PIPE              0x00001000
+#define A3XX_RB_RENDER_CONTROL_ENABLE_GMEM                     0x00002000
+#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__MASK           0x07000000
+#define A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__SHIFT          24
+static inline uint32_t A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC(enum adreno_compare_func val)
+{
+       return ((val) << A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__SHIFT) & A3XX_RB_RENDER_CONTROL_ALPHA_TEST_FUNC__MASK;
+}
+
+#define REG_A3XX_RB_MSAA_CONTROL                               0x000020c2
+#define A3XX_RB_MSAA_CONTROL_DISABLE                           0x00000400
+#define A3XX_RB_MSAA_CONTROL_SAMPLES__MASK                     0x0000f000
+#define A3XX_RB_MSAA_CONTROL_SAMPLES__SHIFT                    12
+static inline uint32_t A3XX_RB_MSAA_CONTROL_SAMPLES(enum a3xx_msaa_samples val)
+{
+       return ((val) << A3XX_RB_MSAA_CONTROL_SAMPLES__SHIFT) & A3XX_RB_MSAA_CONTROL_SAMPLES__MASK;
+}
+#define A3XX_RB_MSAA_CONTROL_SAMPLE_MASK__MASK                 0xffff0000
+#define A3XX_RB_MSAA_CONTROL_SAMPLE_MASK__SHIFT                        16
+static inline uint32_t A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(uint32_t val)
+{
+       return ((val) << A3XX_RB_MSAA_CONTROL_SAMPLE_MASK__SHIFT) & A3XX_RB_MSAA_CONTROL_SAMPLE_MASK__MASK;
+}
+
+#define REG_A3XX_UNKNOWN_20C3                                  0x000020c3
+
+static inline uint32_t REG_A3XX_RB_MRT(uint32_t i0) { return 0x000020c4 + 0x4*i0; }
+
+static inline uint32_t REG_A3XX_RB_MRT_CONTROL(uint32_t i0) { return 0x000020c4 + 0x4*i0; }
+#define A3XX_RB_MRT_CONTROL_READ_DEST_ENABLE                   0x00000008
+#define A3XX_RB_MRT_CONTROL_BLEND                              0x00000010
+#define A3XX_RB_MRT_CONTROL_BLEND2                             0x00000020
+#define A3XX_RB_MRT_CONTROL_ROP_CODE__MASK                     0x00000f00
+#define A3XX_RB_MRT_CONTROL_ROP_CODE__SHIFT                    8
+static inline uint32_t A3XX_RB_MRT_CONTROL_ROP_CODE(uint32_t val)
+{
+       return ((val) << A3XX_RB_MRT_CONTROL_ROP_CODE__SHIFT) & A3XX_RB_MRT_CONTROL_ROP_CODE__MASK;
+}
+#define A3XX_RB_MRT_CONTROL_DITHER_MODE__MASK                  0x00003000
+#define A3XX_RB_MRT_CONTROL_DITHER_MODE__SHIFT                 12
+static inline uint32_t A3XX_RB_MRT_CONTROL_DITHER_MODE(enum adreno_rb_dither_mode val)
+{
+       return ((val) << A3XX_RB_MRT_CONTROL_DITHER_MODE__SHIFT) & A3XX_RB_MRT_CONTROL_DITHER_MODE__MASK;
+}
+#define A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK             0x0f000000
+#define A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE__SHIFT            24
+static inline uint32_t A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE(uint32_t val)
+{
+       return ((val) << A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE__SHIFT) & A3XX_RB_MRT_CONTROL_COMPONENT_ENABLE__MASK;
+}
+
+static inline uint32_t REG_A3XX_RB_MRT_BUF_INFO(uint32_t i0) { return 0x000020c5 + 0x4*i0; }
+#define A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT__MASK                        0x0000003f
+#define A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT__SHIFT               0
+static inline uint32_t A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT(enum a3xx_color_fmt val)
+{
+       return ((val) << A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT__SHIFT) & A3XX_RB_MRT_BUF_INFO_COLOR_FORMAT__MASK;
+}
+#define A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE__MASK             0x000000c0
+#define A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE__SHIFT            6
+static inline uint32_t A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE(enum a3xx_tile_mode val)
+{
+       return ((val) << A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE__SHIFT) & A3XX_RB_MRT_BUF_INFO_COLOR_TILE_MODE__MASK;
+}
+#define A3XX_RB_MRT_BUF_INFO_COLOR_SWAP__MASK                  0x00000c00
+#define A3XX_RB_MRT_BUF_INFO_COLOR_SWAP__SHIFT                 10
+static inline uint32_t A3XX_RB_MRT_BUF_INFO_COLOR_SWAP(enum a3xx_color_swap val)
+{
+       return ((val) << A3XX_RB_MRT_BUF_INFO_COLOR_SWAP__SHIFT) & A3XX_RB_MRT_BUF_INFO_COLOR_SWAP__MASK;
+}
+#define A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__MASK             0xfffe0000
+#define A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__SHIFT            17
+static inline uint32_t A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH(uint32_t val)
+{
+       return ((val >> 5) << A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__SHIFT) & A3XX_RB_MRT_BUF_INFO_COLOR_BUF_PITCH__MASK;
+}
+
+static inline uint32_t REG_A3XX_RB_MRT_BUF_BASE(uint32_t i0) { return 0x000020c6 + 0x4*i0; }
+#define A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE__MASK              0xfffffff0
+#define A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE__SHIFT             4
+static inline uint32_t A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE(uint32_t val)
+{
+       return ((val >> 5) << A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE__SHIFT) & A3XX_RB_MRT_BUF_BASE_COLOR_BUF_BASE__MASK;
+}
+
+static inline uint32_t REG_A3XX_RB_MRT_BLEND_CONTROL(uint32_t i0) { return 0x000020c7 + 0x4*i0; }
+#define A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR__MASK         0x0000001f
+#define A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR__SHIFT                0
+static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR(enum adreno_rb_blend_factor val)
+{
+       return ((val) << A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR__SHIFT) & A3XX_RB_MRT_BLEND_CONTROL_RGB_SRC_FACTOR__MASK;
+}
+#define A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__MASK       0x000000e0
+#define A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__SHIFT      5
+static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE(enum adreno_rb_blend_opcode val)
+{
+       return ((val) << A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__SHIFT) & A3XX_RB_MRT_BLEND_CONTROL_RGB_BLEND_OPCODE__MASK;
+}
+#define A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR__MASK                0x00001f00
+#define A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR__SHIFT       8
+static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR(enum adreno_rb_blend_factor val)
+{
+       return ((val) << A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR__SHIFT) & A3XX_RB_MRT_BLEND_CONTROL_RGB_DEST_FACTOR__MASK;
+}
+#define A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR__MASK       0x001f0000
+#define A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR__SHIFT      16
+static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR(enum adreno_rb_blend_factor val)
+{
+       return ((val) << A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR__SHIFT) & A3XX_RB_MRT_BLEND_CONTROL_ALPHA_SRC_FACTOR__MASK;
+}
+#define A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__MASK     0x00e00000
+#define A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__SHIFT    21
+static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE(enum adreno_rb_blend_opcode val)
+{
+       return ((val) << A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__SHIFT) & A3XX_RB_MRT_BLEND_CONTROL_ALPHA_BLEND_OPCODE__MASK;
+}
+#define A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__MASK      0x1f000000
+#define A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__SHIFT     24
+static inline uint32_t A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(enum adreno_rb_blend_factor val)
+{
+       return ((val) << A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__SHIFT) & A3XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__MASK;
+}
+#define A3XX_RB_MRT_BLEND_CONTROL_CLAMP_ENABLE                 0x20000000
+
+#define REG_A3XX_RB_BLEND_RED                                  0x000020e4
+#define A3XX_RB_BLEND_RED_UINT__MASK                           0x000000ff
+#define A3XX_RB_BLEND_RED_UINT__SHIFT                          0
+static inline uint32_t A3XX_RB_BLEND_RED_UINT(uint32_t val)
+{
+       return ((val) << A3XX_RB_BLEND_RED_UINT__SHIFT) & A3XX_RB_BLEND_RED_UINT__MASK;
+}
+#define A3XX_RB_BLEND_RED_FLOAT__MASK                          0xffff0000
+#define A3XX_RB_BLEND_RED_FLOAT__SHIFT                         16
+static inline uint32_t A3XX_RB_BLEND_RED_FLOAT(float val)
+{
+       return ((util_float_to_half(val)) << A3XX_RB_BLEND_RED_FLOAT__SHIFT) & A3XX_RB_BLEND_RED_FLOAT__MASK;
+}
+
+#define REG_A3XX_RB_BLEND_GREEN                                        0x000020e5
+#define A3XX_RB_BLEND_GREEN_UINT__MASK                         0x000000ff
+#define A3XX_RB_BLEND_GREEN_UINT__SHIFT                                0
+static inline uint32_t A3XX_RB_BLEND_GREEN_UINT(uint32_t val)
+{
+       return ((val) << A3XX_RB_BLEND_GREEN_UINT__SHIFT) & A3XX_RB_BLEND_GREEN_UINT__MASK;
+}
+#define A3XX_RB_BLEND_GREEN_FLOAT__MASK                                0xffff0000
+#define A3XX_RB_BLEND_GREEN_FLOAT__SHIFT                       16
+static inline uint32_t A3XX_RB_BLEND_GREEN_FLOAT(float val)
+{
+       return ((util_float_to_half(val)) << A3XX_RB_BLEND_GREEN_FLOAT__SHIFT) & A3XX_RB_BLEND_GREEN_FLOAT__MASK;
+}
+
+#define REG_A3XX_RB_BLEND_BLUE                                 0x000020e6
+#define A3XX_RB_BLEND_BLUE_UINT__MASK                          0x000000ff
+#define A3XX_RB_BLEND_BLUE_UINT__SHIFT                         0
+static inline uint32_t A3XX_RB_BLEND_BLUE_UINT(uint32_t val)
+{
+       return ((val) << A3XX_RB_BLEND_BLUE_UINT__SHIFT) & A3XX_RB_BLEND_BLUE_UINT__MASK;
+}
+#define A3XX_RB_BLEND_BLUE_FLOAT__MASK                         0xffff0000
+#define A3XX_RB_BLEND_BLUE_FLOAT__SHIFT                                16
+static inline uint32_t A3XX_RB_BLEND_BLUE_FLOAT(float val)
+{
+       return ((util_float_to_half(val)) << A3XX_RB_BLEND_BLUE_FLOAT__SHIFT) & A3XX_RB_BLEND_BLUE_FLOAT__MASK;
+}
+
+#define REG_A3XX_RB_BLEND_ALPHA                                        0x000020e7
+#define A3XX_RB_BLEND_ALPHA_UINT__MASK                         0x000000ff
+#define A3XX_RB_BLEND_ALPHA_UINT__SHIFT                                0
+static inline uint32_t A3XX_RB_BLEND_ALPHA_UINT(uint32_t val)
+{
+       return ((val) << A3XX_RB_BLEND_ALPHA_UINT__SHIFT) & A3XX_RB_BLEND_ALPHA_UINT__MASK;
+}
+#define A3XX_RB_BLEND_ALPHA_FLOAT__MASK                                0xffff0000
+#define A3XX_RB_BLEND_ALPHA_FLOAT__SHIFT                       16
+static inline uint32_t A3XX_RB_BLEND_ALPHA_FLOAT(float val)
+{
+       return ((util_float_to_half(val)) << A3XX_RB_BLEND_ALPHA_FLOAT__SHIFT) & A3XX_RB_BLEND_ALPHA_FLOAT__MASK;
+}
+
+#define REG_A3XX_UNKNOWN_20E8                                  0x000020e8
+
+#define REG_A3XX_UNKNOWN_20E9                                  0x000020e9
+
+#define REG_A3XX_UNKNOWN_20EA                                  0x000020ea
+
+#define REG_A3XX_UNKNOWN_20EB                                  0x000020eb
+
+#define REG_A3XX_RB_COPY_CONTROL                               0x000020ec
+#define A3XX_RB_COPY_CONTROL_MSAA_RESOLVE__MASK                        0x00000003
+#define A3XX_RB_COPY_CONTROL_MSAA_RESOLVE__SHIFT               0
+static inline uint32_t A3XX_RB_COPY_CONTROL_MSAA_RESOLVE(enum a3xx_msaa_samples val)
+{
+       return ((val) << A3XX_RB_COPY_CONTROL_MSAA_RESOLVE__SHIFT) & A3XX_RB_COPY_CONTROL_MSAA_RESOLVE__MASK;
+}
+#define A3XX_RB_COPY_CONTROL_MODE__MASK                                0x00000070
+#define A3XX_RB_COPY_CONTROL_MODE__SHIFT                       4
+static inline uint32_t A3XX_RB_COPY_CONTROL_MODE(enum adreno_rb_copy_control_mode val)
+{
+       return ((val) << A3XX_RB_COPY_CONTROL_MODE__SHIFT) & A3XX_RB_COPY_CONTROL_MODE__MASK;
+}
+#define A3XX_RB_COPY_CONTROL_GMEM_BASE__MASK                   0xfffffc00
+#define A3XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT                  10
+static inline uint32_t A3XX_RB_COPY_CONTROL_GMEM_BASE(uint32_t val)
+{
+       return ((val >> 10) << A3XX_RB_COPY_CONTROL_GMEM_BASE__SHIFT) & A3XX_RB_COPY_CONTROL_GMEM_BASE__MASK;
+}
+
+#define REG_A3XX_RB_COPY_DEST_BASE                             0x000020ed
+#define A3XX_RB_COPY_DEST_BASE_BASE__MASK                      0xfffffff0
+#define A3XX_RB_COPY_DEST_BASE_BASE__SHIFT                     4
+static inline uint32_t A3XX_RB_COPY_DEST_BASE_BASE(uint32_t val)
+{
+       return ((val >> 5) << A3XX_RB_COPY_DEST_BASE_BASE__SHIFT) & A3XX_RB_COPY_DEST_BASE_BASE__MASK;
+}
+
+#define REG_A3XX_RB_COPY_DEST_PITCH                            0x000020ee
+#define A3XX_RB_COPY_DEST_PITCH_PITCH__MASK                    0xffffffff
+#define A3XX_RB_COPY_DEST_PITCH_PITCH__SHIFT                   0
+static inline uint32_t A3XX_RB_COPY_DEST_PITCH_PITCH(uint32_t val)
+{
+       return ((val >> 5) << A3XX_RB_COPY_DEST_PITCH_PITCH__SHIFT) & A3XX_RB_COPY_DEST_PITCH_PITCH__MASK;
+}
+
+#define REG_A3XX_RB_COPY_DEST_INFO                             0x000020ef
+#define A3XX_RB_COPY_DEST_INFO_TILE__MASK                      0x00000003
+#define A3XX_RB_COPY_DEST_INFO_TILE__SHIFT                     0
+static inline uint32_t A3XX_RB_COPY_DEST_INFO_TILE(enum a3xx_tile_mode val)
+{
+       return ((val) << A3XX_RB_COPY_DEST_INFO_TILE__SHIFT) & A3XX_RB_COPY_DEST_INFO_TILE__MASK;
+}
+#define A3XX_RB_COPY_DEST_INFO_FORMAT__MASK                    0x000000fc
+#define A3XX_RB_COPY_DEST_INFO_FORMAT__SHIFT                   2
+static inline uint32_t A3XX_RB_COPY_DEST_INFO_FORMAT(enum a3xx_color_fmt val)
+{
+       return ((val) << A3XX_RB_COPY_DEST_INFO_FORMAT__SHIFT) & A3XX_RB_COPY_DEST_INFO_FORMAT__MASK;
+}
+#define A3XX_RB_COPY_DEST_INFO_SWAP__MASK                      0x00000300
+#define A3XX_RB_COPY_DEST_INFO_SWAP__SHIFT                     8
+static inline uint32_t A3XX_RB_COPY_DEST_INFO_SWAP(enum a3xx_color_swap val)
+{
+       return ((val) << A3XX_RB_COPY_DEST_INFO_SWAP__SHIFT) & A3XX_RB_COPY_DEST_INFO_SWAP__MASK;
+}
+#define A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__MASK          0x0003c000
+#define A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__SHIFT         14
+static inline uint32_t A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE(uint32_t val)
+{
+       return ((val) << A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__SHIFT) & A3XX_RB_COPY_DEST_INFO_COMPONENT_ENABLE__MASK;
+}
+#define A3XX_RB_COPY_DEST_INFO_ENDIAN__MASK                    0x001c0000
+#define A3XX_RB_COPY_DEST_INFO_ENDIAN__SHIFT                   18
+static inline uint32_t A3XX_RB_COPY_DEST_INFO_ENDIAN(enum adreno_rb_surface_endian val)
+{
+       return ((val) << A3XX_RB_COPY_DEST_INFO_ENDIAN__SHIFT) & A3XX_RB_COPY_DEST_INFO_ENDIAN__MASK;
+}
+
+#define REG_A3XX_RB_DEPTH_CONTROL                              0x00002100
+#define A3XX_RB_DEPTH_CONTROL_Z_ENABLE                         0x00000002
+#define A3XX_RB_DEPTH_CONTROL_Z_WRITE_ENABLE                   0x00000004
+#define A3XX_RB_DEPTH_CONTROL_EARLY_Z_ENABLE                   0x00000008
+#define A3XX_RB_DEPTH_CONTROL_ZFUNC__MASK                      0x00000070
+#define A3XX_RB_DEPTH_CONTROL_ZFUNC__SHIFT                     4
+static inline uint32_t A3XX_RB_DEPTH_CONTROL_ZFUNC(enum adreno_compare_func val)
+{
+       return ((val) << A3XX_RB_DEPTH_CONTROL_ZFUNC__SHIFT) & A3XX_RB_DEPTH_CONTROL_ZFUNC__MASK;
+}
+#define A3XX_RB_DEPTH_CONTROL_BF_ENABLE                                0x00000080
+#define A3XX_RB_DEPTH_CONTROL_Z_TEST_ENABLE                    0x80000000
+
+#define REG_A3XX_UNKNOWN_2101                                  0x00002101
+
+#define REG_A3XX_RB_DEPTH_INFO                                 0x00002102
+#define A3XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK                  0x00000001
+#define A3XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT                 0
+static inline uint32_t A3XX_RB_DEPTH_INFO_DEPTH_FORMAT(enum adreno_rb_depth_format val)
+{
+       return ((val) << A3XX_RB_DEPTH_INFO_DEPTH_FORMAT__SHIFT) & A3XX_RB_DEPTH_INFO_DEPTH_FORMAT__MASK;
+}
+#define A3XX_RB_DEPTH_INFO_DEPTH_BASE__MASK                    0xfffff800
+#define A3XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT                   11
+static inline uint32_t A3XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val)
+{
+       return ((val >> 10) << A3XX_RB_DEPTH_INFO_DEPTH_BASE__SHIFT) & A3XX_RB_DEPTH_INFO_DEPTH_BASE__MASK;
+}
+
+#define REG_A3XX_RB_DEPTH_PITCH                                        0x00002103
+#define A3XX_RB_DEPTH_PITCH__MASK                              0xffffffff
+#define A3XX_RB_DEPTH_PITCH__SHIFT                             0
+static inline uint32_t A3XX_RB_DEPTH_PITCH(uint32_t val)
+{
+       return ((val >> 3) << A3XX_RB_DEPTH_PITCH__SHIFT) & A3XX_RB_DEPTH_PITCH__MASK;
+}
+
+#define REG_A3XX_RB_STENCIL_CONTROL                            0x00002104
+#define A3XX_RB_STENCIL_CONTROL_STENCIL_ENABLE                 0x00000001
+#define A3XX_RB_STENCIL_CONTROL_STENCIL_ENABLE_BF              0x00000004
+#define A3XX_RB_STENCIL_CONTROL_FUNC__MASK                     0x00000700
+#define A3XX_RB_STENCIL_CONTROL_FUNC__SHIFT                    8
+static inline uint32_t A3XX_RB_STENCIL_CONTROL_FUNC(enum adreno_compare_func val)
+{
+       return ((val) << A3XX_RB_STENCIL_CONTROL_FUNC__SHIFT) & A3XX_RB_STENCIL_CONTROL_FUNC__MASK;
+}
+#define A3XX_RB_STENCIL_CONTROL_FAIL__MASK                     0x00003800
+#define A3XX_RB_STENCIL_CONTROL_FAIL__SHIFT                    11
+static inline uint32_t A3XX_RB_STENCIL_CONTROL_FAIL(enum adreno_stencil_op val)
+{
+       return ((val) << A3XX_RB_STENCIL_CONTROL_FAIL__SHIFT) & A3XX_RB_STENCIL_CONTROL_FAIL__MASK;
+}
+#define A3XX_RB_STENCIL_CONTROL_ZPASS__MASK                    0x0001c000
+#define A3XX_RB_STENCIL_CONTROL_ZPASS__SHIFT                   14
+static inline uint32_t A3XX_RB_STENCIL_CONTROL_ZPASS(enum adreno_stencil_op val)
+{
+       return ((val) << A3XX_RB_STENCIL_CONTROL_ZPASS__SHIFT) & A3XX_RB_STENCIL_CONTROL_ZPASS__MASK;
+}
+#define A3XX_RB_STENCIL_CONTROL_ZFAIL__MASK                    0x000e0000
+#define A3XX_RB_STENCIL_CONTROL_ZFAIL__SHIFT                   17
+static inline uint32_t A3XX_RB_STENCIL_CONTROL_ZFAIL(enum adreno_stencil_op val)
+{
+       return ((val) << A3XX_RB_STENCIL_CONTROL_ZFAIL__SHIFT) & A3XX_RB_STENCIL_CONTROL_ZFAIL__MASK;
+}
+#define A3XX_RB_STENCIL_CONTROL_FUNC_BF__MASK                  0x00700000
+#define A3XX_RB_STENCIL_CONTROL_FUNC_BF__SHIFT                 20
+static inline uint32_t A3XX_RB_STENCIL_CONTROL_FUNC_BF(enum adreno_compare_func val)
+{
+       return ((val) << A3XX_RB_STENCIL_CONTROL_FUNC_BF__SHIFT) & A3XX_RB_STENCIL_CONTROL_FUNC_BF__MASK;
+}
+#define A3XX_RB_STENCIL_CONTROL_FAIL_BF__MASK                  0x03800000
+#define A3XX_RB_STENCIL_CONTROL_FAIL_BF__SHIFT                 23
+static inline uint32_t A3XX_RB_STENCIL_CONTROL_FAIL_BF(enum adreno_stencil_op val)
+{
+       return ((val) << A3XX_RB_STENCIL_CONTROL_FAIL_BF__SHIFT) & A3XX_RB_STENCIL_CONTROL_FAIL_BF__MASK;
+}
+#define A3XX_RB_STENCIL_CONTROL_ZPASS_BF__MASK                 0x1c000000
+#define A3XX_RB_STENCIL_CONTROL_ZPASS_BF__SHIFT                        26
+static inline uint32_t A3XX_RB_STENCIL_CONTROL_ZPASS_BF(enum adreno_stencil_op val)
+{
+       return ((val) << A3XX_RB_STENCIL_CONTROL_ZPASS_BF__SHIFT) & A3XX_RB_STENCIL_CONTROL_ZPASS_BF__MASK;
+}
+#define A3XX_RB_STENCIL_CONTROL_ZFAIL_BF__MASK                 0xe0000000
+#define A3XX_RB_STENCIL_CONTROL_ZFAIL_BF__SHIFT                        29
+static inline uint32_t A3XX_RB_STENCIL_CONTROL_ZFAIL_BF(enum adreno_stencil_op val)
+{
+       return ((val) << A3XX_RB_STENCIL_CONTROL_ZFAIL_BF__SHIFT) & A3XX_RB_STENCIL_CONTROL_ZFAIL_BF__MASK;
+}
+
+#define REG_A3XX_UNKNOWN_2105                                  0x00002105
+
+#define REG_A3XX_UNKNOWN_2106                                  0x00002106
+
+#define REG_A3XX_UNKNOWN_2107                                  0x00002107
+
+#define REG_A3XX_RB_STENCILREFMASK                             0x00002108
+#define A3XX_RB_STENCILREFMASK_STENCILREF__MASK                        0x000000ff
+#define A3XX_RB_STENCILREFMASK_STENCILREF__SHIFT               0
+static inline uint32_t A3XX_RB_STENCILREFMASK_STENCILREF(uint32_t val)
+{
+       return ((val) << A3XX_RB_STENCILREFMASK_STENCILREF__SHIFT) & A3XX_RB_STENCILREFMASK_STENCILREF__MASK;
+}
+#define A3XX_RB_STENCILREFMASK_STENCILMASK__MASK               0x0000ff00
+#define A3XX_RB_STENCILREFMASK_STENCILMASK__SHIFT              8
+static inline uint32_t A3XX_RB_STENCILREFMASK_STENCILMASK(uint32_t val)
+{
+       return ((val) << A3XX_RB_STENCILREFMASK_STENCILMASK__SHIFT) & A3XX_RB_STENCILREFMASK_STENCILMASK__MASK;
+}
+#define A3XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK          0x00ff0000
+#define A3XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT         16
+static inline uint32_t A3XX_RB_STENCILREFMASK_STENCILWRITEMASK(uint32_t val)
+{
+       return ((val) << A3XX_RB_STENCILREFMASK_STENCILWRITEMASK__SHIFT) & A3XX_RB_STENCILREFMASK_STENCILWRITEMASK__MASK;
+}
+
+#define REG_A3XX_RB_STENCILREFMASK_BF                          0x00002109
+#define A3XX_RB_STENCILREFMASK_BF_STENCILREF__MASK             0x000000ff
+#define A3XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT            0
+static inline uint32_t A3XX_RB_STENCILREFMASK_BF_STENCILREF(uint32_t val)
+{
+       return ((val) << A3XX_RB_STENCILREFMASK_BF_STENCILREF__SHIFT) & A3XX_RB_STENCILREFMASK_BF_STENCILREF__MASK;
+}
+#define A3XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK            0x0000ff00
+#define A3XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT           8
+static inline uint32_t A3XX_RB_STENCILREFMASK_BF_STENCILMASK(uint32_t val)
+{
+       return ((val) << A3XX_RB_STENCILREFMASK_BF_STENCILMASK__SHIFT) & A3XX_RB_STENCILREFMASK_BF_STENCILMASK__MASK;
+}
+#define A3XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK       0x00ff0000
+#define A3XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT      16
+static inline uint32_t A3XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK(uint32_t val)
+{
+       return ((val) << A3XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__SHIFT) & A3XX_RB_STENCILREFMASK_BF_STENCILWRITEMASK__MASK;
+}
+
+#define REG_A3XX_PA_SC_WINDOW_OFFSET                           0x0000210e
+#define A3XX_PA_SC_WINDOW_OFFSET_X__MASK                       0x0000ffff
+#define A3XX_PA_SC_WINDOW_OFFSET_X__SHIFT                      0
+static inline uint32_t A3XX_PA_SC_WINDOW_OFFSET_X(uint32_t val)
+{
+       return ((val) << A3XX_PA_SC_WINDOW_OFFSET_X__SHIFT) & A3XX_PA_SC_WINDOW_OFFSET_X__MASK;
+}
+#define A3XX_PA_SC_WINDOW_OFFSET_Y__MASK                       0xffff0000
+#define A3XX_PA_SC_WINDOW_OFFSET_Y__SHIFT                      16
+static inline uint32_t A3XX_PA_SC_WINDOW_OFFSET_Y(uint32_t val)
+{
+       return ((val) << A3XX_PA_SC_WINDOW_OFFSET_Y__SHIFT) & A3XX_PA_SC_WINDOW_OFFSET_Y__MASK;
+}
+
+#define REG_A3XX_PC_VSTREAM_CONTROL                            0x000021e4
+
+#define REG_A3XX_PC_VERTEX_REUSE_BLOCK_CNTL                    0x000021ea
+
+#define REG_A3XX_PC_PRIM_VTX_CNTL                              0x000021ec
+#define A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC__MASK              0x0000001f
+#define A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC__SHIFT             0
+static inline uint32_t A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC(uint32_t val)
+{
+       return ((val) << A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC__SHIFT) & A3XX_PC_PRIM_VTX_CNTL_STRIDE_IN_VPC__MASK;
+}
+#define A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE__MASK       0x000000e0
+#define A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE__SHIFT      5
+static inline uint32_t A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE(enum adreno_pa_su_sc_draw val)
+{
+       return ((val) << A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE__SHIFT) & A3XX_PC_PRIM_VTX_CNTL_POLYMODE_FRONT_PTYPE__MASK;
+}
+#define A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__MASK                0x00000700
+#define A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__SHIFT       8
+static inline uint32_t A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE(enum adreno_pa_su_sc_draw val)
+{
+       return ((val) << A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__SHIFT) & A3XX_PC_PRIM_VTX_CNTL_POLYMODE_BACK_PTYPE__MASK;
+}
+#define A3XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST               0x02000000
+
+#define REG_A3XX_PC_RESTART_INDEX                              0x000021ed
+
+#define REG_A3XX_HLSQ_CONTROL_0_REG                            0x00002200
+#define A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__MASK             0x00000010
+#define A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__SHIFT            4
+static inline uint32_t A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE(enum a3xx_threadsize val)
+{
+       return ((val) << A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__SHIFT) & A3XX_HLSQ_CONTROL_0_REG_FSTHREADSIZE__MASK;
+}
+#define A3XX_HLSQ_CONTROL_0_REG_FSSUPERTHREADENABLE            0x00000040
+#define A3XX_HLSQ_CONTROL_0_REG_SPSHADERRESTART                        0x00000200
+#define A3XX_HLSQ_CONTROL_0_REG_RESERVED2                      0x00000400
+#define A3XX_HLSQ_CONTROL_0_REG_CHUNKDISABLE                   0x04000000
+#define A3XX_HLSQ_CONTROL_0_REG_CONSTSWITCHMODE                        0x08000000
+#define A3XX_HLSQ_CONTROL_0_REG_LAZYUPDATEDISABLE              0x10000000
+#define A3XX_HLSQ_CONTROL_0_REG_SPCONSTFULLUPDATE              0x20000000
+#define A3XX_HLSQ_CONTROL_0_REG_TPFULLUPDATE                   0x40000000
+#define A3XX_HLSQ_CONTROL_0_REG_SINGLECONTEXT                  0x80000000
+
+#define REG_A3XX_HLSQ_CONTROL_1_REG                            0x00002201
+#define A3XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE__MASK             0x00000040
+#define A3XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE__SHIFT            6
+static inline uint32_t A3XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE(enum a3xx_threadsize val)
+{
+       return ((val) << A3XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE__SHIFT) & A3XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE__MASK;
+}
+#define A3XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE            0x00000100
+#define A3XX_HLSQ_CONTROL_1_REG_RESERVED1                      0x00000200
+
+#define REG_A3XX_HLSQ_CONTROL_2_REG                            0x00002202
+#define A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__MASK       0xfc000000
+#define A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__SHIFT      26
+static inline uint32_t A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__SHIFT) & A3XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__MASK;
+}
+
+#define REG_A3XX_HLSQ_CONTROL_3_REG                            0x00002203
+
+#define REG_A3XX_HLSQ_VS_CONTROL_REG                           0x00002204
+#define A3XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__MASK             0x00000fff
+#define A3XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__SHIFT            0
+static inline uint32_t A3XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__SHIFT) & A3XX_HLSQ_VS_CONTROL_REG_CONSTLENGTH__MASK;
+}
+#define A3XX_HLSQ_VS_CONTROL_REG_CONSTSTARTOFFSET__MASK                0x00fff000
+#define A3XX_HLSQ_VS_CONTROL_REG_CONSTSTARTOFFSET__SHIFT       12
+static inline uint32_t A3XX_HLSQ_VS_CONTROL_REG_CONSTSTARTOFFSET(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_VS_CONTROL_REG_CONSTSTARTOFFSET__SHIFT) & A3XX_HLSQ_VS_CONTROL_REG_CONSTSTARTOFFSET__MASK;
+}
+#define A3XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH__MASK             0xff000000
+#define A3XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH__SHIFT            24
+static inline uint32_t A3XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH__SHIFT) & A3XX_HLSQ_VS_CONTROL_REG_INSTRLENGTH__MASK;
+}
+
+#define REG_A3XX_HLSQ_FS_CONTROL_REG                           0x00002205
+#define A3XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH__MASK             0x00000fff
+#define A3XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH__SHIFT            0
+static inline uint32_t A3XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH__SHIFT) & A3XX_HLSQ_FS_CONTROL_REG_CONSTLENGTH__MASK;
+}
+#define A3XX_HLSQ_FS_CONTROL_REG_CONSTSTARTOFFSET__MASK                0x00fff000
+#define A3XX_HLSQ_FS_CONTROL_REG_CONSTSTARTOFFSET__SHIFT       12
+static inline uint32_t A3XX_HLSQ_FS_CONTROL_REG_CONSTSTARTOFFSET(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_FS_CONTROL_REG_CONSTSTARTOFFSET__SHIFT) & A3XX_HLSQ_FS_CONTROL_REG_CONSTSTARTOFFSET__MASK;
+}
+#define A3XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH__MASK             0xff000000
+#define A3XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH__SHIFT            24
+static inline uint32_t A3XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH__SHIFT) & A3XX_HLSQ_FS_CONTROL_REG_INSTRLENGTH__MASK;
+}
+
+#define REG_A3XX_HLSQ_CONST_VSPRESV_RANGE_REG                  0x00002206
+#define A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_STARTENTRY__MASK     0x0000ffff
+#define A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_STARTENTRY__SHIFT    0
+static inline uint32_t A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_STARTENTRY(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_STARTENTRY__SHIFT) & A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_STARTENTRY__MASK;
+}
+#define A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_ENDENTRY__MASK       0xffff0000
+#define A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_ENDENTRY__SHIFT      16
+static inline uint32_t A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_ENDENTRY(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_ENDENTRY__SHIFT) & A3XX_HLSQ_CONST_VSPRESV_RANGE_REG_ENDENTRY__MASK;
+}
+
+#define REG_A3XX_HLSQ_CONST_FSPRESV_RANGE_REG                  0x00002207
+#define A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_STARTENTRY__MASK     0x0000ffff
+#define A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_STARTENTRY__SHIFT    0
+static inline uint32_t A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_STARTENTRY(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_STARTENTRY__SHIFT) & A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_STARTENTRY__MASK;
+}
+#define A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY__MASK       0xffff0000
+#define A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY__SHIFT      16
+static inline uint32_t A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY(uint32_t val)
+{
+       return ((val) << A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY__SHIFT) & A3XX_HLSQ_CONST_FSPRESV_RANGE_REG_ENDENTRY__MASK;
+}
+
+#define REG_A3XX_HLSQ_CL_NDRANGE_0_REG                         0x0000220a
+
+#define REG_A3XX_HLSQ_CL_NDRANGE_1_REG                         0x0000220b
+
+#define REG_A3XX_HLSQ_CL_NDRANGE_2_REG                         0x0000220c
+
+#define REG_A3XX_HLSQ_CL_CONTROL_0_REG                         0x00002211
+
+#define REG_A3XX_HLSQ_CL_CONTROL_1_REG                         0x00002212
+
+#define REG_A3XX_HLSQ_CL_KERNEL_CONST_REG                      0x00002214
+
+#define REG_A3XX_HLSQ_CL_KERNEL_GROUP_X_REG                    0x00002215
+
+#define REG_A3XX_HLSQ_CL_KERNEL_GROUP_Z_REG                    0x00002217
+
+#define REG_A3XX_HLSQ_CL_WG_OFFSET_REG                         0x0000221a
+
+#define REG_A3XX_VFD_CONTROL_0                                 0x00002240
+#define A3XX_VFD_CONTROL_0_TOTALATTRTOVS__MASK                 0x0003ffff
+#define A3XX_VFD_CONTROL_0_TOTALATTRTOVS__SHIFT                        0
+static inline uint32_t A3XX_VFD_CONTROL_0_TOTALATTRTOVS(uint32_t val)
+{
+       return ((val) << A3XX_VFD_CONTROL_0_TOTALATTRTOVS__SHIFT) & A3XX_VFD_CONTROL_0_TOTALATTRTOVS__MASK;
+}
+#define A3XX_VFD_CONTROL_0_PACKETSIZE__MASK                    0x003c0000
+#define A3XX_VFD_CONTROL_0_PACKETSIZE__SHIFT                   18
+static inline uint32_t A3XX_VFD_CONTROL_0_PACKETSIZE(uint32_t val)
+{
+       return ((val) << A3XX_VFD_CONTROL_0_PACKETSIZE__SHIFT) & A3XX_VFD_CONTROL_0_PACKETSIZE__MASK;
+}
+#define A3XX_VFD_CONTROL_0_STRMDECINSTRCNT__MASK               0x07c00000
+#define A3XX_VFD_CONTROL_0_STRMDECINSTRCNT__SHIFT              22
+static inline uint32_t A3XX_VFD_CONTROL_0_STRMDECINSTRCNT(uint32_t val)
+{
+       return ((val) << A3XX_VFD_CONTROL_0_STRMDECINSTRCNT__SHIFT) & A3XX_VFD_CONTROL_0_STRMDECINSTRCNT__MASK;
+}
+#define A3XX_VFD_CONTROL_0_STRMFETCHINSTRCNT__MASK             0xf8000000
+#define A3XX_VFD_CONTROL_0_STRMFETCHINSTRCNT__SHIFT            27
+static inline uint32_t A3XX_VFD_CONTROL_0_STRMFETCHINSTRCNT(uint32_t val)
+{
+       return ((val) << A3XX_VFD_CONTROL_0_STRMFETCHINSTRCNT__SHIFT) & A3XX_VFD_CONTROL_0_STRMFETCHINSTRCNT__MASK;
+}
+
+#define REG_A3XX_VFD_CONTROL_1                                 0x00002241
+#define A3XX_VFD_CONTROL_1_MAXSTORAGE__MASK                    0x0000ffff
+#define A3XX_VFD_CONTROL_1_MAXSTORAGE__SHIFT                   0
+static inline uint32_t A3XX_VFD_CONTROL_1_MAXSTORAGE(uint32_t val)
+{
+       return ((val) << A3XX_VFD_CONTROL_1_MAXSTORAGE__SHIFT) & A3XX_VFD_CONTROL_1_MAXSTORAGE__MASK;
+}
+#define A3XX_VFD_CONTROL_1_REGID4VTX__MASK                     0x00ff0000
+#define A3XX_VFD_CONTROL_1_REGID4VTX__SHIFT                    16
+static inline uint32_t A3XX_VFD_CONTROL_1_REGID4VTX(uint32_t val)
+{
+       return ((val) << A3XX_VFD_CONTROL_1_REGID4VTX__SHIFT) & A3XX_VFD_CONTROL_1_REGID4VTX__MASK;
+}
+#define A3XX_VFD_CONTROL_1_REGID4INST__MASK                    0xff000000
+#define A3XX_VFD_CONTROL_1_REGID4INST__SHIFT                   24
+static inline uint32_t A3XX_VFD_CONTROL_1_REGID4INST(uint32_t val)
+{
+       return ((val) << A3XX_VFD_CONTROL_1_REGID4INST__SHIFT) & A3XX_VFD_CONTROL_1_REGID4INST__MASK;
+}
+
+#define REG_A3XX_VFD_INDEX_MIN                                 0x00002242
+
+#define REG_A3XX_VFD_INDEX_MAX                                 0x00002243
+
+#define REG_A3XX_VFD_INSTANCEID_OFFSET                         0x00002244
+
+#define REG_A3XX_VFD_INDEX_OFFSET                              0x00002245
+
+static inline uint32_t REG_A3XX_VFD_FETCH(uint32_t i0) { return 0x00002246 + 0x2*i0; }
+
+static inline uint32_t REG_A3XX_VFD_FETCH_INSTR_0(uint32_t i0) { return 0x00002246 + 0x2*i0; }
+#define A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__MASK                 0x0000007f
+#define A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__SHIFT                        0
+static inline uint32_t A3XX_VFD_FETCH_INSTR_0_FETCHSIZE(uint32_t val)
+{
+       return ((val) << A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__MASK;
+}
+#define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK                 0x0001ff80
+#define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT                        7
+static inline uint32_t A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(uint32_t val)
+{
+       return ((val) << A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK;
+}
+#define A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT                      0x00020000
+#define A3XX_VFD_FETCH_INSTR_0_INDEXCODE__MASK                 0x00fc0000
+#define A3XX_VFD_FETCH_INSTR_0_INDEXCODE__SHIFT                        18
+static inline uint32_t A3XX_VFD_FETCH_INSTR_0_INDEXCODE(uint32_t val)
+{
+       return ((val) << A3XX_VFD_FETCH_INSTR_0_INDEXCODE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_INDEXCODE__MASK;
+}
+#define A3XX_VFD_FETCH_INSTR_0_STEPRATE__MASK                  0xff000000
+#define A3XX_VFD_FETCH_INSTR_0_STEPRATE__SHIFT                 24
+static inline uint32_t A3XX_VFD_FETCH_INSTR_0_STEPRATE(uint32_t val)
+{
+       return ((val) << A3XX_VFD_FETCH_INSTR_0_STEPRATE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_STEPRATE__MASK;
+}
+
+static inline uint32_t REG_A3XX_VFD_FETCH_INSTR_1(uint32_t i0) { return 0x00002247 + 0x2*i0; }
+
+static inline uint32_t REG_A3XX_VFD_DECODE(uint32_t i0) { return 0x00002266 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_VFD_DECODE_INSTR(uint32_t i0) { return 0x00002266 + 0x1*i0; }
+#define A3XX_VFD_DECODE_INSTR_WRITEMASK__MASK                  0x0000000f
+#define A3XX_VFD_DECODE_INSTR_WRITEMASK__SHIFT                 0
+static inline uint32_t A3XX_VFD_DECODE_INSTR_WRITEMASK(uint32_t val)
+{
+       return ((val) << A3XX_VFD_DECODE_INSTR_WRITEMASK__SHIFT) & A3XX_VFD_DECODE_INSTR_WRITEMASK__MASK;
+}
+#define A3XX_VFD_DECODE_INSTR_CONSTFILL                                0x00000010
+#define A3XX_VFD_DECODE_INSTR_FORMAT__MASK                     0x00000fc0
+#define A3XX_VFD_DECODE_INSTR_FORMAT__SHIFT                    6
+static inline uint32_t A3XX_VFD_DECODE_INSTR_FORMAT(enum a3xx_vtx_fmt val)
+{
+       return ((val) << A3XX_VFD_DECODE_INSTR_FORMAT__SHIFT) & A3XX_VFD_DECODE_INSTR_FORMAT__MASK;
+}
+#define A3XX_VFD_DECODE_INSTR_REGID__MASK                      0x000ff000
+#define A3XX_VFD_DECODE_INSTR_REGID__SHIFT                     12
+static inline uint32_t A3XX_VFD_DECODE_INSTR_REGID(uint32_t val)
+{
+       return ((val) << A3XX_VFD_DECODE_INSTR_REGID__SHIFT) & A3XX_VFD_DECODE_INSTR_REGID__MASK;
+}
+#define A3XX_VFD_DECODE_INSTR_SHIFTCNT__MASK                   0x1f000000
+#define A3XX_VFD_DECODE_INSTR_SHIFTCNT__SHIFT                  24
+static inline uint32_t A3XX_VFD_DECODE_INSTR_SHIFTCNT(uint32_t val)
+{
+       return ((val) << A3XX_VFD_DECODE_INSTR_SHIFTCNT__SHIFT) & A3XX_VFD_DECODE_INSTR_SHIFTCNT__MASK;
+}
+#define A3XX_VFD_DECODE_INSTR_LASTCOMPVALID                    0x20000000
+#define A3XX_VFD_DECODE_INSTR_SWITCHNEXT                       0x40000000
+
+#define REG_A3XX_VFD_VS_THREADING_THRESHOLD                    0x0000227e
+#define A3XX_VFD_VS_THREADING_THRESHOLD_REGID_THRESHOLD__MASK  0x0000000f
+#define A3XX_VFD_VS_THREADING_THRESHOLD_REGID_THRESHOLD__SHIFT 0
+static inline uint32_t A3XX_VFD_VS_THREADING_THRESHOLD_REGID_THRESHOLD(uint32_t val)
+{
+       return ((val) << A3XX_VFD_VS_THREADING_THRESHOLD_REGID_THRESHOLD__SHIFT) & A3XX_VFD_VS_THREADING_THRESHOLD_REGID_THRESHOLD__MASK;
+}
+#define A3XX_VFD_VS_THREADING_THRESHOLD_REGID_VTXCNT__MASK     0x0000ff00
+#define A3XX_VFD_VS_THREADING_THRESHOLD_REGID_VTXCNT__SHIFT    8
+static inline uint32_t A3XX_VFD_VS_THREADING_THRESHOLD_REGID_VTXCNT(uint32_t val)
+{
+       return ((val) << A3XX_VFD_VS_THREADING_THRESHOLD_REGID_VTXCNT__SHIFT) & A3XX_VFD_VS_THREADING_THRESHOLD_REGID_VTXCNT__MASK;
+}
+
+#define REG_A3XX_VPC_ATTR                                      0x00002280
+#define A3XX_VPC_ATTR_TOTALATTR__MASK                          0x00000fff
+#define A3XX_VPC_ATTR_TOTALATTR__SHIFT                         0
+static inline uint32_t A3XX_VPC_ATTR_TOTALATTR(uint32_t val)
+{
+       return ((val) << A3XX_VPC_ATTR_TOTALATTR__SHIFT) & A3XX_VPC_ATTR_TOTALATTR__MASK;
+}
+#define A3XX_VPC_ATTR_THRDASSIGN__MASK                         0x0ffff000
+#define A3XX_VPC_ATTR_THRDASSIGN__SHIFT                                12
+static inline uint32_t A3XX_VPC_ATTR_THRDASSIGN(uint32_t val)
+{
+       return ((val) << A3XX_VPC_ATTR_THRDASSIGN__SHIFT) & A3XX_VPC_ATTR_THRDASSIGN__MASK;
+}
+#define A3XX_VPC_ATTR_LMSIZE__MASK                             0xf0000000
+#define A3XX_VPC_ATTR_LMSIZE__SHIFT                            28
+static inline uint32_t A3XX_VPC_ATTR_LMSIZE(uint32_t val)
+{
+       return ((val) << A3XX_VPC_ATTR_LMSIZE__SHIFT) & A3XX_VPC_ATTR_LMSIZE__MASK;
+}
+
+#define REG_A3XX_VPC_PACK                                      0x00002281
+#define A3XX_VPC_PACK_NUMFPNONPOSVAR__MASK                     0x0000ff00
+#define A3XX_VPC_PACK_NUMFPNONPOSVAR__SHIFT                    8
+static inline uint32_t A3XX_VPC_PACK_NUMFPNONPOSVAR(uint32_t val)
+{
+       return ((val) << A3XX_VPC_PACK_NUMFPNONPOSVAR__SHIFT) & A3XX_VPC_PACK_NUMFPNONPOSVAR__MASK;
+}
+#define A3XX_VPC_PACK_NUMNONPOSVSVAR__MASK                     0x00ff0000
+#define A3XX_VPC_PACK_NUMNONPOSVSVAR__SHIFT                    16
+static inline uint32_t A3XX_VPC_PACK_NUMNONPOSVSVAR(uint32_t val)
+{
+       return ((val) << A3XX_VPC_PACK_NUMNONPOSVSVAR__SHIFT) & A3XX_VPC_PACK_NUMNONPOSVSVAR__MASK;
+}
+
+static inline uint32_t REG_A3XX_VPC_VARYING_INTERP(uint32_t i0) { return 0x00002282 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_VPC_VARYING_INTERP_MODE(uint32_t i0) { return 0x00002282 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_VPC_VARYING_PS_REPL(uint32_t i0) { return 0x00002286 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_VPC_VARYING_PS_REPL_MODE(uint32_t i0) { return 0x00002286 + 0x1*i0; }
+
+#define REG_A3XX_VPC_VARY_CYLWRAP_ENABLE_0                     0x0000228a
+
+#define REG_A3XX_VPC_VARY_CYLWRAP_ENABLE_1                     0x0000228b
+
+#define REG_A3XX_SP_SP_CTRL_REG                                        0x000022c0
+#define A3XX_SP_SP_CTRL_REG_RESOLVE                            0x00010000
+#define A3XX_SP_SP_CTRL_REG_CONSTMODE__MASK                    0x000c0000
+#define A3XX_SP_SP_CTRL_REG_CONSTMODE__SHIFT                   18
+static inline uint32_t A3XX_SP_SP_CTRL_REG_CONSTMODE(uint32_t val)
+{
+       return ((val) << A3XX_SP_SP_CTRL_REG_CONSTMODE__SHIFT) & A3XX_SP_SP_CTRL_REG_CONSTMODE__MASK;
+}
+#define A3XX_SP_SP_CTRL_REG_SLEEPMODE__MASK                    0x00300000
+#define A3XX_SP_SP_CTRL_REG_SLEEPMODE__SHIFT                   20
+static inline uint32_t A3XX_SP_SP_CTRL_REG_SLEEPMODE(uint32_t val)
+{
+       return ((val) << A3XX_SP_SP_CTRL_REG_SLEEPMODE__SHIFT) & A3XX_SP_SP_CTRL_REG_SLEEPMODE__MASK;
+}
+#define A3XX_SP_SP_CTRL_REG_LOMODE__MASK                       0x00c00000
+#define A3XX_SP_SP_CTRL_REG_LOMODE__SHIFT                      22
+static inline uint32_t A3XX_SP_SP_CTRL_REG_LOMODE(uint32_t val)
+{
+       return ((val) << A3XX_SP_SP_CTRL_REG_LOMODE__SHIFT) & A3XX_SP_SP_CTRL_REG_LOMODE__MASK;
+}
+
+#define REG_A3XX_SP_VS_CTRL_REG0                               0x000022c4
+#define A3XX_SP_VS_CTRL_REG0_THREADMODE__MASK                  0x00000001
+#define A3XX_SP_VS_CTRL_REG0_THREADMODE__SHIFT                 0
+static inline uint32_t A3XX_SP_VS_CTRL_REG0_THREADMODE(enum a3xx_threadmode val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG0_THREADMODE__SHIFT) & A3XX_SP_VS_CTRL_REG0_THREADMODE__MASK;
+}
+#define A3XX_SP_VS_CTRL_REG0_INSTRBUFFERMODE__MASK             0x00000002
+#define A3XX_SP_VS_CTRL_REG0_INSTRBUFFERMODE__SHIFT            1
+static inline uint32_t A3XX_SP_VS_CTRL_REG0_INSTRBUFFERMODE(enum a3xx_instrbuffermode val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG0_INSTRBUFFERMODE__SHIFT) & A3XX_SP_VS_CTRL_REG0_INSTRBUFFERMODE__MASK;
+}
+#define A3XX_SP_VS_CTRL_REG0_CACHEINVALID                      0x00000004
+#define A3XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__MASK            0x000003f0
+#define A3XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT           4
+static inline uint32_t A3XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT) & A3XX_SP_VS_CTRL_REG0_HALFREGFOOTPRINT__MASK;
+}
+#define A3XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT__MASK            0x0003fc00
+#define A3XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT           10
+static inline uint32_t A3XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT) & A3XX_SP_VS_CTRL_REG0_FULLREGFOOTPRINT__MASK;
+}
+#define A3XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP__MASK             0x000c0000
+#define A3XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP__SHIFT            18
+static inline uint32_t A3XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP__SHIFT) & A3XX_SP_VS_CTRL_REG0_INOUTREGOVERLAP__MASK;
+}
+#define A3XX_SP_VS_CTRL_REG0_THREADSIZE__MASK                  0x00100000
+#define A3XX_SP_VS_CTRL_REG0_THREADSIZE__SHIFT                 20
+static inline uint32_t A3XX_SP_VS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG0_THREADSIZE__SHIFT) & A3XX_SP_VS_CTRL_REG0_THREADSIZE__MASK;
+}
+#define A3XX_SP_VS_CTRL_REG0_SUPERTHREADMODE                   0x00200000
+#define A3XX_SP_VS_CTRL_REG0_PIXLODENABLE                      0x00400000
+#define A3XX_SP_VS_CTRL_REG0_LENGTH__MASK                      0xff000000
+#define A3XX_SP_VS_CTRL_REG0_LENGTH__SHIFT                     24
+static inline uint32_t A3XX_SP_VS_CTRL_REG0_LENGTH(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG0_LENGTH__SHIFT) & A3XX_SP_VS_CTRL_REG0_LENGTH__MASK;
+}
+
+#define REG_A3XX_SP_VS_CTRL_REG1                               0x000022c5
+#define A3XX_SP_VS_CTRL_REG1_CONSTLENGTH__MASK                 0x000003ff
+#define A3XX_SP_VS_CTRL_REG1_CONSTLENGTH__SHIFT                        0
+static inline uint32_t A3XX_SP_VS_CTRL_REG1_CONSTLENGTH(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG1_CONSTLENGTH__SHIFT) & A3XX_SP_VS_CTRL_REG1_CONSTLENGTH__MASK;
+}
+#define A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT__MASK              0x000ffc00
+#define A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT__SHIFT             10
+static inline uint32_t A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT__SHIFT) & A3XX_SP_VS_CTRL_REG1_CONSTFOOTPRINT__MASK;
+}
+#define A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__MASK          0x3f000000
+#define A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__SHIFT         24
+static inline uint32_t A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__SHIFT) & A3XX_SP_VS_CTRL_REG1_INITIALOUTSTANDING__MASK;
+}
+
+#define REG_A3XX_SP_VS_PARAM_REG                               0x000022c6
+#define A3XX_SP_VS_PARAM_REG_POSREGID__MASK                    0x000000ff
+#define A3XX_SP_VS_PARAM_REG_POSREGID__SHIFT                   0
+static inline uint32_t A3XX_SP_VS_PARAM_REG_POSREGID(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_PARAM_REG_POSREGID__SHIFT) & A3XX_SP_VS_PARAM_REG_POSREGID__MASK;
+}
+#define A3XX_SP_VS_PARAM_REG_PSIZEREGID__MASK                  0x0000ff00
+#define A3XX_SP_VS_PARAM_REG_PSIZEREGID__SHIFT                 8
+static inline uint32_t A3XX_SP_VS_PARAM_REG_PSIZEREGID(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_PARAM_REG_PSIZEREGID__SHIFT) & A3XX_SP_VS_PARAM_REG_PSIZEREGID__MASK;
+}
+#define A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR__MASK               0xfff00000
+#define A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR__SHIFT              20
+static inline uint32_t A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR__SHIFT) & A3XX_SP_VS_PARAM_REG_TOTALVSOUTVAR__MASK;
+}
+
+static inline uint32_t REG_A3XX_SP_VS_OUT(uint32_t i0) { return 0x000022c7 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_SP_VS_OUT_REG(uint32_t i0) { return 0x000022c7 + 0x1*i0; }
+#define A3XX_SP_VS_OUT_REG_A_REGID__MASK                       0x000001ff
+#define A3XX_SP_VS_OUT_REG_A_REGID__SHIFT                      0
+static inline uint32_t A3XX_SP_VS_OUT_REG_A_REGID(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_OUT_REG_A_REGID__SHIFT) & A3XX_SP_VS_OUT_REG_A_REGID__MASK;
+}
+#define A3XX_SP_VS_OUT_REG_A_COMPMASK__MASK                    0x00001e00
+#define A3XX_SP_VS_OUT_REG_A_COMPMASK__SHIFT                   9
+static inline uint32_t A3XX_SP_VS_OUT_REG_A_COMPMASK(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_OUT_REG_A_COMPMASK__SHIFT) & A3XX_SP_VS_OUT_REG_A_COMPMASK__MASK;
+}
+#define A3XX_SP_VS_OUT_REG_B_REGID__MASK                       0x01ff0000
+#define A3XX_SP_VS_OUT_REG_B_REGID__SHIFT                      16
+static inline uint32_t A3XX_SP_VS_OUT_REG_B_REGID(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_OUT_REG_B_REGID__SHIFT) & A3XX_SP_VS_OUT_REG_B_REGID__MASK;
+}
+#define A3XX_SP_VS_OUT_REG_B_COMPMASK__MASK                    0x1e000000
+#define A3XX_SP_VS_OUT_REG_B_COMPMASK__SHIFT                   25
+static inline uint32_t A3XX_SP_VS_OUT_REG_B_COMPMASK(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_OUT_REG_B_COMPMASK__SHIFT) & A3XX_SP_VS_OUT_REG_B_COMPMASK__MASK;
+}
+
+static inline uint32_t REG_A3XX_SP_VS_VPC_DST(uint32_t i0) { return 0x000022d0 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_SP_VS_VPC_DST_REG(uint32_t i0) { return 0x000022d0 + 0x1*i0; }
+#define A3XX_SP_VS_VPC_DST_REG_OUTLOC0__MASK                   0x000000ff
+#define A3XX_SP_VS_VPC_DST_REG_OUTLOC0__SHIFT                  0
+static inline uint32_t A3XX_SP_VS_VPC_DST_REG_OUTLOC0(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_VPC_DST_REG_OUTLOC0__SHIFT) & A3XX_SP_VS_VPC_DST_REG_OUTLOC0__MASK;
+}
+#define A3XX_SP_VS_VPC_DST_REG_OUTLOC1__MASK                   0x0000ff00
+#define A3XX_SP_VS_VPC_DST_REG_OUTLOC1__SHIFT                  8
+static inline uint32_t A3XX_SP_VS_VPC_DST_REG_OUTLOC1(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_VPC_DST_REG_OUTLOC1__SHIFT) & A3XX_SP_VS_VPC_DST_REG_OUTLOC1__MASK;
+}
+#define A3XX_SP_VS_VPC_DST_REG_OUTLOC2__MASK                   0x00ff0000
+#define A3XX_SP_VS_VPC_DST_REG_OUTLOC2__SHIFT                  16
+static inline uint32_t A3XX_SP_VS_VPC_DST_REG_OUTLOC2(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_VPC_DST_REG_OUTLOC2__SHIFT) & A3XX_SP_VS_VPC_DST_REG_OUTLOC2__MASK;
+}
+#define A3XX_SP_VS_VPC_DST_REG_OUTLOC3__MASK                   0xff000000
+#define A3XX_SP_VS_VPC_DST_REG_OUTLOC3__SHIFT                  24
+static inline uint32_t A3XX_SP_VS_VPC_DST_REG_OUTLOC3(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_VPC_DST_REG_OUTLOC3__SHIFT) & A3XX_SP_VS_VPC_DST_REG_OUTLOC3__MASK;
+}
+
+#define REG_A3XX_SP_VS_OBJ_OFFSET_REG                          0x000022d4
+#define A3XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK      0x01ff0000
+#define A3XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT     16
+static inline uint32_t A3XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT) & A3XX_SP_VS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK;
+}
+#define A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK                0xfe000000
+#define A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT       25
+static inline uint32_t A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT) & A3XX_SP_VS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK;
+}
+
+#define REG_A3XX_SP_VS_OBJ_START_REG                           0x000022d5
+
+#define REG_A3XX_SP_VS_PVT_MEM_CTRL_REG                                0x000022d6
+
+#define REG_A3XX_SP_VS_PVT_MEM_ADDR_REG                                0x000022d7
+
+#define REG_A3XX_SP_VS_PVT_MEM_SIZE_REG                                0x000022d8
+
+#define REG_A3XX_SP_VS_LENGTH_REG                              0x000022df
+#define A3XX_SP_VS_LENGTH_REG_SHADERLENGTH__MASK               0xffffffff
+#define A3XX_SP_VS_LENGTH_REG_SHADERLENGTH__SHIFT              0
+static inline uint32_t A3XX_SP_VS_LENGTH_REG_SHADERLENGTH(uint32_t val)
+{
+       return ((val) << A3XX_SP_VS_LENGTH_REG_SHADERLENGTH__SHIFT) & A3XX_SP_VS_LENGTH_REG_SHADERLENGTH__MASK;
+}
+
+#define REG_A3XX_SP_FS_CTRL_REG0                               0x000022e0
+#define A3XX_SP_FS_CTRL_REG0_THREADMODE__MASK                  0x00000001
+#define A3XX_SP_FS_CTRL_REG0_THREADMODE__SHIFT                 0
+static inline uint32_t A3XX_SP_FS_CTRL_REG0_THREADMODE(enum a3xx_threadmode val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG0_THREADMODE__SHIFT) & A3XX_SP_FS_CTRL_REG0_THREADMODE__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG0_INSTRBUFFERMODE__MASK             0x00000002
+#define A3XX_SP_FS_CTRL_REG0_INSTRBUFFERMODE__SHIFT            1
+static inline uint32_t A3XX_SP_FS_CTRL_REG0_INSTRBUFFERMODE(enum a3xx_instrbuffermode val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG0_INSTRBUFFERMODE__SHIFT) & A3XX_SP_FS_CTRL_REG0_INSTRBUFFERMODE__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG0_CACHEINVALID                      0x00000004
+#define A3XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__MASK            0x000003f0
+#define A3XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT           4
+static inline uint32_t A3XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__SHIFT) & A3XX_SP_FS_CTRL_REG0_HALFREGFOOTPRINT__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT__MASK            0x0003fc00
+#define A3XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT           10
+static inline uint32_t A3XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT__SHIFT) & A3XX_SP_FS_CTRL_REG0_FULLREGFOOTPRINT__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP__MASK             0x000c0000
+#define A3XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP__SHIFT            18
+static inline uint32_t A3XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP__SHIFT) & A3XX_SP_FS_CTRL_REG0_INOUTREGOVERLAP__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG0_THREADSIZE__MASK                  0x00100000
+#define A3XX_SP_FS_CTRL_REG0_THREADSIZE__SHIFT                 20
+static inline uint32_t A3XX_SP_FS_CTRL_REG0_THREADSIZE(enum a3xx_threadsize val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG0_THREADSIZE__SHIFT) & A3XX_SP_FS_CTRL_REG0_THREADSIZE__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG0_SUPERTHREADMODE                   0x00200000
+#define A3XX_SP_FS_CTRL_REG0_PIXLODENABLE                      0x00400000
+#define A3XX_SP_FS_CTRL_REG0_LENGTH__MASK                      0xff000000
+#define A3XX_SP_FS_CTRL_REG0_LENGTH__SHIFT                     24
+static inline uint32_t A3XX_SP_FS_CTRL_REG0_LENGTH(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG0_LENGTH__SHIFT) & A3XX_SP_FS_CTRL_REG0_LENGTH__MASK;
+}
+
+#define REG_A3XX_SP_FS_CTRL_REG1                               0x000022e1
+#define A3XX_SP_FS_CTRL_REG1_CONSTLENGTH__MASK                 0x000003ff
+#define A3XX_SP_FS_CTRL_REG1_CONSTLENGTH__SHIFT                        0
+static inline uint32_t A3XX_SP_FS_CTRL_REG1_CONSTLENGTH(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG1_CONSTLENGTH__SHIFT) & A3XX_SP_FS_CTRL_REG1_CONSTLENGTH__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT__MASK              0x000ffc00
+#define A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT__SHIFT             10
+static inline uint32_t A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT__SHIFT) & A3XX_SP_FS_CTRL_REG1_CONSTFOOTPRINT__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG1_INITIALOUTSTANDING__MASK          0x00f00000
+#define A3XX_SP_FS_CTRL_REG1_INITIALOUTSTANDING__SHIFT         20
+static inline uint32_t A3XX_SP_FS_CTRL_REG1_INITIALOUTSTANDING(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG1_INITIALOUTSTANDING__SHIFT) & A3XX_SP_FS_CTRL_REG1_INITIALOUTSTANDING__MASK;
+}
+#define A3XX_SP_FS_CTRL_REG1_HALFPRECVAROFFSET__MASK           0x3f000000
+#define A3XX_SP_FS_CTRL_REG1_HALFPRECVAROFFSET__SHIFT          24
+static inline uint32_t A3XX_SP_FS_CTRL_REG1_HALFPRECVAROFFSET(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_CTRL_REG1_HALFPRECVAROFFSET__SHIFT) & A3XX_SP_FS_CTRL_REG1_HALFPRECVAROFFSET__MASK;
+}
+
+#define REG_A3XX_SP_FS_OBJ_OFFSET_REG                          0x000022e2
+#define A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK      0x01ff0000
+#define A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT     16
+static inline uint32_t A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__SHIFT) & A3XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK;
+}
+#define A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK                0xfe000000
+#define A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT       25
+static inline uint32_t A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET__SHIFT) & A3XX_SP_FS_OBJ_OFFSET_REG_SHADEROBJOFFSET__MASK;
+}
+
+#define REG_A3XX_SP_FS_OBJ_START_REG                           0x000022e3
+
+#define REG_A3XX_SP_FS_PVT_MEM_CTRL_REG                                0x000022e4
+
+#define REG_A3XX_SP_FS_PVT_MEM_ADDR_REG                                0x000022e5
+
+#define REG_A3XX_SP_FS_PVT_MEM_SIZE_REG                                0x000022e6
+
+#define REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_0                    0x000022e8
+
+#define REG_A3XX_SP_FS_FLAT_SHAD_MODE_REG_1                    0x000022e9
+
+#define REG_A3XX_SP_FS_OUTPUT_REG                              0x000022ec
+
+static inline uint32_t REG_A3XX_SP_FS_MRT(uint32_t i0) { return 0x000022f0 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_SP_FS_MRT_REG(uint32_t i0) { return 0x000022f0 + 0x1*i0; }
+#define A3XX_SP_FS_MRT_REG_REGID__MASK                         0x000000ff
+#define A3XX_SP_FS_MRT_REG_REGID__SHIFT                                0
+static inline uint32_t A3XX_SP_FS_MRT_REG_REGID(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_MRT_REG_REGID__SHIFT) & A3XX_SP_FS_MRT_REG_REGID__MASK;
+}
+#define A3XX_SP_FS_MRT_REG_HALF_PRECISION                      0x00000100
+
+static inline uint32_t REG_A3XX_SP_FS_IMAGE_OUTPUT(uint32_t i0) { return 0x000022f4 + 0x1*i0; }
+
+static inline uint32_t REG_A3XX_SP_FS_IMAGE_OUTPUT_REG(uint32_t i0) { return 0x000022f4 + 0x1*i0; }
+#define A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT__MASK            0x0000003f
+#define A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT__SHIFT           0
+static inline uint32_t A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT(enum a3xx_color_fmt val)
+{
+       return ((val) << A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT__SHIFT) & A3XX_SP_FS_IMAGE_OUTPUT_REG_MRTFORMAT__MASK;
+}
+
+#define REG_A3XX_SP_FS_LENGTH_REG                              0x000022ff
+#define A3XX_SP_FS_LENGTH_REG_SHADERLENGTH__MASK               0xffffffff
+#define A3XX_SP_FS_LENGTH_REG_SHADERLENGTH__SHIFT              0
+static inline uint32_t A3XX_SP_FS_LENGTH_REG_SHADERLENGTH(uint32_t val)
+{
+       return ((val) << A3XX_SP_FS_LENGTH_REG_SHADERLENGTH__SHIFT) & A3XX_SP_FS_LENGTH_REG_SHADERLENGTH__MASK;
+}
+
+#define REG_A3XX_TPL1_TP_VS_TEX_OFFSET                         0x00002340
+#define A3XX_TPL1_TP_VS_TEX_OFFSET_SAMPLEROFFSET__MASK         0x000000ff
+#define A3XX_TPL1_TP_VS_TEX_OFFSET_SAMPLEROFFSET__SHIFT                0
+static inline uint32_t A3XX_TPL1_TP_VS_TEX_OFFSET_SAMPLEROFFSET(uint32_t val)
+{
+       return ((val) << A3XX_TPL1_TP_VS_TEX_OFFSET_SAMPLEROFFSET__SHIFT) & A3XX_TPL1_TP_VS_TEX_OFFSET_SAMPLEROFFSET__MASK;
+}
+#define A3XX_TPL1_TP_VS_TEX_OFFSET_MEMOBJOFFSET__MASK          0x0000ff00
+#define A3XX_TPL1_TP_VS_TEX_OFFSET_MEMOBJOFFSET__SHIFT         8
+static inline uint32_t A3XX_TPL1_TP_VS_TEX_OFFSET_MEMOBJOFFSET(uint32_t val)
+{
+       return ((val) << A3XX_TPL1_TP_VS_TEX_OFFSET_MEMOBJOFFSET__SHIFT) & A3XX_TPL1_TP_VS_TEX_OFFSET_MEMOBJOFFSET__MASK;
+}
+#define A3XX_TPL1_TP_VS_TEX_OFFSET_BASETABLEPTR__MASK          0xffff0000
+#define A3XX_TPL1_TP_VS_TEX_OFFSET_BASETABLEPTR__SHIFT         16
+static inline uint32_t A3XX_TPL1_TP_VS_TEX_OFFSET_BASETABLEPTR(uint32_t val)
+{
+       return ((val) << A3XX_TPL1_TP_VS_TEX_OFFSET_BASETABLEPTR__SHIFT) & A3XX_TPL1_TP_VS_TEX_OFFSET_BASETABLEPTR__MASK;
+}
+
+#define REG_A3XX_TPL1_TP_VS_BORDER_COLOR_BASE_ADDR             0x00002341
+
+#define REG_A3XX_TPL1_TP_FS_TEX_OFFSET                         0x00002342
+#define A3XX_TPL1_TP_FS_TEX_OFFSET_SAMPLEROFFSET__MASK         0x000000ff
+#define A3XX_TPL1_TP_FS_TEX_OFFSET_SAMPLEROFFSET__SHIFT                0
+static inline uint32_t A3XX_TPL1_TP_FS_TEX_OFFSET_SAMPLEROFFSET(uint32_t val)
+{
+       return ((val) << A3XX_TPL1_TP_FS_TEX_OFFSET_SAMPLEROFFSET__SHIFT) & A3XX_TPL1_TP_FS_TEX_OFFSET_SAMPLEROFFSET__MASK;
+}
+#define A3XX_TPL1_TP_FS_TEX_OFFSET_MEMOBJOFFSET__MASK          0x0000ff00
+#define A3XX_TPL1_TP_FS_TEX_OFFSET_MEMOBJOFFSET__SHIFT         8
+static inline uint32_t A3XX_TPL1_TP_FS_TEX_OFFSET_MEMOBJOFFSET(uint32_t val)
+{
+       return ((val) << A3XX_TPL1_TP_FS_TEX_OFFSET_MEMOBJOFFSET__SHIFT) & A3XX_TPL1_TP_FS_TEX_OFFSET_MEMOBJOFFSET__MASK;
+}
+#define A3XX_TPL1_TP_FS_TEX_OFFSET_BASETABLEPTR__MASK          0xffff0000
+#define A3XX_TPL1_TP_FS_TEX_OFFSET_BASETABLEPTR__SHIFT         16
+static inline uint32_t A3XX_TPL1_TP_FS_TEX_OFFSET_BASETABLEPTR(uint32_t val)
+{
+       return ((val) << A3XX_TPL1_TP_FS_TEX_OFFSET_BASETABLEPTR__SHIFT) & A3XX_TPL1_TP_FS_TEX_OFFSET_BASETABLEPTR__MASK;
+}
+
+#define REG_A3XX_TPL1_TP_FS_BORDER_COLOR_BASE_ADDR             0x00002343
+
+#define REG_A3XX_VBIF_CLKON                                    0x00003001
+
+#define REG_A3XX_VBIF_FIXED_SORT_EN                            0x0000300c
+
+#define REG_A3XX_VBIF_FIXED_SORT_SEL0                          0x0000300d
+
+#define REG_A3XX_VBIF_FIXED_SORT_SEL1                          0x0000300e
+
+#define REG_A3XX_VBIF_ABIT_SORT                                        0x0000301c
+
+#define REG_A3XX_VBIF_ABIT_SORT_CONF                           0x0000301d
+
+#define REG_A3XX_VBIF_GATE_OFF_WRREQ_EN                                0x0000302a
+
+#define REG_A3XX_VBIF_IN_RD_LIM_CONF0                          0x0000302c
+
+#define REG_A3XX_VBIF_IN_RD_LIM_CONF1                          0x0000302d
+
+#define REG_A3XX_VBIF_IN_WR_LIM_CONF0                          0x00003030
+
+#define REG_A3XX_VBIF_IN_WR_LIM_CONF1                          0x00003031
+
+#define REG_A3XX_VBIF_OUT_RD_LIM_CONF0                         0x00003034
+
+#define REG_A3XX_VBIF_OUT_WR_LIM_CONF0                         0x00003035
+
+#define REG_A3XX_VBIF_DDR_OUT_MAX_BURST                                0x00003036
+
+#define REG_A3XX_VBIF_ARB_CTL                                  0x0000303c
+
+#define REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB                      0x00003049
+
+#define REG_A3XX_VBIF_OUT_AXI_AMEMTYPE_CONF0                   0x00003058
+
+#define REG_A3XX_VBIF_OUT_AXI_AOOO_EN                          0x0000305e
+
+#define REG_A3XX_VBIF_OUT_AXI_AOOO                             0x0000305f
+
+#define REG_A3XX_VSC_BIN_SIZE                                  0x00000c01
+#define A3XX_VSC_BIN_SIZE_WIDTH__MASK                          0x0000001f
+#define A3XX_VSC_BIN_SIZE_WIDTH__SHIFT                         0
+static inline uint32_t A3XX_VSC_BIN_SIZE_WIDTH(uint32_t val)
+{
+       return ((val >> 5) << A3XX_VSC_BIN_SIZE_WIDTH__SHIFT) & A3XX_VSC_BIN_SIZE_WIDTH__MASK;
+}
+#define A3XX_VSC_BIN_SIZE_HEIGHT__MASK                         0x000003e0
+#define A3XX_VSC_BIN_SIZE_HEIGHT__SHIFT                                5
+static inline uint32_t A3XX_VSC_BIN_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val >> 5) << A3XX_VSC_BIN_SIZE_HEIGHT__SHIFT) & A3XX_VSC_BIN_SIZE_HEIGHT__MASK;
+}
+
+#define REG_A3XX_VSC_SIZE_ADDRESS                              0x00000c02
+
+static inline uint32_t REG_A3XX_VSC_PIPE(uint32_t i0) { return 0x00000c06 + 0x3*i0; }
+
+static inline uint32_t REG_A3XX_VSC_PIPE_CONFIG(uint32_t i0) { return 0x00000c06 + 0x3*i0; }
+#define A3XX_VSC_PIPE_CONFIG_X__MASK                           0x000003ff
+#define A3XX_VSC_PIPE_CONFIG_X__SHIFT                          0
+static inline uint32_t A3XX_VSC_PIPE_CONFIG_X(uint32_t val)
+{
+       return ((val) << A3XX_VSC_PIPE_CONFIG_X__SHIFT) & A3XX_VSC_PIPE_CONFIG_X__MASK;
+}
+#define A3XX_VSC_PIPE_CONFIG_Y__MASK                           0x000ffc00
+#define A3XX_VSC_PIPE_CONFIG_Y__SHIFT                          10
+static inline uint32_t A3XX_VSC_PIPE_CONFIG_Y(uint32_t val)
+{
+       return ((val) << A3XX_VSC_PIPE_CONFIG_Y__SHIFT) & A3XX_VSC_PIPE_CONFIG_Y__MASK;
+}
+#define A3XX_VSC_PIPE_CONFIG_W__MASK                           0x00f00000
+#define A3XX_VSC_PIPE_CONFIG_W__SHIFT                          20
+static inline uint32_t A3XX_VSC_PIPE_CONFIG_W(uint32_t val)
+{
+       return ((val) << A3XX_VSC_PIPE_CONFIG_W__SHIFT) & A3XX_VSC_PIPE_CONFIG_W__MASK;
+}
+#define A3XX_VSC_PIPE_CONFIG_H__MASK                           0x0f000000
+#define A3XX_VSC_PIPE_CONFIG_H__SHIFT                          24
+static inline uint32_t A3XX_VSC_PIPE_CONFIG_H(uint32_t val)
+{
+       return ((val) << A3XX_VSC_PIPE_CONFIG_H__SHIFT) & A3XX_VSC_PIPE_CONFIG_H__MASK;
+}
+
+static inline uint32_t REG_A3XX_VSC_PIPE_DATA_ADDRESS(uint32_t i0) { return 0x00000c07 + 0x3*i0; }
+
+static inline uint32_t REG_A3XX_VSC_PIPE_DATA_LENGTH(uint32_t i0) { return 0x00000c08 + 0x3*i0; }
+
+#define REG_A3XX_UNKNOWN_0C3D                                  0x00000c3d
+
+#define REG_A3XX_PC_PERFCOUNTER0_SELECT                                0x00000c48
+
+#define REG_A3XX_PC_PERFCOUNTER1_SELECT                                0x00000c49
+
+#define REG_A3XX_PC_PERFCOUNTER2_SELECT                                0x00000c4a
+
+#define REG_A3XX_PC_PERFCOUNTER3_SELECT                                0x00000c4b
+
+#define REG_A3XX_UNKNOWN_0C81                                  0x00000c81
+
+#define REG_A3XX_GRAS_PERFCOUNTER0_SELECT                      0x00000c88
+
+#define REG_A3XX_GRAS_PERFCOUNTER1_SELECT                      0x00000c89
+
+#define REG_A3XX_GRAS_PERFCOUNTER2_SELECT                      0x00000c8a
+
+#define REG_A3XX_GRAS_PERFCOUNTER3_SELECT                      0x00000c8b
+
+static inline uint32_t REG_A3XX_GRAS_CL_USER_PLANE(uint32_t i0) { return 0x00000ca0 + 0x4*i0; }
+
+static inline uint32_t REG_A3XX_GRAS_CL_USER_PLANE_X(uint32_t i0) { return 0x00000ca0 + 0x4*i0; }
+
+static inline uint32_t REG_A3XX_GRAS_CL_USER_PLANE_Y(uint32_t i0) { return 0x00000ca1 + 0x4*i0; }
+
+static inline uint32_t REG_A3XX_GRAS_CL_USER_PLANE_Z(uint32_t i0) { return 0x00000ca2 + 0x4*i0; }
+
+static inline uint32_t REG_A3XX_GRAS_CL_USER_PLANE_W(uint32_t i0) { return 0x00000ca3 + 0x4*i0; }
+
+#define REG_A3XX_RB_GMEM_BASE_ADDR                             0x00000cc0
+
+#define REG_A3XX_RB_PERFCOUNTER0_SELECT                                0x00000cc6
+
+#define REG_A3XX_RB_PERFCOUNTER1_SELECT                                0x00000cc7
+
+#define REG_A3XX_RB_WINDOW_SIZE                                        0x00000ce0
+#define A3XX_RB_WINDOW_SIZE_WIDTH__MASK                                0x00003fff
+#define A3XX_RB_WINDOW_SIZE_WIDTH__SHIFT                       0
+static inline uint32_t A3XX_RB_WINDOW_SIZE_WIDTH(uint32_t val)
+{
+       return ((val) << A3XX_RB_WINDOW_SIZE_WIDTH__SHIFT) & A3XX_RB_WINDOW_SIZE_WIDTH__MASK;
+}
+#define A3XX_RB_WINDOW_SIZE_HEIGHT__MASK                       0x0fffc000
+#define A3XX_RB_WINDOW_SIZE_HEIGHT__SHIFT                      14
+static inline uint32_t A3XX_RB_WINDOW_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val) << A3XX_RB_WINDOW_SIZE_HEIGHT__SHIFT) & A3XX_RB_WINDOW_SIZE_HEIGHT__MASK;
+}
+
+#define REG_A3XX_HLSQ_PERFCOUNTER0_SELECT                      0x00000e00
+
+#define REG_A3XX_HLSQ_PERFCOUNTER1_SELECT                      0x00000e01
+
+#define REG_A3XX_HLSQ_PERFCOUNTER2_SELECT                      0x00000e02
+
+#define REG_A3XX_HLSQ_PERFCOUNTER3_SELECT                      0x00000e03
+
+#define REG_A3XX_HLSQ_PERFCOUNTER4_SELECT                      0x00000e04
+
+#define REG_A3XX_HLSQ_PERFCOUNTER5_SELECT                      0x00000e05
+
+#define REG_A3XX_UNKNOWN_0E43                                  0x00000e43
+
+#define REG_A3XX_VFD_PERFCOUNTER0_SELECT                       0x00000e44
+
+#define REG_A3XX_VFD_PERFCOUNTER1_SELECT                       0x00000e45
+
+#define REG_A3XX_VPC_VPC_DEBUG_RAM_SEL                         0x00000e61
+
+#define REG_A3XX_VPC_VPC_DEBUG_RAM_READ                                0x00000e62
+
+#define REG_A3XX_VPC_PERFCOUNTER0_SELECT                       0x00000e64
+
+#define REG_A3XX_VPC_PERFCOUNTER1_SELECT                       0x00000e65
+
+#define REG_A3XX_UCHE_CACHE_MODE_CONTROL_REG                   0x00000e82
+
+#define REG_A3XX_UCHE_PERFCOUNTER0_SELECT                      0x00000e84
+
+#define REG_A3XX_UCHE_PERFCOUNTER1_SELECT                      0x00000e85
+
+#define REG_A3XX_UCHE_PERFCOUNTER2_SELECT                      0x00000e86
+
+#define REG_A3XX_UCHE_PERFCOUNTER3_SELECT                      0x00000e87
+
+#define REG_A3XX_UCHE_PERFCOUNTER4_SELECT                      0x00000e88
+
+#define REG_A3XX_UCHE_PERFCOUNTER5_SELECT                      0x00000e89
+
+#define REG_A3XX_UCHE_CACHE_INVALIDATE0_REG                    0x00000ea0
+#define A3XX_UCHE_CACHE_INVALIDATE0_REG_ADDR__MASK             0x0fffffff
+#define A3XX_UCHE_CACHE_INVALIDATE0_REG_ADDR__SHIFT            0
+static inline uint32_t A3XX_UCHE_CACHE_INVALIDATE0_REG_ADDR(uint32_t val)
+{
+       return ((val) << A3XX_UCHE_CACHE_INVALIDATE0_REG_ADDR__SHIFT) & A3XX_UCHE_CACHE_INVALIDATE0_REG_ADDR__MASK;
+}
+
+#define REG_A3XX_UCHE_CACHE_INVALIDATE1_REG                    0x00000ea1
+#define A3XX_UCHE_CACHE_INVALIDATE1_REG_ADDR__MASK             0x0fffffff
+#define A3XX_UCHE_CACHE_INVALIDATE1_REG_ADDR__SHIFT            0
+static inline uint32_t A3XX_UCHE_CACHE_INVALIDATE1_REG_ADDR(uint32_t val)
+{
+       return ((val) << A3XX_UCHE_CACHE_INVALIDATE1_REG_ADDR__SHIFT) & A3XX_UCHE_CACHE_INVALIDATE1_REG_ADDR__MASK;
+}
+#define A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE__MASK           0x30000000
+#define A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE__SHIFT          28
+static inline uint32_t A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE(enum a3xx_cache_opcode val)
+{
+       return ((val) << A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE__SHIFT) & A3XX_UCHE_CACHE_INVALIDATE1_REG_OPCODE__MASK;
+}
+#define A3XX_UCHE_CACHE_INVALIDATE1_REG_ENTIRE_CACHE           0x80000000
+
+#define REG_A3XX_SP_PERFCOUNTER0_SELECT                                0x00000ec4
+
+#define REG_A3XX_SP_PERFCOUNTER1_SELECT                                0x00000ec5
+
+#define REG_A3XX_SP_PERFCOUNTER2_SELECT                                0x00000ec6
+
+#define REG_A3XX_SP_PERFCOUNTER3_SELECT                                0x00000ec7
+
+#define REG_A3XX_SP_PERFCOUNTER4_SELECT                                0x00000ec8
+
+#define REG_A3XX_SP_PERFCOUNTER5_SELECT                                0x00000ec9
+
+#define REG_A3XX_SP_PERFCOUNTER6_SELECT                                0x00000eca
+
+#define REG_A3XX_SP_PERFCOUNTER7_SELECT                                0x00000ecb
+
+#define REG_A3XX_UNKNOWN_0EE0                                  0x00000ee0
+
+#define REG_A3XX_UNKNOWN_0F03                                  0x00000f03
+
+#define REG_A3XX_TP_PERFCOUNTER0_SELECT                                0x00000f04
+
+#define REG_A3XX_TP_PERFCOUNTER1_SELECT                                0x00000f05
+
+#define REG_A3XX_TP_PERFCOUNTER2_SELECT                                0x00000f06
+
+#define REG_A3XX_TP_PERFCOUNTER3_SELECT                                0x00000f07
+
+#define REG_A3XX_TP_PERFCOUNTER4_SELECT                                0x00000f08
+
+#define REG_A3XX_TP_PERFCOUNTER5_SELECT                                0x00000f09
+
+#define REG_A3XX_TEX_SAMP_0                                    0x00000000
+#define A3XX_TEX_SAMP_0_XY_MAG__MASK                           0x0000000c
+#define A3XX_TEX_SAMP_0_XY_MAG__SHIFT                          2
+static inline uint32_t A3XX_TEX_SAMP_0_XY_MAG(enum a3xx_tex_filter val)
+{
+       return ((val) << A3XX_TEX_SAMP_0_XY_MAG__SHIFT) & A3XX_TEX_SAMP_0_XY_MAG__MASK;
+}
+#define A3XX_TEX_SAMP_0_XY_MIN__MASK                           0x00000030
+#define A3XX_TEX_SAMP_0_XY_MIN__SHIFT                          4
+static inline uint32_t A3XX_TEX_SAMP_0_XY_MIN(enum a3xx_tex_filter val)
+{
+       return ((val) << A3XX_TEX_SAMP_0_XY_MIN__SHIFT) & A3XX_TEX_SAMP_0_XY_MIN__MASK;
+}
+#define A3XX_TEX_SAMP_0_WRAP_S__MASK                           0x000001c0
+#define A3XX_TEX_SAMP_0_WRAP_S__SHIFT                          6
+static inline uint32_t A3XX_TEX_SAMP_0_WRAP_S(enum a3xx_tex_clamp val)
+{
+       return ((val) << A3XX_TEX_SAMP_0_WRAP_S__SHIFT) & A3XX_TEX_SAMP_0_WRAP_S__MASK;
+}
+#define A3XX_TEX_SAMP_0_WRAP_T__MASK                           0x00000e00
+#define A3XX_TEX_SAMP_0_WRAP_T__SHIFT                          9
+static inline uint32_t A3XX_TEX_SAMP_0_WRAP_T(enum a3xx_tex_clamp val)
+{
+       return ((val) << A3XX_TEX_SAMP_0_WRAP_T__SHIFT) & A3XX_TEX_SAMP_0_WRAP_T__MASK;
+}
+#define A3XX_TEX_SAMP_0_WRAP_R__MASK                           0x00007000
+#define A3XX_TEX_SAMP_0_WRAP_R__SHIFT                          12
+static inline uint32_t A3XX_TEX_SAMP_0_WRAP_R(enum a3xx_tex_clamp val)
+{
+       return ((val) << A3XX_TEX_SAMP_0_WRAP_R__SHIFT) & A3XX_TEX_SAMP_0_WRAP_R__MASK;
+}
+#define A3XX_TEX_SAMP_0_UNNORM_COORDS                          0x80000000
+
+#define REG_A3XX_TEX_SAMP_1                                    0x00000001
+
+#define REG_A3XX_TEX_CONST_0                                   0x00000000
+#define A3XX_TEX_CONST_0_TILED                                 0x00000001
+#define A3XX_TEX_CONST_0_SWIZ_X__MASK                          0x00000070
+#define A3XX_TEX_CONST_0_SWIZ_X__SHIFT                         4
+static inline uint32_t A3XX_TEX_CONST_0_SWIZ_X(enum a3xx_tex_swiz val)
+{
+       return ((val) << A3XX_TEX_CONST_0_SWIZ_X__SHIFT) & A3XX_TEX_CONST_0_SWIZ_X__MASK;
+}
+#define A3XX_TEX_CONST_0_SWIZ_Y__MASK                          0x00000380
+#define A3XX_TEX_CONST_0_SWIZ_Y__SHIFT                         7
+static inline uint32_t A3XX_TEX_CONST_0_SWIZ_Y(enum a3xx_tex_swiz val)
+{
+       return ((val) << A3XX_TEX_CONST_0_SWIZ_Y__SHIFT) & A3XX_TEX_CONST_0_SWIZ_Y__MASK;
+}
+#define A3XX_TEX_CONST_0_SWIZ_Z__MASK                          0x00001c00
+#define A3XX_TEX_CONST_0_SWIZ_Z__SHIFT                         10
+static inline uint32_t A3XX_TEX_CONST_0_SWIZ_Z(enum a3xx_tex_swiz val)
+{
+       return ((val) << A3XX_TEX_CONST_0_SWIZ_Z__SHIFT) & A3XX_TEX_CONST_0_SWIZ_Z__MASK;
+}
+#define A3XX_TEX_CONST_0_SWIZ_W__MASK                          0x0000e000
+#define A3XX_TEX_CONST_0_SWIZ_W__SHIFT                         13
+static inline uint32_t A3XX_TEX_CONST_0_SWIZ_W(enum a3xx_tex_swiz val)
+{
+       return ((val) << A3XX_TEX_CONST_0_SWIZ_W__SHIFT) & A3XX_TEX_CONST_0_SWIZ_W__MASK;
+}
+#define A3XX_TEX_CONST_0_FMT__MASK                             0x1fc00000
+#define A3XX_TEX_CONST_0_FMT__SHIFT                            22
+static inline uint32_t A3XX_TEX_CONST_0_FMT(enum a3xx_tex_fmt val)
+{
+       return ((val) << A3XX_TEX_CONST_0_FMT__SHIFT) & A3XX_TEX_CONST_0_FMT__MASK;
+}
+#define A3XX_TEX_CONST_0_TYPE__MASK                            0xc0000000
+#define A3XX_TEX_CONST_0_TYPE__SHIFT                           30
+static inline uint32_t A3XX_TEX_CONST_0_TYPE(enum a3xx_tex_type val)
+{
+       return ((val) << A3XX_TEX_CONST_0_TYPE__SHIFT) & A3XX_TEX_CONST_0_TYPE__MASK;
+}
+
+#define REG_A3XX_TEX_CONST_1                                   0x00000001
+#define A3XX_TEX_CONST_1_HEIGHT__MASK                          0x00003fff
+#define A3XX_TEX_CONST_1_HEIGHT__SHIFT                         0
+static inline uint32_t A3XX_TEX_CONST_1_HEIGHT(uint32_t val)
+{
+       return ((val) << A3XX_TEX_CONST_1_HEIGHT__SHIFT) & A3XX_TEX_CONST_1_HEIGHT__MASK;
+}
+#define A3XX_TEX_CONST_1_WIDTH__MASK                           0x0fffc000
+#define A3XX_TEX_CONST_1_WIDTH__SHIFT                          14
+static inline uint32_t A3XX_TEX_CONST_1_WIDTH(uint32_t val)
+{
+       return ((val) << A3XX_TEX_CONST_1_WIDTH__SHIFT) & A3XX_TEX_CONST_1_WIDTH__MASK;
+}
+#define A3XX_TEX_CONST_1_FETCHSIZE__MASK                       0xf0000000
+#define A3XX_TEX_CONST_1_FETCHSIZE__SHIFT                      28
+static inline uint32_t A3XX_TEX_CONST_1_FETCHSIZE(enum a3xx_tex_fetchsize val)
+{
+       return ((val) << A3XX_TEX_CONST_1_FETCHSIZE__SHIFT) & A3XX_TEX_CONST_1_FETCHSIZE__MASK;
+}
+
+#define REG_A3XX_TEX_CONST_2                                   0x00000002
+#define A3XX_TEX_CONST_2_INDX__MASK                            0x000000ff
+#define A3XX_TEX_CONST_2_INDX__SHIFT                           0
+static inline uint32_t A3XX_TEX_CONST_2_INDX(uint32_t val)
+{
+       return ((val) << A3XX_TEX_CONST_2_INDX__SHIFT) & A3XX_TEX_CONST_2_INDX__MASK;
+}
+#define A3XX_TEX_CONST_2_PITCH__MASK                           0x3ffff000
+#define A3XX_TEX_CONST_2_PITCH__SHIFT                          12
+static inline uint32_t A3XX_TEX_CONST_2_PITCH(uint32_t val)
+{
+       return ((val) << A3XX_TEX_CONST_2_PITCH__SHIFT) & A3XX_TEX_CONST_2_PITCH__MASK;
+}
+#define A3XX_TEX_CONST_2_SWAP__MASK                            0xc0000000
+#define A3XX_TEX_CONST_2_SWAP__SHIFT                           30
+static inline uint32_t A3XX_TEX_CONST_2_SWAP(enum a3xx_color_swap val)
+{
+       return ((val) << A3XX_TEX_CONST_2_SWAP__SHIFT) & A3XX_TEX_CONST_2_SWAP__MASK;
+}
+
+#define REG_A3XX_TEX_CONST_3                                   0x00000003
+
+
+#endif /* A3XX_XML */
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c
new file mode 100644 (file)
index 0000000..035bd13
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "a3xx_gpu.h"
+
+#define A3XX_INT0_MASK \
+       (A3XX_INT0_RBBM_AHB_ERROR |        \
+        A3XX_INT0_RBBM_ATB_BUS_OVERFLOW | \
+        A3XX_INT0_CP_T0_PACKET_IN_IB |    \
+        A3XX_INT0_CP_OPCODE_ERROR |       \
+        A3XX_INT0_CP_RESERVED_BIT_ERROR | \
+        A3XX_INT0_CP_HW_FAULT |           \
+        A3XX_INT0_CP_IB1_INT |            \
+        A3XX_INT0_CP_IB2_INT |            \
+        A3XX_INT0_CP_RB_INT |             \
+        A3XX_INT0_CP_REG_PROTECT_FAULT |  \
+        A3XX_INT0_CP_AHB_ERROR_HALT |     \
+        A3XX_INT0_UCHE_OOB_ACCESS)
+
+static struct platform_device *a3xx_pdev;
+
+static void a3xx_me_init(struct msm_gpu *gpu)
+{
+       struct msm_ringbuffer *ring = gpu->rb;
+
+       OUT_PKT3(ring, CP_ME_INIT, 17);
+       OUT_RING(ring, 0x000003f7);
+       OUT_RING(ring, 0x00000000);
+       OUT_RING(ring, 0x00000000);
+       OUT_RING(ring, 0x00000000);
+       OUT_RING(ring, 0x00000080);
+       OUT_RING(ring, 0x00000100);
+       OUT_RING(ring, 0x00000180);
+       OUT_RING(ring, 0x00006600);
+       OUT_RING(ring, 0x00000150);
+       OUT_RING(ring, 0x0000014e);
+       OUT_RING(ring, 0x00000154);
+       OUT_RING(ring, 0x00000001);
+       OUT_RING(ring, 0x00000000);
+       OUT_RING(ring, 0x00000000);
+       OUT_RING(ring, 0x00000000);
+       OUT_RING(ring, 0x00000000);
+       OUT_RING(ring, 0x00000000);
+
+       gpu->funcs->flush(gpu);
+       gpu->funcs->idle(gpu);
+}
+
+static int a3xx_hw_init(struct msm_gpu *gpu)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       uint32_t *ptr, len;
+       int i, ret;
+
+       DBG("%s", gpu->name);
+
+       if (adreno_is_a305(adreno_gpu)) {
+               /* Set up 16 deep read/write request queues: */
+               gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010);
+               /* Enable WR-REQ: */
+               gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x0000ff);
+               /* Set up round robin arbitration between both AXI ports: */
+               gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030);
+               /* Set up AOOO: */
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c);
+
+       } else if (adreno_is_a320(adreno_gpu)) {
+               /* Set up 16 deep read/write request queues: */
+               gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x10101010);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x10101010);
+               /* Enable WR-REQ: */
+               gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x0000ff);
+               /* Set up round robin arbitration between both AXI ports: */
+               gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030);
+               /* Set up AOOO: */
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000003c);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0x003c003c);
+               /* Enable 1K sort: */
+               gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x000000ff);
+               gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4);
+
+       } else if (adreno_is_a330(adreno_gpu)) {
+               /* Set up 16 deep read/write request queues: */
+               gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF0, 0x18181818);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_RD_LIM_CONF1, 0x18181818);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_RD_LIM_CONF0, 0x18181818);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_WR_LIM_CONF0, 0x18181818);
+               gpu_write(gpu, REG_A3XX_VBIF_DDR_OUT_MAX_BURST, 0x0000303);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF0, 0x18181818);
+               gpu_write(gpu, REG_A3XX_VBIF_IN_WR_LIM_CONF1, 0x18181818);
+               /* Enable WR-REQ: */
+               gpu_write(gpu, REG_A3XX_VBIF_GATE_OFF_WRREQ_EN, 0x00003f);
+               /* Set up round robin arbitration between both AXI ports: */
+               gpu_write(gpu, REG_A3XX_VBIF_ARB_CTL, 0x00000030);
+               /* Set up VBIF_ROUND_ROBIN_QOS_ARB: */
+               gpu_write(gpu, REG_A3XX_VBIF_ROUND_ROBIN_QOS_ARB, 0x0001);
+               /* Set up AOOO: */
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO_EN, 0x0000ffff);
+               gpu_write(gpu, REG_A3XX_VBIF_OUT_AXI_AOOO, 0xffffffff);
+               /* Enable 1K sort: */
+               gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT, 0x0001ffff);
+               gpu_write(gpu, REG_A3XX_VBIF_ABIT_SORT_CONF, 0x000000a4);
+               /* Disable VBIF clock gating. This is to enable AXI running
+                * higher frequency than GPU:
+                */
+               gpu_write(gpu, REG_A3XX_VBIF_CLKON, 0x00000001);
+
+       } else {
+               BUG();
+       }
+
+       /* Make all blocks contribute to the GPU BUSY perf counter: */
+       gpu_write(gpu, REG_A3XX_RBBM_GPU_BUSY_MASKED, 0xffffffff);
+
+       /* Tune the hystersis counters for SP and CP idle detection: */
+       gpu_write(gpu, REG_A3XX_RBBM_SP_HYST_CNT, 0x10);
+       gpu_write(gpu, REG_A3XX_RBBM_WAIT_IDLE_CLOCKS_CTL, 0x10);
+
+       /* Enable the RBBM error reporting bits.  This lets us get
+        * useful information on failure:
+        */
+       gpu_write(gpu, REG_A3XX_RBBM_AHB_CTL0, 0x00000001);
+
+       /* Enable AHB error reporting: */
+       gpu_write(gpu, REG_A3XX_RBBM_AHB_CTL1, 0xa6ffffff);
+
+       /* Turn on the power counters: */
+       gpu_write(gpu, REG_A3XX_RBBM_RBBM_CTL, 0x00030000);
+
+       /* Turn on hang detection - this spews a lot of useful information
+        * into the RBBM registers on a hang:
+        */
+       gpu_write(gpu, REG_A3XX_RBBM_INTERFACE_HANG_INT_CTL, 0x00010fff);
+
+       /* Enable 64-byte cacheline size. HW Default is 32-byte (0x000000E0): */
+       gpu_write(gpu, REG_A3XX_UCHE_CACHE_MODE_CONTROL_REG, 0x00000001);
+
+       /* Enable Clock gating: */
+       gpu_write(gpu, REG_A3XX_RBBM_CLOCK_CTL, 0xbfffffff);
+
+       /* Set the OCMEM base address for A330 */
+//TODO:
+//     if (adreno_is_a330(adreno_gpu)) {
+//             gpu_write(gpu, REG_A3XX_RB_GMEM_BASE_ADDR,
+//                     (unsigned int)(a3xx_gpu->ocmem_base >> 14));
+//     }
+
+       /* Turn on performance counters: */
+       gpu_write(gpu, REG_A3XX_RBBM_PERFCTR_CTL, 0x01);
+
+       /* Set SP perfcounter 7 to count SP_FS_FULL_ALU_INSTRUCTIONS
+        * we will use this to augment our hang detection:
+        */
+       gpu_write(gpu, REG_A3XX_SP_PERFCOUNTER7_SELECT,
+                       SP_FS_FULL_ALU_INSTRUCTIONS);
+
+       gpu_write(gpu, REG_A3XX_RBBM_INT_0_MASK, A3XX_INT0_MASK);
+
+       ret = adreno_hw_init(gpu);
+       if (ret)
+               return ret;
+
+       /* setup access protection: */
+       gpu_write(gpu, REG_A3XX_CP_PROTECT_CTRL, 0x00000007);
+
+       /* RBBM registers */
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(0), 0x63000040);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(1), 0x62000080);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(2), 0x600000cc);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(3), 0x60000108);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(4), 0x64000140);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(5), 0x66000400);
+
+       /* CP registers */
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(6), 0x65000700);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(7), 0x610007d8);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(8), 0x620007e0);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(9), 0x61001178);
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(10), 0x64001180);
+
+       /* RB registers */
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(11), 0x60003300);
+
+       /* VBIF registers */
+       gpu_write(gpu, REG_A3XX_CP_PROTECT(12), 0x6b00c000);
+
+       /* NOTE: PM4/micro-engine firmware registers look to be the same
+        * for a2xx and a3xx.. we could possibly push that part down to
+        * adreno_gpu base class.  Or push both PM4 and PFP but
+        * parameterize the pfp ucode addr/data registers..
+        */
+
+       /* Load PM4: */
+       ptr = (uint32_t *)(adreno_gpu->pm4->data);
+       len = adreno_gpu->pm4->size / 4;
+       DBG("loading PM4 ucode version: %u", ptr[0]);
+
+       gpu_write(gpu, REG_AXXX_CP_DEBUG,
+                       AXXX_CP_DEBUG_DYNAMIC_CLK_DISABLE |
+                       AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE);
+       gpu_write(gpu, REG_AXXX_CP_ME_RAM_WADDR, 0);
+       for (i = 1; i < len; i++)
+               gpu_write(gpu, REG_AXXX_CP_ME_RAM_DATA, ptr[i]);
+
+       /* Load PFP: */
+       ptr = (uint32_t *)(adreno_gpu->pfp->data);
+       len = adreno_gpu->pfp->size / 4;
+       DBG("loading PFP ucode version: %u", ptr[0]);
+
+       gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_ADDR, 0);
+       for (i = 1; i < len; i++)
+               gpu_write(gpu, REG_A3XX_CP_PFP_UCODE_DATA, ptr[i]);
+
+       /* CP ROQ queue sizes (bytes) - RB:16, ST:16, IB1:32, IB2:64 */
+       if (adreno_is_a305(adreno_gpu) || adreno_is_a320(adreno_gpu))
+               gpu_write(gpu, REG_AXXX_CP_QUEUE_THRESHOLDS,
+                               AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START(2) |
+                               AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START(6) |
+                               AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START(14));
+
+
+       /* clear ME_HALT to start micro engine */
+       gpu_write(gpu, REG_AXXX_CP_ME_CNTL, 0);
+
+       a3xx_me_init(gpu);
+
+       return 0;
+}
+
+static void a3xx_destroy(struct msm_gpu *gpu)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       struct a3xx_gpu *a3xx_gpu = to_a3xx_gpu(adreno_gpu);
+
+       DBG("%s", gpu->name);
+
+       adreno_gpu_cleanup(adreno_gpu);
+       put_device(&a3xx_gpu->pdev->dev);
+       kfree(a3xx_gpu);
+}
+
+static void a3xx_idle(struct msm_gpu *gpu)
+{
+       unsigned long t;
+
+       /* wait for ringbuffer to drain: */
+       adreno_idle(gpu);
+
+       t = jiffies + ADRENO_IDLE_TIMEOUT;
+
+       /* then wait for GPU to finish: */
+       do {
+               uint32_t rbbm_status = gpu_read(gpu, REG_A3XX_RBBM_STATUS);
+               if (!(rbbm_status & A3XX_RBBM_STATUS_GPU_BUSY))
+                       return;
+       } while(time_before(jiffies, t));
+
+       DRM_ERROR("timeout waiting for %s to idle!\n", gpu->name);
+
+       /* TODO maybe we need to reset GPU here to recover from hang? */
+}
+
+static irqreturn_t a3xx_irq(struct msm_gpu *gpu)
+{
+       uint32_t status;
+
+       status = gpu_read(gpu, REG_A3XX_RBBM_INT_0_STATUS);
+       DBG("%s: %08x", gpu->name, status);
+
+       // TODO
+
+       gpu_write(gpu, REG_A3XX_RBBM_INT_CLEAR_CMD, status);
+
+       msm_gpu_retire(gpu);
+
+       return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static const unsigned int a3xx_registers[] = {
+       0x0000, 0x0002, 0x0010, 0x0012, 0x0018, 0x0018, 0x0020, 0x0027,
+       0x0029, 0x002b, 0x002e, 0x0033, 0x0040, 0x0042, 0x0050, 0x005c,
+       0x0060, 0x006c, 0x0080, 0x0082, 0x0084, 0x0088, 0x0090, 0x00e5,
+       0x00ea, 0x00ed, 0x0100, 0x0100, 0x0110, 0x0123, 0x01c0, 0x01c1,
+       0x01c3, 0x01c5, 0x01c7, 0x01c7, 0x01d5, 0x01d9, 0x01dc, 0x01dd,
+       0x01ea, 0x01ea, 0x01ee, 0x01f1, 0x01f5, 0x01f5, 0x01fc, 0x01ff,
+       0x0440, 0x0440, 0x0443, 0x0443, 0x0445, 0x0445, 0x044d, 0x044f,
+       0x0452, 0x0452, 0x0454, 0x046f, 0x047c, 0x047c, 0x047f, 0x047f,
+       0x0578, 0x057f, 0x0600, 0x0602, 0x0605, 0x0607, 0x060a, 0x060e,
+       0x0612, 0x0614, 0x0c01, 0x0c02, 0x0c06, 0x0c1d, 0x0c3d, 0x0c3f,
+       0x0c48, 0x0c4b, 0x0c80, 0x0c80, 0x0c88, 0x0c8b, 0x0ca0, 0x0cb7,
+       0x0cc0, 0x0cc1, 0x0cc6, 0x0cc7, 0x0ce4, 0x0ce5, 0x0e00, 0x0e05,
+       0x0e0c, 0x0e0c, 0x0e22, 0x0e23, 0x0e41, 0x0e45, 0x0e64, 0x0e65,
+       0x0e80, 0x0e82, 0x0e84, 0x0e89, 0x0ea0, 0x0ea1, 0x0ea4, 0x0ea7,
+       0x0ec4, 0x0ecb, 0x0ee0, 0x0ee0, 0x0f00, 0x0f01, 0x0f03, 0x0f09,
+       0x2040, 0x2040, 0x2044, 0x2044, 0x2048, 0x204d, 0x2068, 0x2069,
+       0x206c, 0x206d, 0x2070, 0x2070, 0x2072, 0x2072, 0x2074, 0x2075,
+       0x2079, 0x207a, 0x20c0, 0x20d3, 0x20e4, 0x20ef, 0x2100, 0x2109,
+       0x210c, 0x210c, 0x210e, 0x210e, 0x2110, 0x2111, 0x2114, 0x2115,
+       0x21e4, 0x21e4, 0x21ea, 0x21ea, 0x21ec, 0x21ed, 0x21f0, 0x21f0,
+       0x2200, 0x2212, 0x2214, 0x2217, 0x221a, 0x221a, 0x2240, 0x227e,
+       0x2280, 0x228b, 0x22c0, 0x22c0, 0x22c4, 0x22ce, 0x22d0, 0x22d8,
+       0x22df, 0x22e6, 0x22e8, 0x22e9, 0x22ec, 0x22ec, 0x22f0, 0x22f7,
+       0x22ff, 0x22ff, 0x2340, 0x2343, 0x2348, 0x2349, 0x2350, 0x2356,
+       0x2360, 0x2360, 0x2440, 0x2440, 0x2444, 0x2444, 0x2448, 0x244d,
+       0x2468, 0x2469, 0x246c, 0x246d, 0x2470, 0x2470, 0x2472, 0x2472,
+       0x2474, 0x2475, 0x2479, 0x247a, 0x24c0, 0x24d3, 0x24e4, 0x24ef,
+       0x2500, 0x2509, 0x250c, 0x250c, 0x250e, 0x250e, 0x2510, 0x2511,
+       0x2514, 0x2515, 0x25e4, 0x25e4, 0x25ea, 0x25ea, 0x25ec, 0x25ed,
+       0x25f0, 0x25f0, 0x2600, 0x2612, 0x2614, 0x2617, 0x261a, 0x261a,
+       0x2640, 0x267e, 0x2680, 0x268b, 0x26c0, 0x26c0, 0x26c4, 0x26ce,
+       0x26d0, 0x26d8, 0x26df, 0x26e6, 0x26e8, 0x26e9, 0x26ec, 0x26ec,
+       0x26f0, 0x26f7, 0x26ff, 0x26ff, 0x2740, 0x2743, 0x2748, 0x2749,
+       0x2750, 0x2756, 0x2760, 0x2760, 0x300c, 0x300e, 0x301c, 0x301d,
+       0x302a, 0x302a, 0x302c, 0x302d, 0x3030, 0x3031, 0x3034, 0x3036,
+       0x303c, 0x303c, 0x305e, 0x305f,
+};
+
+static void a3xx_show(struct msm_gpu *gpu, struct seq_file *m)
+{
+       int i;
+
+       adreno_show(gpu, m);
+       seq_printf(m, "status:   %08x\n",
+                       gpu_read(gpu, REG_A3XX_RBBM_STATUS));
+
+       /* dump these out in a form that can be parsed by demsm: */
+       seq_printf(m, "IO:region %s 00000000 00020000\n", gpu->name);
+       for (i = 0; i < ARRAY_SIZE(a3xx_registers); i += 2) {
+               uint32_t start = a3xx_registers[i];
+               uint32_t end   = a3xx_registers[i+1];
+               uint32_t addr;
+
+               for (addr = start; addr <= end; addr++) {
+                       uint32_t val = gpu_read(gpu, addr);
+                       seq_printf(m, "IO:R %08x %08x\n", addr<<2, val);
+               }
+       }
+}
+#endif
+
+static const struct adreno_gpu_funcs funcs = {
+       .base = {
+               .get_param = adreno_get_param,
+               .hw_init = a3xx_hw_init,
+               .pm_suspend = msm_gpu_pm_suspend,
+               .pm_resume = msm_gpu_pm_resume,
+               .recover = adreno_recover,
+               .last_fence = adreno_last_fence,
+               .submit = adreno_submit,
+               .flush = adreno_flush,
+               .idle = a3xx_idle,
+               .irq = a3xx_irq,
+               .destroy = a3xx_destroy,
+#ifdef CONFIG_DEBUG_FS
+               .show = a3xx_show,
+#endif
+       },
+};
+
+struct msm_gpu *a3xx_gpu_init(struct drm_device *dev)
+{
+       struct a3xx_gpu *a3xx_gpu = NULL;
+       struct msm_gpu *gpu;
+       struct platform_device *pdev = a3xx_pdev;
+       struct adreno_platform_config *config;
+       int ret;
+
+       if (!pdev) {
+               dev_err(dev->dev, "no a3xx device\n");
+               ret = -ENXIO;
+               goto fail;
+       }
+
+       config = pdev->dev.platform_data;
+
+       a3xx_gpu = kzalloc(sizeof(*a3xx_gpu), GFP_KERNEL);
+       if (!a3xx_gpu) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       gpu = &a3xx_gpu->base.base;
+
+       get_device(&pdev->dev);
+       a3xx_gpu->pdev = pdev;
+
+       gpu->fast_rate = config->fast_rate;
+       gpu->slow_rate = config->slow_rate;
+       gpu->bus_freq  = config->bus_freq;
+
+       DBG("fast_rate=%u, slow_rate=%u, bus_freq=%u",
+                       gpu->fast_rate, gpu->slow_rate, gpu->bus_freq);
+
+       ret = adreno_gpu_init(dev, pdev, &a3xx_gpu->base,
+                       &funcs, config->rev);
+       if (ret)
+               goto fail;
+
+       return &a3xx_gpu->base.base;
+
+fail:
+       if (a3xx_gpu)
+               a3xx_destroy(&a3xx_gpu->base.base);
+
+       return ERR_PTR(ret);
+}
+
+/*
+ * The a3xx device:
+ */
+
+static int a3xx_probe(struct platform_device *pdev)
+{
+       static struct adreno_platform_config config = {};
+#ifdef CONFIG_OF
+       /* TODO */
+#else
+       uint32_t version = socinfo_get_version();
+       if (cpu_is_apq8064ab()) {
+               config.fast_rate = 450000000;
+               config.slow_rate = 27000000;
+               config.bus_freq  = 4;
+               config.rev = ADRENO_REV(3, 2, 1, 0);
+       } else if (cpu_is_apq8064() || cpu_is_msm8960ab()) {
+               config.fast_rate = 400000000;
+               config.slow_rate = 27000000;
+               config.bus_freq  = 4;
+
+               if (SOCINFO_VERSION_MAJOR(version) == 2)
+                       config.rev = ADRENO_REV(3, 2, 0, 2);
+               else if ((SOCINFO_VERSION_MAJOR(version) == 1) &&
+                               (SOCINFO_VERSION_MINOR(version) == 1))
+                       config.rev = ADRENO_REV(3, 2, 0, 1);
+               else
+                       config.rev = ADRENO_REV(3, 2, 0, 0);
+
+       } else if (cpu_is_msm8930()) {
+               config.fast_rate = 400000000;
+               config.slow_rate = 27000000;
+               config.bus_freq  = 3;
+
+               if ((SOCINFO_VERSION_MAJOR(version) == 1) &&
+                       (SOCINFO_VERSION_MINOR(version) == 2))
+                       config.rev = ADRENO_REV(3, 0, 5, 2);
+               else
+                       config.rev = ADRENO_REV(3, 0, 5, 0);
+
+       }
+#endif
+       pdev->dev.platform_data = &config;
+       a3xx_pdev = pdev;
+       return 0;
+}
+
+static int a3xx_remove(struct platform_device *pdev)
+{
+       a3xx_pdev = NULL;
+       return 0;
+}
+
+static struct platform_driver a3xx_driver = {
+       .probe = a3xx_probe,
+       .remove = a3xx_remove,
+       .driver.name = "kgsl-3d0",
+};
+
+void __init a3xx_register(void)
+{
+       platform_driver_register(&a3xx_driver);
+}
+
+void __exit a3xx_unregister(void)
+{
+       platform_driver_unregister(&a3xx_driver);
+}
diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.h b/drivers/gpu/drm/msm/adreno/a3xx_gpu.h
new file mode 100644 (file)
index 0000000..32c398c
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __A3XX_GPU_H__
+#define __A3XX_GPU_H__
+
+#include "adreno_gpu.h"
+#include "a3xx.xml.h"
+
+struct a3xx_gpu {
+       struct adreno_gpu base;
+       struct platform_device *pdev;
+};
+#define to_a3xx_gpu(x) container_of(x, struct a3xx_gpu, base)
+
+#endif /* __A3XX_GPU_H__ */
diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h
new file mode 100644 (file)
index 0000000..61979d4
--- /dev/null
@@ -0,0 +1,432 @@
+#ifndef ADRENO_COMMON_XML
+#define ADRENO_COMMON_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml              (    327 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml           (  30005 bytes, from 2013-07-19 21:30:48)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml       (   8983 bytes, from 2013-07-24 01:38:36)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9712 bytes, from 2013-05-26 15:22:37)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51415 bytes, from 2013-08-03 14:26:05)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+enum adreno_pa_su_sc_draw {
+       PC_DRAW_POINTS = 0,
+       PC_DRAW_LINES = 1,
+       PC_DRAW_TRIANGLES = 2,
+};
+
+enum adreno_compare_func {
+       FUNC_NEVER = 0,
+       FUNC_LESS = 1,
+       FUNC_EQUAL = 2,
+       FUNC_LEQUAL = 3,
+       FUNC_GREATER = 4,
+       FUNC_NOTEQUAL = 5,
+       FUNC_GEQUAL = 6,
+       FUNC_ALWAYS = 7,
+};
+
+enum adreno_stencil_op {
+       STENCIL_KEEP = 0,
+       STENCIL_ZERO = 1,
+       STENCIL_REPLACE = 2,
+       STENCIL_INCR_CLAMP = 3,
+       STENCIL_DECR_CLAMP = 4,
+       STENCIL_INVERT = 5,
+       STENCIL_INCR_WRAP = 6,
+       STENCIL_DECR_WRAP = 7,
+};
+
+enum adreno_rb_blend_factor {
+       FACTOR_ZERO = 0,
+       FACTOR_ONE = 1,
+       FACTOR_SRC_COLOR = 4,
+       FACTOR_ONE_MINUS_SRC_COLOR = 5,
+       FACTOR_SRC_ALPHA = 6,
+       FACTOR_ONE_MINUS_SRC_ALPHA = 7,
+       FACTOR_DST_COLOR = 8,
+       FACTOR_ONE_MINUS_DST_COLOR = 9,
+       FACTOR_DST_ALPHA = 10,
+       FACTOR_ONE_MINUS_DST_ALPHA = 11,
+       FACTOR_CONSTANT_COLOR = 12,
+       FACTOR_ONE_MINUS_CONSTANT_COLOR = 13,
+       FACTOR_CONSTANT_ALPHA = 14,
+       FACTOR_ONE_MINUS_CONSTANT_ALPHA = 15,
+       FACTOR_SRC_ALPHA_SATURATE = 16,
+};
+
+enum adreno_rb_blend_opcode {
+       BLEND_DST_PLUS_SRC = 0,
+       BLEND_SRC_MINUS_DST = 1,
+       BLEND_MIN_DST_SRC = 2,
+       BLEND_MAX_DST_SRC = 3,
+       BLEND_DST_MINUS_SRC = 4,
+       BLEND_DST_PLUS_SRC_BIAS = 5,
+};
+
+enum adreno_rb_surface_endian {
+       ENDIAN_NONE = 0,
+       ENDIAN_8IN16 = 1,
+       ENDIAN_8IN32 = 2,
+       ENDIAN_16IN32 = 3,
+       ENDIAN_8IN64 = 4,
+       ENDIAN_8IN128 = 5,
+};
+
+enum adreno_rb_dither_mode {
+       DITHER_DISABLE = 0,
+       DITHER_ALWAYS = 1,
+       DITHER_IF_ALPHA_OFF = 2,
+};
+
+enum adreno_rb_depth_format {
+       DEPTHX_16 = 0,
+       DEPTHX_24_8 = 1,
+};
+
+enum adreno_mmu_clnt_beh {
+       BEH_NEVR = 0,
+       BEH_TRAN_RNG = 1,
+       BEH_TRAN_FLT = 2,
+};
+
+#define REG_AXXX_MH_MMU_CONFIG                                 0x00000040
+#define AXXX_MH_MMU_CONFIG_MMU_ENABLE                          0x00000001
+#define AXXX_MH_MMU_CONFIG_SPLIT_MODE_ENABLE                   0x00000002
+#define AXXX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR__MASK            0x00000030
+#define AXXX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR__SHIFT           4
+static inline uint32_t AXXX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_RB_W_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR__MASK            0x000000c0
+#define AXXX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR__SHIFT           6
+static inline uint32_t AXXX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_CP_W_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR__MASK           0x00000300
+#define AXXX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR__SHIFT          8
+static inline uint32_t AXXX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_CP_R0_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR__MASK           0x00000c00
+#define AXXX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR__SHIFT          10
+static inline uint32_t AXXX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_CP_R1_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR__MASK           0x00003000
+#define AXXX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR__SHIFT          12
+static inline uint32_t AXXX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_CP_R2_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR__MASK           0x0000c000
+#define AXXX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR__SHIFT          14
+static inline uint32_t AXXX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_CP_R3_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR__MASK           0x00030000
+#define AXXX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR__SHIFT          16
+static inline uint32_t AXXX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_CP_R4_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR__MASK          0x000c0000
+#define AXXX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR__SHIFT         18
+static inline uint32_t AXXX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_VGT_R0_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR__MASK          0x00300000
+#define AXXX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR__SHIFT         20
+static inline uint32_t AXXX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_VGT_R1_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR__MASK            0x00c00000
+#define AXXX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR__SHIFT           22
+static inline uint32_t AXXX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_TC_R_CLNT_BEHAVIOR__MASK;
+}
+#define AXXX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR__MASK            0x03000000
+#define AXXX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR__SHIFT           24
+static inline uint32_t AXXX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR(enum adreno_mmu_clnt_beh val)
+{
+       return ((val) << AXXX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR__SHIFT) & AXXX_MH_MMU_CONFIG_PA_W_CLNT_BEHAVIOR__MASK;
+}
+
+#define REG_AXXX_MH_MMU_VA_RANGE                               0x00000041
+
+#define REG_AXXX_MH_MMU_PT_BASE                                        0x00000042
+
+#define REG_AXXX_MH_MMU_PAGE_FAULT                             0x00000043
+
+#define REG_AXXX_MH_MMU_TRAN_ERROR                             0x00000044
+
+#define REG_AXXX_MH_MMU_INVALIDATE                             0x00000045
+
+#define REG_AXXX_MH_MMU_MPU_BASE                               0x00000046
+
+#define REG_AXXX_MH_MMU_MPU_END                                        0x00000047
+
+#define REG_AXXX_CP_RB_BASE                                    0x000001c0
+
+#define REG_AXXX_CP_RB_CNTL                                    0x000001c1
+#define AXXX_CP_RB_CNTL_BUFSZ__MASK                            0x0000003f
+#define AXXX_CP_RB_CNTL_BUFSZ__SHIFT                           0
+static inline uint32_t AXXX_CP_RB_CNTL_BUFSZ(uint32_t val)
+{
+       return ((val) << AXXX_CP_RB_CNTL_BUFSZ__SHIFT) & AXXX_CP_RB_CNTL_BUFSZ__MASK;
+}
+#define AXXX_CP_RB_CNTL_BLKSZ__MASK                            0x00003f00
+#define AXXX_CP_RB_CNTL_BLKSZ__SHIFT                           8
+static inline uint32_t AXXX_CP_RB_CNTL_BLKSZ(uint32_t val)
+{
+       return ((val) << AXXX_CP_RB_CNTL_BLKSZ__SHIFT) & AXXX_CP_RB_CNTL_BLKSZ__MASK;
+}
+#define AXXX_CP_RB_CNTL_BUF_SWAP__MASK                         0x00030000
+#define AXXX_CP_RB_CNTL_BUF_SWAP__SHIFT                                16
+static inline uint32_t AXXX_CP_RB_CNTL_BUF_SWAP(uint32_t val)
+{
+       return ((val) << AXXX_CP_RB_CNTL_BUF_SWAP__SHIFT) & AXXX_CP_RB_CNTL_BUF_SWAP__MASK;
+}
+#define AXXX_CP_RB_CNTL_POLL_EN                                        0x00100000
+#define AXXX_CP_RB_CNTL_NO_UPDATE                              0x08000000
+#define AXXX_CP_RB_CNTL_RPTR_WR_EN                             0x80000000
+
+#define REG_AXXX_CP_RB_RPTR_ADDR                               0x000001c3
+#define AXXX_CP_RB_RPTR_ADDR_SWAP__MASK                                0x00000003
+#define AXXX_CP_RB_RPTR_ADDR_SWAP__SHIFT                       0
+static inline uint32_t AXXX_CP_RB_RPTR_ADDR_SWAP(uint32_t val)
+{
+       return ((val) << AXXX_CP_RB_RPTR_ADDR_SWAP__SHIFT) & AXXX_CP_RB_RPTR_ADDR_SWAP__MASK;
+}
+#define AXXX_CP_RB_RPTR_ADDR_ADDR__MASK                                0xfffffffc
+#define AXXX_CP_RB_RPTR_ADDR_ADDR__SHIFT                       2
+static inline uint32_t AXXX_CP_RB_RPTR_ADDR_ADDR(uint32_t val)
+{
+       return ((val >> 2) << AXXX_CP_RB_RPTR_ADDR_ADDR__SHIFT) & AXXX_CP_RB_RPTR_ADDR_ADDR__MASK;
+}
+
+#define REG_AXXX_CP_RB_RPTR                                    0x000001c4
+
+#define REG_AXXX_CP_RB_WPTR                                    0x000001c5
+
+#define REG_AXXX_CP_RB_WPTR_DELAY                              0x000001c6
+
+#define REG_AXXX_CP_RB_RPTR_WR                                 0x000001c7
+
+#define REG_AXXX_CP_RB_WPTR_BASE                               0x000001c8
+
+#define REG_AXXX_CP_QUEUE_THRESHOLDS                           0x000001d5
+#define AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START__MASK           0x0000000f
+#define AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START__SHIFT          0
+static inline uint32_t AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START(uint32_t val)
+{
+       return ((val) << AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START__SHIFT) & AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB1_START__MASK;
+}
+#define AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START__MASK           0x00000f00
+#define AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START__SHIFT          8
+static inline uint32_t AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START(uint32_t val)
+{
+       return ((val) << AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START__SHIFT) & AXXX_CP_QUEUE_THRESHOLDS_CSQ_IB2_START__MASK;
+}
+#define AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START__MASK            0x000f0000
+#define AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START__SHIFT           16
+static inline uint32_t AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START(uint32_t val)
+{
+       return ((val) << AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START__SHIFT) & AXXX_CP_QUEUE_THRESHOLDS_CSQ_ST_START__MASK;
+}
+
+#define REG_AXXX_CP_MEQ_THRESHOLDS                             0x000001d6
+
+#define REG_AXXX_CP_CSQ_AVAIL                                  0x000001d7
+#define AXXX_CP_CSQ_AVAIL_RING__MASK                           0x0000007f
+#define AXXX_CP_CSQ_AVAIL_RING__SHIFT                          0
+static inline uint32_t AXXX_CP_CSQ_AVAIL_RING(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_AVAIL_RING__SHIFT) & AXXX_CP_CSQ_AVAIL_RING__MASK;
+}
+#define AXXX_CP_CSQ_AVAIL_IB1__MASK                            0x00007f00
+#define AXXX_CP_CSQ_AVAIL_IB1__SHIFT                           8
+static inline uint32_t AXXX_CP_CSQ_AVAIL_IB1(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_AVAIL_IB1__SHIFT) & AXXX_CP_CSQ_AVAIL_IB1__MASK;
+}
+#define AXXX_CP_CSQ_AVAIL_IB2__MASK                            0x007f0000
+#define AXXX_CP_CSQ_AVAIL_IB2__SHIFT                           16
+static inline uint32_t AXXX_CP_CSQ_AVAIL_IB2(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_AVAIL_IB2__SHIFT) & AXXX_CP_CSQ_AVAIL_IB2__MASK;
+}
+
+#define REG_AXXX_CP_STQ_AVAIL                                  0x000001d8
+#define AXXX_CP_STQ_AVAIL_ST__MASK                             0x0000007f
+#define AXXX_CP_STQ_AVAIL_ST__SHIFT                            0
+static inline uint32_t AXXX_CP_STQ_AVAIL_ST(uint32_t val)
+{
+       return ((val) << AXXX_CP_STQ_AVAIL_ST__SHIFT) & AXXX_CP_STQ_AVAIL_ST__MASK;
+}
+
+#define REG_AXXX_CP_MEQ_AVAIL                                  0x000001d9
+#define AXXX_CP_MEQ_AVAIL_MEQ__MASK                            0x0000001f
+#define AXXX_CP_MEQ_AVAIL_MEQ__SHIFT                           0
+static inline uint32_t AXXX_CP_MEQ_AVAIL_MEQ(uint32_t val)
+{
+       return ((val) << AXXX_CP_MEQ_AVAIL_MEQ__SHIFT) & AXXX_CP_MEQ_AVAIL_MEQ__MASK;
+}
+
+#define REG_AXXX_SCRATCH_UMSK                                  0x000001dc
+#define AXXX_SCRATCH_UMSK_UMSK__MASK                           0x000000ff
+#define AXXX_SCRATCH_UMSK_UMSK__SHIFT                          0
+static inline uint32_t AXXX_SCRATCH_UMSK_UMSK(uint32_t val)
+{
+       return ((val) << AXXX_SCRATCH_UMSK_UMSK__SHIFT) & AXXX_SCRATCH_UMSK_UMSK__MASK;
+}
+#define AXXX_SCRATCH_UMSK_SWAP__MASK                           0x00030000
+#define AXXX_SCRATCH_UMSK_SWAP__SHIFT                          16
+static inline uint32_t AXXX_SCRATCH_UMSK_SWAP(uint32_t val)
+{
+       return ((val) << AXXX_SCRATCH_UMSK_SWAP__SHIFT) & AXXX_SCRATCH_UMSK_SWAP__MASK;
+}
+
+#define REG_AXXX_SCRATCH_ADDR                                  0x000001dd
+
+#define REG_AXXX_CP_ME_RDADDR                                  0x000001ea
+
+#define REG_AXXX_CP_STATE_DEBUG_INDEX                          0x000001ec
+
+#define REG_AXXX_CP_STATE_DEBUG_DATA                           0x000001ed
+
+#define REG_AXXX_CP_INT_CNTL                                   0x000001f2
+
+#define REG_AXXX_CP_INT_STATUS                                 0x000001f3
+
+#define REG_AXXX_CP_INT_ACK                                    0x000001f4
+
+#define REG_AXXX_CP_ME_CNTL                                    0x000001f6
+
+#define REG_AXXX_CP_ME_STATUS                                  0x000001f7
+
+#define REG_AXXX_CP_ME_RAM_WADDR                               0x000001f8
+
+#define REG_AXXX_CP_ME_RAM_RADDR                               0x000001f9
+
+#define REG_AXXX_CP_ME_RAM_DATA                                        0x000001fa
+
+#define REG_AXXX_CP_DEBUG                                      0x000001fc
+#define AXXX_CP_DEBUG_PREDICATE_DISABLE                                0x00800000
+#define AXXX_CP_DEBUG_PROG_END_PTR_ENABLE                      0x01000000
+#define AXXX_CP_DEBUG_MIU_128BIT_WRITE_ENABLE                  0x02000000
+#define AXXX_CP_DEBUG_PREFETCH_PASS_NOPS                       0x04000000
+#define AXXX_CP_DEBUG_DYNAMIC_CLK_DISABLE                      0x08000000
+#define AXXX_CP_DEBUG_PREFETCH_MATCH_DISABLE                   0x10000000
+#define AXXX_CP_DEBUG_SIMPLE_ME_FLOW_CONTROL                   0x40000000
+#define AXXX_CP_DEBUG_MIU_WRITE_PACK_DISABLE                   0x80000000
+
+#define REG_AXXX_CP_CSQ_RB_STAT                                        0x000001fd
+#define AXXX_CP_CSQ_RB_STAT_RPTR__MASK                         0x0000007f
+#define AXXX_CP_CSQ_RB_STAT_RPTR__SHIFT                                0
+static inline uint32_t AXXX_CP_CSQ_RB_STAT_RPTR(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_RB_STAT_RPTR__SHIFT) & AXXX_CP_CSQ_RB_STAT_RPTR__MASK;
+}
+#define AXXX_CP_CSQ_RB_STAT_WPTR__MASK                         0x007f0000
+#define AXXX_CP_CSQ_RB_STAT_WPTR__SHIFT                                16
+static inline uint32_t AXXX_CP_CSQ_RB_STAT_WPTR(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_RB_STAT_WPTR__SHIFT) & AXXX_CP_CSQ_RB_STAT_WPTR__MASK;
+}
+
+#define REG_AXXX_CP_CSQ_IB1_STAT                               0x000001fe
+#define AXXX_CP_CSQ_IB1_STAT_RPTR__MASK                                0x0000007f
+#define AXXX_CP_CSQ_IB1_STAT_RPTR__SHIFT                       0
+static inline uint32_t AXXX_CP_CSQ_IB1_STAT_RPTR(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_IB1_STAT_RPTR__SHIFT) & AXXX_CP_CSQ_IB1_STAT_RPTR__MASK;
+}
+#define AXXX_CP_CSQ_IB1_STAT_WPTR__MASK                                0x007f0000
+#define AXXX_CP_CSQ_IB1_STAT_WPTR__SHIFT                       16
+static inline uint32_t AXXX_CP_CSQ_IB1_STAT_WPTR(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_IB1_STAT_WPTR__SHIFT) & AXXX_CP_CSQ_IB1_STAT_WPTR__MASK;
+}
+
+#define REG_AXXX_CP_CSQ_IB2_STAT                               0x000001ff
+#define AXXX_CP_CSQ_IB2_STAT_RPTR__MASK                                0x0000007f
+#define AXXX_CP_CSQ_IB2_STAT_RPTR__SHIFT                       0
+static inline uint32_t AXXX_CP_CSQ_IB2_STAT_RPTR(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_IB2_STAT_RPTR__SHIFT) & AXXX_CP_CSQ_IB2_STAT_RPTR__MASK;
+}
+#define AXXX_CP_CSQ_IB2_STAT_WPTR__MASK                                0x007f0000
+#define AXXX_CP_CSQ_IB2_STAT_WPTR__SHIFT                       16
+static inline uint32_t AXXX_CP_CSQ_IB2_STAT_WPTR(uint32_t val)
+{
+       return ((val) << AXXX_CP_CSQ_IB2_STAT_WPTR__SHIFT) & AXXX_CP_CSQ_IB2_STAT_WPTR__MASK;
+}
+
+#define REG_AXXX_CP_SCRATCH_REG0                               0x00000578
+
+#define REG_AXXX_CP_SCRATCH_REG1                               0x00000579
+
+#define REG_AXXX_CP_SCRATCH_REG2                               0x0000057a
+
+#define REG_AXXX_CP_SCRATCH_REG3                               0x0000057b
+
+#define REG_AXXX_CP_SCRATCH_REG4                               0x0000057c
+
+#define REG_AXXX_CP_SCRATCH_REG5                               0x0000057d
+
+#define REG_AXXX_CP_SCRATCH_REG6                               0x0000057e
+
+#define REG_AXXX_CP_SCRATCH_REG7                               0x0000057f
+
+#define REG_AXXX_CP_ME_CF_EVENT_SRC                            0x0000060a
+
+#define REG_AXXX_CP_ME_CF_EVENT_ADDR                           0x0000060b
+
+#define REG_AXXX_CP_ME_CF_EVENT_DATA                           0x0000060c
+
+#define REG_AXXX_CP_ME_NRT_ADDR                                        0x0000060d
+
+#define REG_AXXX_CP_ME_NRT_DATA                                        0x0000060e
+
+
+#endif /* ADRENO_COMMON_XML */
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
new file mode 100644 (file)
index 0000000..a605847
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "adreno_gpu.h"
+#include "msm_gem.h"
+
+struct adreno_info {
+       struct adreno_rev rev;
+       uint32_t revn;
+       const char *name;
+       const char *pm4fw, *pfpfw;
+       uint32_t gmem;
+};
+
+#define ANY_ID 0xff
+
+static const struct adreno_info gpulist[] = {
+       {
+               .rev   = ADRENO_REV(3, 0, 5, ANY_ID),
+               .revn  = 305,
+               .name  = "A305",
+               .pm4fw = "a300_pm4.fw",
+               .pfpfw = "a300_pfp.fw",
+               .gmem  = SZ_256K,
+       }, {
+               .rev   = ADRENO_REV(3, 2, ANY_ID, ANY_ID),
+               .revn  = 320,
+               .name  = "A320",
+               .pm4fw = "a300_pm4.fw",
+               .pfpfw = "a300_pfp.fw",
+               .gmem  = SZ_512K,
+       }, {
+               .rev   = ADRENO_REV(3, 3, 0, 0),
+               .revn  = 330,
+               .name  = "A330",
+               .pm4fw = "a330_pm4.fw",
+               .pfpfw = "a330_pfp.fw",
+               .gmem  = SZ_1M,
+       },
+};
+
+#define RB_SIZE    SZ_32K
+#define RB_BLKSIZE 16
+
+int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+
+       switch (param) {
+       case MSM_PARAM_GPU_ID:
+               *value = adreno_gpu->info->revn;
+               return 0;
+       case MSM_PARAM_GMEM_SIZE:
+               *value = adreno_gpu->info->gmem;
+               return 0;
+       default:
+               DBG("%s: invalid param: %u", gpu->name, param);
+               return -EINVAL;
+       }
+}
+
+#define rbmemptr(adreno_gpu, member)  \
+       ((adreno_gpu)->memptrs_iova + offsetof(struct adreno_rbmemptrs, member))
+
+int adreno_hw_init(struct msm_gpu *gpu)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+
+       DBG("%s", gpu->name);
+
+       /* Setup REG_CP_RB_CNTL: */
+       gpu_write(gpu, REG_AXXX_CP_RB_CNTL,
+                       /* size is log2(quad-words): */
+                       AXXX_CP_RB_CNTL_BUFSZ(ilog2(gpu->rb->size / 8)) |
+                       AXXX_CP_RB_CNTL_BLKSZ(RB_BLKSIZE));
+
+       /* Setup ringbuffer address: */
+       gpu_write(gpu, REG_AXXX_CP_RB_BASE, gpu->rb_iova);
+       gpu_write(gpu, REG_AXXX_CP_RB_RPTR_ADDR, rbmemptr(adreno_gpu, rptr));
+
+       /* Setup scratch/timestamp: */
+       gpu_write(gpu, REG_AXXX_SCRATCH_ADDR, rbmemptr(adreno_gpu, fence));
+
+       gpu_write(gpu, REG_AXXX_SCRATCH_UMSK, 0x1);
+
+       return 0;
+}
+
+static uint32_t get_wptr(struct msm_ringbuffer *ring)
+{
+       return ring->cur - ring->start;
+}
+
+uint32_t adreno_last_fence(struct msm_gpu *gpu)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       return adreno_gpu->memptrs->fence;
+}
+
+void adreno_recover(struct msm_gpu *gpu)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       struct drm_device *dev = gpu->dev;
+       int ret;
+
+       gpu->funcs->pm_suspend(gpu);
+
+       /* reset ringbuffer: */
+       gpu->rb->cur = gpu->rb->start;
+
+       /* reset completed fence seqno, just discard anything pending: */
+       adreno_gpu->memptrs->fence = gpu->submitted_fence;
+
+       gpu->funcs->pm_resume(gpu);
+       ret = gpu->funcs->hw_init(gpu);
+       if (ret) {
+               dev_err(dev->dev, "gpu hw init failed: %d\n", ret);
+               /* hmm, oh well? */
+       }
+}
+
+int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
+               struct msm_file_private *ctx)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       struct msm_drm_private *priv = gpu->dev->dev_private;
+       struct msm_ringbuffer *ring = gpu->rb;
+       unsigned i, ibs = 0;
+
+       for (i = 0; i < submit->nr_cmds; i++) {
+               switch (submit->cmd[i].type) {
+               case MSM_SUBMIT_CMD_IB_TARGET_BUF:
+                       /* ignore IB-targets */
+                       break;
+               case MSM_SUBMIT_CMD_CTX_RESTORE_BUF:
+                       /* ignore if there has not been a ctx switch: */
+                       if (priv->lastctx == ctx)
+                               break;
+               case MSM_SUBMIT_CMD_BUF:
+                       OUT_PKT3(ring, CP_INDIRECT_BUFFER_PFD, 2);
+                       OUT_RING(ring, submit->cmd[i].iova);
+                       OUT_RING(ring, submit->cmd[i].size);
+                       ibs++;
+                       break;
+               }
+       }
+
+       /* on a320, at least, we seem to need to pad things out to an
+        * even number of qwords to avoid issue w/ CP hanging on wrap-
+        * around:
+        */
+       if (ibs % 2)
+               OUT_PKT2(ring);
+
+       OUT_PKT0(ring, REG_AXXX_CP_SCRATCH_REG2, 1);
+       OUT_RING(ring, submit->fence);
+
+       if (adreno_is_a3xx(adreno_gpu)) {
+               /* Flush HLSQ lazy updates to make sure there is nothing
+                * pending for indirect loads after the timestamp has
+                * passed:
+                */
+               OUT_PKT3(ring, CP_EVENT_WRITE, 1);
+               OUT_RING(ring, HLSQ_FLUSH);
+
+               OUT_PKT3(ring, CP_WAIT_FOR_IDLE, 1);
+               OUT_RING(ring, 0x00000000);
+       }
+
+       OUT_PKT3(ring, CP_EVENT_WRITE, 3);
+       OUT_RING(ring, CACHE_FLUSH_TS);
+       OUT_RING(ring, rbmemptr(adreno_gpu, fence));
+       OUT_RING(ring, submit->fence);
+
+       /* we could maybe be clever and only CP_COND_EXEC the interrupt: */
+       OUT_PKT3(ring, CP_INTERRUPT, 1);
+       OUT_RING(ring, 0x80000000);
+
+#if 0
+       if (adreno_is_a3xx(adreno_gpu)) {
+               /* Dummy set-constant to trigger context rollover */
+               OUT_PKT3(ring, CP_SET_CONSTANT, 2);
+               OUT_RING(ring, CP_REG(REG_A3XX_HLSQ_CL_KERNEL_GROUP_X_REG));
+               OUT_RING(ring, 0x00000000);
+       }
+#endif
+
+       gpu->funcs->flush(gpu);
+
+       return 0;
+}
+
+void adreno_flush(struct msm_gpu *gpu)
+{
+       uint32_t wptr = get_wptr(gpu->rb);
+
+       /* ensure writes to ringbuffer have hit system memory: */
+       mb();
+
+       gpu_write(gpu, REG_AXXX_CP_RB_WPTR, wptr);
+}
+
+void adreno_idle(struct msm_gpu *gpu)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       uint32_t rptr, wptr = get_wptr(gpu->rb);
+       unsigned long t;
+
+       t = jiffies + ADRENO_IDLE_TIMEOUT;
+
+       /* then wait for CP to drain ringbuffer: */
+       do {
+               rptr = adreno_gpu->memptrs->rptr;
+               if (rptr == wptr)
+                       return;
+       } while(time_before(jiffies, t));
+
+       DRM_ERROR("timeout waiting for %s to drain ringbuffer!\n", gpu->name);
+
+       /* TODO maybe we need to reset GPU here to recover from hang? */
+}
+
+#ifdef CONFIG_DEBUG_FS
+void adreno_show(struct msm_gpu *gpu, struct seq_file *m)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+
+       seq_printf(m, "revision: %d (%d.%d.%d.%d)\n",
+                       adreno_gpu->info->revn, adreno_gpu->rev.core,
+                       adreno_gpu->rev.major, adreno_gpu->rev.minor,
+                       adreno_gpu->rev.patchid);
+
+       seq_printf(m, "fence:    %d/%d\n", adreno_gpu->memptrs->fence,
+                       gpu->submitted_fence);
+       seq_printf(m, "rptr:     %d\n", adreno_gpu->memptrs->rptr);
+       seq_printf(m, "wptr:     %d\n", adreno_gpu->memptrs->wptr);
+       seq_printf(m, "rb wptr:  %d\n", get_wptr(gpu->rb));
+}
+#endif
+
+void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords)
+{
+       struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
+       uint32_t freedwords;
+       do {
+               uint32_t size = gpu->rb->size / 4;
+               uint32_t wptr = get_wptr(gpu->rb);
+               uint32_t rptr = adreno_gpu->memptrs->rptr;
+               freedwords = (rptr + (size - 1) - wptr) % size;
+       } while(freedwords < ndwords);
+}
+
+static const char *iommu_ports[] = {
+               "gfx3d_user", "gfx3d_priv",
+               "gfx3d1_user", "gfx3d1_priv",
+};
+
+static inline bool _rev_match(uint8_t entry, uint8_t id)
+{
+       return (entry == ANY_ID) || (entry == id);
+}
+
+int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+               struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
+               struct adreno_rev rev)
+{
+       int i, ret;
+
+       /* identify gpu: */
+       for (i = 0; i < ARRAY_SIZE(gpulist); i++) {
+               const struct adreno_info *info = &gpulist[i];
+               if (_rev_match(info->rev.core, rev.core) &&
+                               _rev_match(info->rev.major, rev.major) &&
+                               _rev_match(info->rev.minor, rev.minor) &&
+                               _rev_match(info->rev.patchid, rev.patchid)) {
+                       gpu->info = info;
+                       gpu->revn = info->revn;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(gpulist)) {
+               dev_err(drm->dev, "Unknown GPU revision: %u.%u.%u.%u\n",
+                               rev.core, rev.major, rev.minor, rev.patchid);
+               return -ENXIO;
+       }
+
+       DBG("Found GPU: %s (%u.%u.%u.%u)", gpu->info->name,
+                       rev.core, rev.major, rev.minor, rev.patchid);
+
+       gpu->funcs = funcs;
+       gpu->rev = rev;
+
+       ret = request_firmware(&gpu->pm4, gpu->info->pm4fw, drm->dev);
+       if (ret) {
+               dev_err(drm->dev, "failed to load %s PM4 firmware: %d\n",
+                               gpu->info->pm4fw, ret);
+               return ret;
+       }
+
+       ret = request_firmware(&gpu->pfp, gpu->info->pfpfw, drm->dev);
+       if (ret) {
+               dev_err(drm->dev, "failed to load %s PFP firmware: %d\n",
+                               gpu->info->pfpfw, ret);
+               return ret;
+       }
+
+       ret = msm_gpu_init(drm, pdev, &gpu->base, &funcs->base,
+                       gpu->info->name, "kgsl_3d0_reg_memory", "kgsl_3d0_irq",
+                       RB_SIZE);
+       if (ret)
+               return ret;
+
+       ret = msm_iommu_attach(drm, gpu->base.iommu,
+                       iommu_ports, ARRAY_SIZE(iommu_ports));
+       if (ret)
+               return ret;
+
+       gpu->memptrs_bo = msm_gem_new(drm, sizeof(*gpu->memptrs),
+                       MSM_BO_UNCACHED);
+       if (IS_ERR(gpu->memptrs_bo)) {
+               ret = PTR_ERR(gpu->memptrs_bo);
+               gpu->memptrs_bo = NULL;
+               dev_err(drm->dev, "could not allocate memptrs: %d\n", ret);
+               return ret;
+       }
+
+       gpu->memptrs = msm_gem_vaddr_locked(gpu->memptrs_bo);
+       if (!gpu->memptrs) {
+               dev_err(drm->dev, "could not vmap memptrs\n");
+               return -ENOMEM;
+       }
+
+       ret = msm_gem_get_iova_locked(gpu->memptrs_bo, gpu->base.id,
+                       &gpu->memptrs_iova);
+       if (ret) {
+               dev_err(drm->dev, "could not map memptrs: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+void adreno_gpu_cleanup(struct adreno_gpu *gpu)
+{
+       if (gpu->memptrs_bo) {
+               if (gpu->memptrs_iova)
+                       msm_gem_put_iova(gpu->memptrs_bo, gpu->base.id);
+               drm_gem_object_unreference(gpu->memptrs_bo);
+       }
+       if (gpu->pm4)
+               release_firmware(gpu->pm4);
+       if (gpu->pfp)
+               release_firmware(gpu->pfp);
+       msm_gpu_cleanup(&gpu->base);
+}
diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h
new file mode 100644 (file)
index 0000000..f73abfb
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ADRENO_GPU_H__
+#define __ADRENO_GPU_H__
+
+#include <linux/firmware.h>
+
+#include "msm_gpu.h"
+
+#include "adreno_common.xml.h"
+#include "adreno_pm4.xml.h"
+
+struct adreno_rev {
+       uint8_t  core;
+       uint8_t  major;
+       uint8_t  minor;
+       uint8_t  patchid;
+};
+
+#define ADRENO_REV(core, major, minor, patchid) \
+       ((struct adreno_rev){ core, major, minor, patchid })
+
+struct adreno_gpu_funcs {
+       struct msm_gpu_funcs base;
+};
+
+struct adreno_info;
+
+struct adreno_rbmemptrs {
+       volatile uint32_t rptr;
+       volatile uint32_t wptr;
+       volatile uint32_t fence;
+};
+
+struct adreno_gpu {
+       struct msm_gpu base;
+       struct adreno_rev rev;
+       const struct adreno_info *info;
+       uint32_t revn;  /* numeric revision name */
+       const struct adreno_gpu_funcs *funcs;
+
+       /* firmware: */
+       const struct firmware *pm4, *pfp;
+
+       /* ringbuffer rptr/wptr: */
+       // TODO should this be in msm_ringbuffer?  I think it would be
+       // different for z180..
+       struct adreno_rbmemptrs *memptrs;
+       struct drm_gem_object *memptrs_bo;
+       uint32_t memptrs_iova;
+};
+#define to_adreno_gpu(x) container_of(x, struct adreno_gpu, base)
+
+/* platform config data (ie. from DT, or pdata) */
+struct adreno_platform_config {
+       struct adreno_rev rev;
+       uint32_t fast_rate, slow_rate, bus_freq;
+};
+
+#define ADRENO_IDLE_TIMEOUT (20 * 1000)
+
+static inline bool adreno_is_a3xx(struct adreno_gpu *gpu)
+{
+       return (gpu->revn >= 300) && (gpu->revn < 400);
+}
+
+static inline bool adreno_is_a305(struct adreno_gpu *gpu)
+{
+       return gpu->revn == 305;
+}
+
+static inline bool adreno_is_a320(struct adreno_gpu *gpu)
+{
+       return gpu->revn == 320;
+}
+
+static inline bool adreno_is_a330(struct adreno_gpu *gpu)
+{
+       return gpu->revn == 330;
+}
+
+int adreno_get_param(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
+int adreno_hw_init(struct msm_gpu *gpu);
+uint32_t adreno_last_fence(struct msm_gpu *gpu);
+void adreno_recover(struct msm_gpu *gpu);
+int adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
+               struct msm_file_private *ctx);
+void adreno_flush(struct msm_gpu *gpu);
+void adreno_idle(struct msm_gpu *gpu);
+#ifdef CONFIG_DEBUG_FS
+void adreno_show(struct msm_gpu *gpu, struct seq_file *m);
+#endif
+void adreno_wait_ring(struct msm_gpu *gpu, uint32_t ndwords);
+
+int adreno_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+               struct adreno_gpu *gpu, const struct adreno_gpu_funcs *funcs,
+               struct adreno_rev rev);
+void adreno_gpu_cleanup(struct adreno_gpu *gpu);
+
+
+/* ringbuffer helpers (the parts that are adreno specific) */
+
+static inline void
+OUT_PKT0(struct msm_ringbuffer *ring, uint16_t regindx, uint16_t cnt)
+{
+       adreno_wait_ring(ring->gpu, cnt+1);
+       OUT_RING(ring, CP_TYPE0_PKT | ((cnt-1) << 16) | (regindx & 0x7FFF));
+}
+
+/* no-op packet: */
+static inline void
+OUT_PKT2(struct msm_ringbuffer *ring)
+{
+       adreno_wait_ring(ring->gpu, 1);
+       OUT_RING(ring, CP_TYPE2_PKT);
+}
+
+static inline void
+OUT_PKT3(struct msm_ringbuffer *ring, uint8_t opcode, uint16_t cnt)
+{
+       adreno_wait_ring(ring->gpu, cnt+1);
+       OUT_RING(ring, CP_TYPE3_PKT | ((cnt-1) << 16) | ((opcode & 0xFF) << 8));
+}
+
+
+#endif /* __ADRENO_GPU_H__ */
diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h
new file mode 100644 (file)
index 0000000..94c13f4
--- /dev/null
@@ -0,0 +1,254 @@
+#ifndef ADRENO_PM4_XML
+#define ADRENO_PM4_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/adreno.xml              (    327 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/a2xx/a2xx.xml           (  30005 bytes, from 2013-07-19 21:30:48)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_common.xml       (   8983 bytes, from 2013-07-24 01:38:36)
+- /home/robclark/src/freedreno/envytools/rnndb/adreno_pm4.xml          (   9712 bytes, from 2013-05-26 15:22:37)
+- /home/robclark/src/freedreno/envytools/rnndb/a3xx/a3xx.xml           (  51415 bytes, from 2013-08-03 14:26:05)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+enum vgt_event_type {
+       VS_DEALLOC = 0,
+       PS_DEALLOC = 1,
+       VS_DONE_TS = 2,
+       PS_DONE_TS = 3,
+       CACHE_FLUSH_TS = 4,
+       CONTEXT_DONE = 5,
+       CACHE_FLUSH = 6,
+       HLSQ_FLUSH = 7,
+       VIZQUERY_START = 7,
+       VIZQUERY_END = 8,
+       SC_WAIT_WC = 9,
+       RST_PIX_CNT = 13,
+       RST_VTX_CNT = 14,
+       TILE_FLUSH = 15,
+       CACHE_FLUSH_AND_INV_TS_EVENT = 20,
+       ZPASS_DONE = 21,
+       CACHE_FLUSH_AND_INV_EVENT = 22,
+       PERFCOUNTER_START = 23,
+       PERFCOUNTER_STOP = 24,
+       VS_FETCH_DONE = 27,
+       FACENESS_FLUSH = 28,
+};
+
+enum pc_di_primtype {
+       DI_PT_NONE = 0,
+       DI_PT_POINTLIST = 1,
+       DI_PT_LINELIST = 2,
+       DI_PT_LINESTRIP = 3,
+       DI_PT_TRILIST = 4,
+       DI_PT_TRIFAN = 5,
+       DI_PT_TRISTRIP = 6,
+       DI_PT_RECTLIST = 8,
+       DI_PT_QUADLIST = 13,
+       DI_PT_QUADSTRIP = 14,
+       DI_PT_POLYGON = 15,
+       DI_PT_2D_COPY_RECT_LIST_V0 = 16,
+       DI_PT_2D_COPY_RECT_LIST_V1 = 17,
+       DI_PT_2D_COPY_RECT_LIST_V2 = 18,
+       DI_PT_2D_COPY_RECT_LIST_V3 = 19,
+       DI_PT_2D_FILL_RECT_LIST = 20,
+       DI_PT_2D_LINE_STRIP = 21,
+       DI_PT_2D_TRI_STRIP = 22,
+};
+
+enum pc_di_src_sel {
+       DI_SRC_SEL_DMA = 0,
+       DI_SRC_SEL_IMMEDIATE = 1,
+       DI_SRC_SEL_AUTO_INDEX = 2,
+       DI_SRC_SEL_RESERVED = 3,
+};
+
+enum pc_di_index_size {
+       INDEX_SIZE_IGN = 0,
+       INDEX_SIZE_16_BIT = 0,
+       INDEX_SIZE_32_BIT = 1,
+       INDEX_SIZE_8_BIT = 2,
+       INDEX_SIZE_INVALID = 0,
+};
+
+enum pc_di_vis_cull_mode {
+       IGNORE_VISIBILITY = 0,
+};
+
+enum adreno_pm4_packet_type {
+       CP_TYPE0_PKT = 0,
+       CP_TYPE1_PKT = 0x40000000,
+       CP_TYPE2_PKT = 0x80000000,
+       CP_TYPE3_PKT = 0xc0000000,
+};
+
+enum adreno_pm4_type3_packets {
+       CP_ME_INIT = 72,
+       CP_NOP = 16,
+       CP_INDIRECT_BUFFER = 63,
+       CP_INDIRECT_BUFFER_PFD = 55,
+       CP_WAIT_FOR_IDLE = 38,
+       CP_WAIT_REG_MEM = 60,
+       CP_WAIT_REG_EQ = 82,
+       CP_WAT_REG_GTE = 83,
+       CP_WAIT_UNTIL_READ = 92,
+       CP_WAIT_IB_PFD_COMPLETE = 93,
+       CP_REG_RMW = 33,
+       CP_SET_BIN_DATA = 47,
+       CP_REG_TO_MEM = 62,
+       CP_MEM_WRITE = 61,
+       CP_MEM_WRITE_CNTR = 79,
+       CP_COND_EXEC = 68,
+       CP_COND_WRITE = 69,
+       CP_EVENT_WRITE = 70,
+       CP_EVENT_WRITE_SHD = 88,
+       CP_EVENT_WRITE_CFL = 89,
+       CP_EVENT_WRITE_ZPD = 91,
+       CP_RUN_OPENCL = 49,
+       CP_DRAW_INDX = 34,
+       CP_DRAW_INDX_2 = 54,
+       CP_DRAW_INDX_BIN = 52,
+       CP_DRAW_INDX_2_BIN = 53,
+       CP_VIZ_QUERY = 35,
+       CP_SET_STATE = 37,
+       CP_SET_CONSTANT = 45,
+       CP_IM_LOAD = 39,
+       CP_IM_LOAD_IMMEDIATE = 43,
+       CP_LOAD_CONSTANT_CONTEXT = 46,
+       CP_INVALIDATE_STATE = 59,
+       CP_SET_SHADER_BASES = 74,
+       CP_SET_BIN_MASK = 80,
+       CP_SET_BIN_SELECT = 81,
+       CP_CONTEXT_UPDATE = 94,
+       CP_INTERRUPT = 64,
+       CP_IM_STORE = 44,
+       CP_SET_BIN_BASE_OFFSET = 75,
+       CP_SET_DRAW_INIT_FLAGS = 75,
+       CP_SET_PROTECTED_MODE = 95,
+       CP_LOAD_STATE = 48,
+       CP_COND_INDIRECT_BUFFER_PFE = 58,
+       CP_COND_INDIRECT_BUFFER_PFD = 50,
+       CP_INDIRECT_BUFFER_PFE = 63,
+       CP_SET_BIN = 76,
+};
+
+enum adreno_state_block {
+       SB_VERT_TEX = 0,
+       SB_VERT_MIPADDR = 1,
+       SB_FRAG_TEX = 2,
+       SB_FRAG_MIPADDR = 3,
+       SB_VERT_SHADER = 4,
+       SB_FRAG_SHADER = 6,
+};
+
+enum adreno_state_type {
+       ST_SHADER = 0,
+       ST_CONSTANTS = 1,
+};
+
+enum adreno_state_src {
+       SS_DIRECT = 0,
+       SS_INDIRECT = 4,
+};
+
+#define REG_CP_LOAD_STATE_0                                    0x00000000
+#define CP_LOAD_STATE_0_DST_OFF__MASK                          0x0000ffff
+#define CP_LOAD_STATE_0_DST_OFF__SHIFT                         0
+static inline uint32_t CP_LOAD_STATE_0_DST_OFF(uint32_t val)
+{
+       return ((val) << CP_LOAD_STATE_0_DST_OFF__SHIFT) & CP_LOAD_STATE_0_DST_OFF__MASK;
+}
+#define CP_LOAD_STATE_0_STATE_SRC__MASK                                0x00070000
+#define CP_LOAD_STATE_0_STATE_SRC__SHIFT                       16
+static inline uint32_t CP_LOAD_STATE_0_STATE_SRC(enum adreno_state_src val)
+{
+       return ((val) << CP_LOAD_STATE_0_STATE_SRC__SHIFT) & CP_LOAD_STATE_0_STATE_SRC__MASK;
+}
+#define CP_LOAD_STATE_0_STATE_BLOCK__MASK                      0x00380000
+#define CP_LOAD_STATE_0_STATE_BLOCK__SHIFT                     19
+static inline uint32_t CP_LOAD_STATE_0_STATE_BLOCK(enum adreno_state_block val)
+{
+       return ((val) << CP_LOAD_STATE_0_STATE_BLOCK__SHIFT) & CP_LOAD_STATE_0_STATE_BLOCK__MASK;
+}
+#define CP_LOAD_STATE_0_NUM_UNIT__MASK                         0x7fc00000
+#define CP_LOAD_STATE_0_NUM_UNIT__SHIFT                                22
+static inline uint32_t CP_LOAD_STATE_0_NUM_UNIT(uint32_t val)
+{
+       return ((val) << CP_LOAD_STATE_0_NUM_UNIT__SHIFT) & CP_LOAD_STATE_0_NUM_UNIT__MASK;
+}
+
+#define REG_CP_LOAD_STATE_1                                    0x00000001
+#define CP_LOAD_STATE_1_STATE_TYPE__MASK                       0x00000003
+#define CP_LOAD_STATE_1_STATE_TYPE__SHIFT                      0
+static inline uint32_t CP_LOAD_STATE_1_STATE_TYPE(enum adreno_state_type val)
+{
+       return ((val) << CP_LOAD_STATE_1_STATE_TYPE__SHIFT) & CP_LOAD_STATE_1_STATE_TYPE__MASK;
+}
+#define CP_LOAD_STATE_1_EXT_SRC_ADDR__MASK                     0xfffffffc
+#define CP_LOAD_STATE_1_EXT_SRC_ADDR__SHIFT                    2
+static inline uint32_t CP_LOAD_STATE_1_EXT_SRC_ADDR(uint32_t val)
+{
+       return ((val >> 2) << CP_LOAD_STATE_1_EXT_SRC_ADDR__SHIFT) & CP_LOAD_STATE_1_EXT_SRC_ADDR__MASK;
+}
+
+#define REG_CP_SET_BIN_0                                       0x00000000
+
+#define REG_CP_SET_BIN_1                                       0x00000001
+#define CP_SET_BIN_1_X1__MASK                                  0x0000ffff
+#define CP_SET_BIN_1_X1__SHIFT                                 0
+static inline uint32_t CP_SET_BIN_1_X1(uint32_t val)
+{
+       return ((val) << CP_SET_BIN_1_X1__SHIFT) & CP_SET_BIN_1_X1__MASK;
+}
+#define CP_SET_BIN_1_Y1__MASK                                  0xffff0000
+#define CP_SET_BIN_1_Y1__SHIFT                                 16
+static inline uint32_t CP_SET_BIN_1_Y1(uint32_t val)
+{
+       return ((val) << CP_SET_BIN_1_Y1__SHIFT) & CP_SET_BIN_1_Y1__MASK;
+}
+
+#define REG_CP_SET_BIN_2                                       0x00000002
+#define CP_SET_BIN_2_X2__MASK                                  0x0000ffff
+#define CP_SET_BIN_2_X2__SHIFT                                 0
+static inline uint32_t CP_SET_BIN_2_X2(uint32_t val)
+{
+       return ((val) << CP_SET_BIN_2_X2__SHIFT) & CP_SET_BIN_2_X2__MASK;
+}
+#define CP_SET_BIN_2_Y2__MASK                                  0xffff0000
+#define CP_SET_BIN_2_Y2__SHIFT                                 16
+static inline uint32_t CP_SET_BIN_2_Y2(uint32_t val)
+{
+       return ((val) << CP_SET_BIN_2_Y2__SHIFT) & CP_SET_BIN_2_Y2__MASK;
+}
+
+
+#endif /* ADRENO_PM4_XML */
diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h
new file mode 100644 (file)
index 0000000..6f8396b
--- /dev/null
@@ -0,0 +1,502 @@
+#ifndef DSI_XML
+#define DSI_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml                 (    595 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml           (  19332 bytes, from 2013-08-16 22:16:36)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml             (  11712 bytes, from 2013-08-17 17:13:43)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml            (    344 bytes, from 2013-08-11 19:26:32)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml         (   1544 bytes, from 2013-08-16 19:17:05)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml         (    600 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml           (  19288 bytes, from 2013-08-11 18:14:15)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+enum dsi_traffic_mode {
+       NON_BURST_SYNCH_PULSE = 0,
+       NON_BURST_SYNCH_EVENT = 1,
+       BURST_MODE = 2,
+};
+
+enum dsi_dst_format {
+       DST_FORMAT_RGB565 = 0,
+       DST_FORMAT_RGB666 = 1,
+       DST_FORMAT_RGB666_LOOSE = 2,
+       DST_FORMAT_RGB888 = 3,
+};
+
+enum dsi_rgb_swap {
+       SWAP_RGB = 0,
+       SWAP_RBG = 1,
+       SWAP_BGR = 2,
+       SWAP_BRG = 3,
+       SWAP_GRB = 4,
+       SWAP_GBR = 5,
+};
+
+enum dsi_cmd_trigger {
+       TRIGGER_NONE = 0,
+       TRIGGER_TE = 2,
+       TRIGGER_SW = 4,
+       TRIGGER_SW_SEOF = 5,
+       TRIGGER_SW_TE = 6,
+};
+
+#define DSI_IRQ_CMD_DMA_DONE                                   0x00000001
+#define DSI_IRQ_MASK_CMD_DMA_DONE                              0x00000002
+#define DSI_IRQ_CMD_MDP_DONE                                   0x00000100
+#define DSI_IRQ_MASK_CMD_MDP_DONE                              0x00000200
+#define DSI_IRQ_VIDEO_DONE                                     0x00010000
+#define DSI_IRQ_MASK_VIDEO_DONE                                        0x00020000
+#define DSI_IRQ_ERROR                                          0x01000000
+#define DSI_IRQ_MASK_ERROR                                     0x02000000
+#define REG_DSI_CTRL                                           0x00000000
+#define DSI_CTRL_ENABLE                                                0x00000001
+#define DSI_CTRL_VID_MODE_EN                                   0x00000002
+#define DSI_CTRL_CMD_MODE_EN                                   0x00000004
+#define DSI_CTRL_LANE0                                         0x00000010
+#define DSI_CTRL_LANE1                                         0x00000020
+#define DSI_CTRL_LANE2                                         0x00000040
+#define DSI_CTRL_LANE3                                         0x00000080
+#define DSI_CTRL_CLK_EN                                                0x00000100
+#define DSI_CTRL_ECC_CHECK                                     0x00100000
+#define DSI_CTRL_CRC_CHECK                                     0x01000000
+
+#define REG_DSI_STATUS0                                                0x00000004
+#define DSI_STATUS0_CMD_MODE_DMA_BUSY                          0x00000002
+#define DSI_STATUS0_VIDEO_MODE_ENGINE_BUSY                     0x00000008
+#define DSI_STATUS0_DSI_BUSY                                   0x00000010
+
+#define REG_DSI_FIFO_STATUS                                    0x00000008
+
+#define REG_DSI_VID_CFG0                                       0x0000000c
+#define DSI_VID_CFG0_VIRT_CHANNEL__MASK                                0x00000003
+#define DSI_VID_CFG0_VIRT_CHANNEL__SHIFT                       0
+static inline uint32_t DSI_VID_CFG0_VIRT_CHANNEL(uint32_t val)
+{
+       return ((val) << DSI_VID_CFG0_VIRT_CHANNEL__SHIFT) & DSI_VID_CFG0_VIRT_CHANNEL__MASK;
+}
+#define DSI_VID_CFG0_DST_FORMAT__MASK                          0x00000030
+#define DSI_VID_CFG0_DST_FORMAT__SHIFT                         4
+static inline uint32_t DSI_VID_CFG0_DST_FORMAT(enum dsi_dst_format val)
+{
+       return ((val) << DSI_VID_CFG0_DST_FORMAT__SHIFT) & DSI_VID_CFG0_DST_FORMAT__MASK;
+}
+#define DSI_VID_CFG0_TRAFFIC_MODE__MASK                                0x00000300
+#define DSI_VID_CFG0_TRAFFIC_MODE__SHIFT                       8
+static inline uint32_t DSI_VID_CFG0_TRAFFIC_MODE(enum dsi_traffic_mode val)
+{
+       return ((val) << DSI_VID_CFG0_TRAFFIC_MODE__SHIFT) & DSI_VID_CFG0_TRAFFIC_MODE__MASK;
+}
+#define DSI_VID_CFG0_BLLP_POWER_STOP                           0x00001000
+#define DSI_VID_CFG0_EOF_BLLP_POWER_STOP                       0x00008000
+#define DSI_VID_CFG0_HSA_POWER_STOP                            0x00010000
+#define DSI_VID_CFG0_HBP_POWER_STOP                            0x00100000
+#define DSI_VID_CFG0_HFP_POWER_STOP                            0x01000000
+#define DSI_VID_CFG0_PULSE_MODE_HSA_HE                         0x10000000
+
+#define REG_DSI_VID_CFG1                                       0x0000001c
+#define DSI_VID_CFG1_R_SEL                                     0x00000010
+#define DSI_VID_CFG1_G_SEL                                     0x00000100
+#define DSI_VID_CFG1_B_SEL                                     0x00001000
+#define DSI_VID_CFG1_RGB_SWAP__MASK                            0x00070000
+#define DSI_VID_CFG1_RGB_SWAP__SHIFT                           16
+static inline uint32_t DSI_VID_CFG1_RGB_SWAP(enum dsi_rgb_swap val)
+{
+       return ((val) << DSI_VID_CFG1_RGB_SWAP__SHIFT) & DSI_VID_CFG1_RGB_SWAP__MASK;
+}
+#define DSI_VID_CFG1_INTERLEAVE_MAX__MASK                      0x00f00000
+#define DSI_VID_CFG1_INTERLEAVE_MAX__SHIFT                     20
+static inline uint32_t DSI_VID_CFG1_INTERLEAVE_MAX(uint32_t val)
+{
+       return ((val) << DSI_VID_CFG1_INTERLEAVE_MAX__SHIFT) & DSI_VID_CFG1_INTERLEAVE_MAX__MASK;
+}
+
+#define REG_DSI_ACTIVE_H                                       0x00000020
+#define DSI_ACTIVE_H_START__MASK                               0x00000fff
+#define DSI_ACTIVE_H_START__SHIFT                              0
+static inline uint32_t DSI_ACTIVE_H_START(uint32_t val)
+{
+       return ((val) << DSI_ACTIVE_H_START__SHIFT) & DSI_ACTIVE_H_START__MASK;
+}
+#define DSI_ACTIVE_H_END__MASK                                 0x0fff0000
+#define DSI_ACTIVE_H_END__SHIFT                                        16
+static inline uint32_t DSI_ACTIVE_H_END(uint32_t val)
+{
+       return ((val) << DSI_ACTIVE_H_END__SHIFT) & DSI_ACTIVE_H_END__MASK;
+}
+
+#define REG_DSI_ACTIVE_V                                       0x00000024
+#define DSI_ACTIVE_V_START__MASK                               0x00000fff
+#define DSI_ACTIVE_V_START__SHIFT                              0
+static inline uint32_t DSI_ACTIVE_V_START(uint32_t val)
+{
+       return ((val) << DSI_ACTIVE_V_START__SHIFT) & DSI_ACTIVE_V_START__MASK;
+}
+#define DSI_ACTIVE_V_END__MASK                                 0x0fff0000
+#define DSI_ACTIVE_V_END__SHIFT                                        16
+static inline uint32_t DSI_ACTIVE_V_END(uint32_t val)
+{
+       return ((val) << DSI_ACTIVE_V_END__SHIFT) & DSI_ACTIVE_V_END__MASK;
+}
+
+#define REG_DSI_TOTAL                                          0x00000028
+#define DSI_TOTAL_H_TOTAL__MASK                                        0x00000fff
+#define DSI_TOTAL_H_TOTAL__SHIFT                               0
+static inline uint32_t DSI_TOTAL_H_TOTAL(uint32_t val)
+{
+       return ((val) << DSI_TOTAL_H_TOTAL__SHIFT) & DSI_TOTAL_H_TOTAL__MASK;
+}
+#define DSI_TOTAL_V_TOTAL__MASK                                        0x0fff0000
+#define DSI_TOTAL_V_TOTAL__SHIFT                               16
+static inline uint32_t DSI_TOTAL_V_TOTAL(uint32_t val)
+{
+       return ((val) << DSI_TOTAL_V_TOTAL__SHIFT) & DSI_TOTAL_V_TOTAL__MASK;
+}
+
+#define REG_DSI_ACTIVE_HSYNC                                   0x0000002c
+#define DSI_ACTIVE_HSYNC_START__MASK                           0x00000fff
+#define DSI_ACTIVE_HSYNC_START__SHIFT                          0
+static inline uint32_t DSI_ACTIVE_HSYNC_START(uint32_t val)
+{
+       return ((val) << DSI_ACTIVE_HSYNC_START__SHIFT) & DSI_ACTIVE_HSYNC_START__MASK;
+}
+#define DSI_ACTIVE_HSYNC_END__MASK                             0x0fff0000
+#define DSI_ACTIVE_HSYNC_END__SHIFT                            16
+static inline uint32_t DSI_ACTIVE_HSYNC_END(uint32_t val)
+{
+       return ((val) << DSI_ACTIVE_HSYNC_END__SHIFT) & DSI_ACTIVE_HSYNC_END__MASK;
+}
+
+#define REG_DSI_ACTIVE_VSYNC                                   0x00000034
+#define DSI_ACTIVE_VSYNC_START__MASK                           0x00000fff
+#define DSI_ACTIVE_VSYNC_START__SHIFT                          0
+static inline uint32_t DSI_ACTIVE_VSYNC_START(uint32_t val)
+{
+       return ((val) << DSI_ACTIVE_VSYNC_START__SHIFT) & DSI_ACTIVE_VSYNC_START__MASK;
+}
+#define DSI_ACTIVE_VSYNC_END__MASK                             0x0fff0000
+#define DSI_ACTIVE_VSYNC_END__SHIFT                            16
+static inline uint32_t DSI_ACTIVE_VSYNC_END(uint32_t val)
+{
+       return ((val) << DSI_ACTIVE_VSYNC_END__SHIFT) & DSI_ACTIVE_VSYNC_END__MASK;
+}
+
+#define REG_DSI_CMD_DMA_CTRL                                   0x00000038
+#define DSI_CMD_DMA_CTRL_FROM_FRAME_BUFFER                     0x10000000
+#define DSI_CMD_DMA_CTRL_LOW_POWER                             0x04000000
+
+#define REG_DSI_CMD_CFG0                                       0x0000003c
+
+#define REG_DSI_CMD_CFG1                                       0x00000040
+
+#define REG_DSI_DMA_BASE                                       0x00000044
+
+#define REG_DSI_DMA_LEN                                                0x00000048
+
+#define REG_DSI_ACK_ERR_STATUS                                 0x00000064
+
+static inline uint32_t REG_DSI_RDBK(uint32_t i0) { return 0x00000068 + 0x4*i0; }
+
+static inline uint32_t REG_DSI_RDBK_DATA(uint32_t i0) { return 0x00000068 + 0x4*i0; }
+
+#define REG_DSI_TRIG_CTRL                                      0x00000080
+#define DSI_TRIG_CTRL_DMA_TRIGGER__MASK                                0x0000000f
+#define DSI_TRIG_CTRL_DMA_TRIGGER__SHIFT                       0
+static inline uint32_t DSI_TRIG_CTRL_DMA_TRIGGER(enum dsi_cmd_trigger val)
+{
+       return ((val) << DSI_TRIG_CTRL_DMA_TRIGGER__SHIFT) & DSI_TRIG_CTRL_DMA_TRIGGER__MASK;
+}
+#define DSI_TRIG_CTRL_MDP_TRIGGER__MASK                                0x000000f0
+#define DSI_TRIG_CTRL_MDP_TRIGGER__SHIFT                       4
+static inline uint32_t DSI_TRIG_CTRL_MDP_TRIGGER(enum dsi_cmd_trigger val)
+{
+       return ((val) << DSI_TRIG_CTRL_MDP_TRIGGER__SHIFT) & DSI_TRIG_CTRL_MDP_TRIGGER__MASK;
+}
+#define DSI_TRIG_CTRL_STREAM                                   0x00000100
+#define DSI_TRIG_CTRL_TE                                       0x80000000
+
+#define REG_DSI_TRIG_DMA                                       0x0000008c
+
+#define REG_DSI_DLN0_PHY_ERR                                   0x000000b0
+
+#define REG_DSI_TIMEOUT_STATUS                                 0x000000bc
+
+#define REG_DSI_CLKOUT_TIMING_CTRL                             0x000000c0
+#define DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE__MASK                 0x0000003f
+#define DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE__SHIFT                        0
+static inline uint32_t DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE(uint32_t val)
+{
+       return ((val) << DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE__SHIFT) & DSI_CLKOUT_TIMING_CTRL_T_CLK_PRE__MASK;
+}
+#define DSI_CLKOUT_TIMING_CTRL_T_CLK_POST__MASK                        0x00003f00
+#define DSI_CLKOUT_TIMING_CTRL_T_CLK_POST__SHIFT               8
+static inline uint32_t DSI_CLKOUT_TIMING_CTRL_T_CLK_POST(uint32_t val)
+{
+       return ((val) << DSI_CLKOUT_TIMING_CTRL_T_CLK_POST__SHIFT) & DSI_CLKOUT_TIMING_CTRL_T_CLK_POST__MASK;
+}
+
+#define REG_DSI_EOT_PACKET_CTRL                                        0x000000c8
+#define DSI_EOT_PACKET_CTRL_TX_EOT_APPEND                      0x00000001
+#define DSI_EOT_PACKET_CTRL_RX_EOT_IGNORE                      0x00000010
+
+#define REG_DSI_LANE_SWAP_CTRL                                 0x000000ac
+
+#define REG_DSI_ERR_INT_MASK0                                  0x00000108
+
+#define REG_DSI_INTR_CTRL                                      0x0000010c
+
+#define REG_DSI_RESET                                          0x00000114
+
+#define REG_DSI_CLK_CTRL                                       0x00000118
+
+#define REG_DSI_PHY_RESET                                      0x00000128
+
+#define REG_DSI_PHY_PLL_CTRL_0                                 0x00000200
+#define DSI_PHY_PLL_CTRL_0_ENABLE                              0x00000001
+
+#define REG_DSI_PHY_PLL_CTRL_1                                 0x00000204
+
+#define REG_DSI_PHY_PLL_CTRL_2                                 0x00000208
+
+#define REG_DSI_PHY_PLL_CTRL_3                                 0x0000020c
+
+#define REG_DSI_PHY_PLL_CTRL_4                                 0x00000210
+
+#define REG_DSI_PHY_PLL_CTRL_5                                 0x00000214
+
+#define REG_DSI_PHY_PLL_CTRL_6                                 0x00000218
+
+#define REG_DSI_PHY_PLL_CTRL_7                                 0x0000021c
+
+#define REG_DSI_PHY_PLL_CTRL_8                                 0x00000220
+
+#define REG_DSI_PHY_PLL_CTRL_9                                 0x00000224
+
+#define REG_DSI_PHY_PLL_CTRL_10                                        0x00000228
+
+#define REG_DSI_PHY_PLL_CTRL_11                                        0x0000022c
+
+#define REG_DSI_PHY_PLL_CTRL_12                                        0x00000230
+
+#define REG_DSI_PHY_PLL_CTRL_13                                        0x00000234
+
+#define REG_DSI_PHY_PLL_CTRL_14                                        0x00000238
+
+#define REG_DSI_PHY_PLL_CTRL_15                                        0x0000023c
+
+#define REG_DSI_PHY_PLL_CTRL_16                                        0x00000240
+
+#define REG_DSI_PHY_PLL_CTRL_17                                        0x00000244
+
+#define REG_DSI_PHY_PLL_CTRL_18                                        0x00000248
+
+#define REG_DSI_PHY_PLL_CTRL_19                                        0x0000024c
+
+#define REG_DSI_PHY_PLL_CTRL_20                                        0x00000250
+
+#define REG_DSI_PHY_PLL_STATUS                                 0x00000280
+#define DSI_PHY_PLL_STATUS_PLL_BUSY                            0x00000001
+
+#define REG_DSI_8x60_PHY_TPA_CTRL_1                            0x00000258
+
+#define REG_DSI_8x60_PHY_TPA_CTRL_2                            0x0000025c
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_0                         0x00000260
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_1                         0x00000264
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_2                         0x00000268
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_3                         0x0000026c
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_4                         0x00000270
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_5                         0x00000274
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_6                         0x00000278
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_7                         0x0000027c
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_8                         0x00000280
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_9                         0x00000284
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_10                                0x00000288
+
+#define REG_DSI_8x60_PHY_TIMING_CTRL_11                                0x0000028c
+
+#define REG_DSI_8x60_PHY_CTRL_0                                        0x00000290
+
+#define REG_DSI_8x60_PHY_CTRL_1                                        0x00000294
+
+#define REG_DSI_8x60_PHY_CTRL_2                                        0x00000298
+
+#define REG_DSI_8x60_PHY_CTRL_3                                        0x0000029c
+
+#define REG_DSI_8x60_PHY_STRENGTH_0                            0x000002a0
+
+#define REG_DSI_8x60_PHY_STRENGTH_1                            0x000002a4
+
+#define REG_DSI_8x60_PHY_STRENGTH_2                            0x000002a8
+
+#define REG_DSI_8x60_PHY_STRENGTH_3                            0x000002ac
+
+#define REG_DSI_8x60_PHY_REGULATOR_CTRL_0                      0x000002cc
+
+#define REG_DSI_8x60_PHY_REGULATOR_CTRL_1                      0x000002d0
+
+#define REG_DSI_8x60_PHY_REGULATOR_CTRL_2                      0x000002d4
+
+#define REG_DSI_8x60_PHY_REGULATOR_CTRL_3                      0x000002d8
+
+#define REG_DSI_8x60_PHY_REGULATOR_CTRL_4                      0x000002dc
+
+#define REG_DSI_8x60_PHY_CAL_HW_TRIGGER                                0x000000f0
+
+#define REG_DSI_8x60_PHY_CAL_CTRL                              0x000000f4
+
+#define REG_DSI_8x60_PHY_CAL_STATUS                            0x000000fc
+#define DSI_8x60_PHY_CAL_STATUS_CAL_BUSY                       0x10000000
+
+static inline uint32_t REG_DSI_8960_LN(uint32_t i0) { return 0x00000300 + 0x40*i0; }
+
+static inline uint32_t REG_DSI_8960_LN_CFG_0(uint32_t i0) { return 0x00000300 + 0x40*i0; }
+
+static inline uint32_t REG_DSI_8960_LN_CFG_1(uint32_t i0) { return 0x00000304 + 0x40*i0; }
+
+static inline uint32_t REG_DSI_8960_LN_CFG_2(uint32_t i0) { return 0x00000308 + 0x40*i0; }
+
+static inline uint32_t REG_DSI_8960_LN_TEST_DATAPATH(uint32_t i0) { return 0x0000030c + 0x40*i0; }
+
+static inline uint32_t REG_DSI_8960_LN_TEST_STR_0(uint32_t i0) { return 0x00000314 + 0x40*i0; }
+
+static inline uint32_t REG_DSI_8960_LN_TEST_STR_1(uint32_t i0) { return 0x00000318 + 0x40*i0; }
+
+#define REG_DSI_8960_PHY_LNCK_CFG_0                            0x00000400
+
+#define REG_DSI_8960_PHY_LNCK_CFG_1                            0x00000404
+
+#define REG_DSI_8960_PHY_LNCK_CFG_2                            0x00000408
+
+#define REG_DSI_8960_PHY_LNCK_TEST_DATAPATH                    0x0000040c
+
+#define REG_DSI_8960_PHY_LNCK_TEST_STR0                                0x00000414
+
+#define REG_DSI_8960_PHY_LNCK_TEST_STR1                                0x00000418
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_0                         0x00000440
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_1                         0x00000444
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_2                         0x00000448
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_3                         0x0000044c
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_4                         0x00000450
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_5                         0x00000454
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_6                         0x00000458
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_7                         0x0000045c
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_8                         0x00000460
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_9                         0x00000464
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_10                                0x00000468
+
+#define REG_DSI_8960_PHY_TIMING_CTRL_11                                0x0000046c
+
+#define REG_DSI_8960_PHY_CTRL_0                                        0x00000470
+
+#define REG_DSI_8960_PHY_CTRL_1                                        0x00000474
+
+#define REG_DSI_8960_PHY_CTRL_2                                        0x00000478
+
+#define REG_DSI_8960_PHY_CTRL_3                                        0x0000047c
+
+#define REG_DSI_8960_PHY_STRENGTH_0                            0x00000480
+
+#define REG_DSI_8960_PHY_STRENGTH_1                            0x00000484
+
+#define REG_DSI_8960_PHY_STRENGTH_2                            0x00000488
+
+#define REG_DSI_8960_PHY_BIST_CTRL_0                           0x0000048c
+
+#define REG_DSI_8960_PHY_BIST_CTRL_1                           0x00000490
+
+#define REG_DSI_8960_PHY_BIST_CTRL_2                           0x00000494
+
+#define REG_DSI_8960_PHY_BIST_CTRL_3                           0x00000498
+
+#define REG_DSI_8960_PHY_BIST_CTRL_4                           0x0000049c
+
+#define REG_DSI_8960_PHY_LDO_CTRL                              0x000004b0
+
+#define REG_DSI_8960_PHY_REGULATOR_CTRL_0                      0x00000500
+
+#define REG_DSI_8960_PHY_REGULATOR_CTRL_1                      0x00000504
+
+#define REG_DSI_8960_PHY_REGULATOR_CTRL_2                      0x00000508
+
+#define REG_DSI_8960_PHY_REGULATOR_CTRL_3                      0x0000050c
+
+#define REG_DSI_8960_PHY_REGULATOR_CTRL_4                      0x00000510
+
+#define REG_DSI_8960_PHY_REGULATOR_CAL_PWR_CFG                 0x00000518
+
+#define REG_DSI_8960_PHY_CAL_HW_TRIGGER                                0x00000528
+
+#define REG_DSI_8960_PHY_CAL_SW_CFG_0                          0x0000052c
+
+#define REG_DSI_8960_PHY_CAL_SW_CFG_1                          0x00000530
+
+#define REG_DSI_8960_PHY_CAL_SW_CFG_2                          0x00000534
+
+#define REG_DSI_8960_PHY_CAL_HW_CFG_0                          0x00000538
+
+#define REG_DSI_8960_PHY_CAL_HW_CFG_1                          0x0000053c
+
+#define REG_DSI_8960_PHY_CAL_HW_CFG_2                          0x00000540
+
+#define REG_DSI_8960_PHY_CAL_HW_CFG_3                          0x00000544
+
+#define REG_DSI_8960_PHY_CAL_HW_CFG_4                          0x00000548
+
+#define REG_DSI_8960_PHY_CAL_STATUS                            0x00000550
+#define DSI_8960_PHY_CAL_STATUS_CAL_BUSY                       0x00000010
+
+
+#endif /* DSI_XML */
diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h
new file mode 100644 (file)
index 0000000..aefc1b8
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef MMSS_CC_XML
+#define MMSS_CC_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml                 (    595 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml           (  19332 bytes, from 2013-08-16 22:16:36)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml             (  11712 bytes, from 2013-08-17 17:13:43)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml            (    344 bytes, from 2013-08-11 19:26:32)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml         (   1544 bytes, from 2013-08-16 19:17:05)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml         (    600 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml           (  19288 bytes, from 2013-08-11 18:14:15)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+enum mmss_cc_clk {
+       CLK = 0,
+       PCLK = 1,
+};
+
+#define REG_MMSS_CC_AHB                                                0x00000008
+
+static inline uint32_t __offset_CLK(enum mmss_cc_clk idx)
+{
+       switch (idx) {
+               case CLK: return 0x0000004c;
+               case PCLK: return 0x00000130;
+               default: return INVALID_IDX(idx);
+       }
+}
+static inline uint32_t REG_MMSS_CC_CLK(enum mmss_cc_clk i0) { return 0x00000000 + __offset_CLK(i0); }
+
+static inline uint32_t REG_MMSS_CC_CLK_CC(enum mmss_cc_clk i0) { return 0x00000000 + __offset_CLK(i0); }
+#define MMSS_CC_CLK_CC_CLK_EN                                  0x00000001
+#define MMSS_CC_CLK_CC_ROOT_EN                                 0x00000004
+#define MMSS_CC_CLK_CC_MND_EN                                  0x00000020
+#define MMSS_CC_CLK_CC_MND_MODE__MASK                          0x000000c0
+#define MMSS_CC_CLK_CC_MND_MODE__SHIFT                         6
+static inline uint32_t MMSS_CC_CLK_CC_MND_MODE(uint32_t val)
+{
+       return ((val) << MMSS_CC_CLK_CC_MND_MODE__SHIFT) & MMSS_CC_CLK_CC_MND_MODE__MASK;
+}
+#define MMSS_CC_CLK_CC_PMXO_SEL__MASK                          0x00000300
+#define MMSS_CC_CLK_CC_PMXO_SEL__SHIFT                         8
+static inline uint32_t MMSS_CC_CLK_CC_PMXO_SEL(uint32_t val)
+{
+       return ((val) << MMSS_CC_CLK_CC_PMXO_SEL__SHIFT) & MMSS_CC_CLK_CC_PMXO_SEL__MASK;
+}
+
+static inline uint32_t REG_MMSS_CC_CLK_MD(enum mmss_cc_clk i0) { return 0x00000004 + __offset_CLK(i0); }
+#define MMSS_CC_CLK_MD_D__MASK                                 0x000000ff
+#define MMSS_CC_CLK_MD_D__SHIFT                                        0
+static inline uint32_t MMSS_CC_CLK_MD_D(uint32_t val)
+{
+       return ((val) << MMSS_CC_CLK_MD_D__SHIFT) & MMSS_CC_CLK_MD_D__MASK;
+}
+#define MMSS_CC_CLK_MD_M__MASK                                 0x0000ff00
+#define MMSS_CC_CLK_MD_M__SHIFT                                        8
+static inline uint32_t MMSS_CC_CLK_MD_M(uint32_t val)
+{
+       return ((val) << MMSS_CC_CLK_MD_M__SHIFT) & MMSS_CC_CLK_MD_M__MASK;
+}
+
+static inline uint32_t REG_MMSS_CC_CLK_NS(enum mmss_cc_clk i0) { return 0x00000008 + __offset_CLK(i0); }
+#define MMSS_CC_CLK_NS_SRC__MASK                               0x0000000f
+#define MMSS_CC_CLK_NS_SRC__SHIFT                              0
+static inline uint32_t MMSS_CC_CLK_NS_SRC(uint32_t val)
+{
+       return ((val) << MMSS_CC_CLK_NS_SRC__SHIFT) & MMSS_CC_CLK_NS_SRC__MASK;
+}
+#define MMSS_CC_CLK_NS_PRE_DIV_FUNC__MASK                      0x00fff000
+#define MMSS_CC_CLK_NS_PRE_DIV_FUNC__SHIFT                     12
+static inline uint32_t MMSS_CC_CLK_NS_PRE_DIV_FUNC(uint32_t val)
+{
+       return ((val) << MMSS_CC_CLK_NS_PRE_DIV_FUNC__SHIFT) & MMSS_CC_CLK_NS_PRE_DIV_FUNC__MASK;
+}
+#define MMSS_CC_CLK_NS_VAL__MASK                               0xff000000
+#define MMSS_CC_CLK_NS_VAL__SHIFT                              24
+static inline uint32_t MMSS_CC_CLK_NS_VAL(uint32_t val)
+{
+       return ((val) << MMSS_CC_CLK_NS_VAL__SHIFT) & MMSS_CC_CLK_NS_VAL__MASK;
+}
+
+
+#endif /* MMSS_CC_XML */
diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h
new file mode 100644 (file)
index 0000000..a225e81
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef SFPB_XML
+#define SFPB_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml                 (    595 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml           (  19332 bytes, from 2013-08-16 22:16:36)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml             (  11712 bytes, from 2013-08-17 17:13:43)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml            (    344 bytes, from 2013-08-11 19:26:32)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml         (   1544 bytes, from 2013-08-16 19:17:05)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml         (    600 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml           (  19288 bytes, from 2013-08-11 18:14:15)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+#define REG_SFPB_CFG                                           0x00000058
+
+
+#endif /* SFPB_XML */
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c
new file mode 100644 (file)
index 0000000..12ecfb9
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hdmi.h"
+
+static struct platform_device *hdmi_pdev;
+
+void hdmi_set_mode(struct hdmi *hdmi, bool power_on)
+{
+       uint32_t ctrl = 0;
+
+       if (power_on) {
+               ctrl |= HDMI_CTRL_ENABLE;
+               if (!hdmi->hdmi_mode) {
+                       ctrl |= HDMI_CTRL_HDMI;
+                       hdmi_write(hdmi, REG_HDMI_CTRL, ctrl);
+                       ctrl &= ~HDMI_CTRL_HDMI;
+               } else {
+                       ctrl |= HDMI_CTRL_HDMI;
+               }
+       } else {
+               ctrl = HDMI_CTRL_HDMI;
+       }
+
+       hdmi_write(hdmi, REG_HDMI_CTRL, ctrl);
+       DBG("HDMI Core: %s, HDMI_CTRL=0x%08x",
+                       power_on ? "Enable" : "Disable", ctrl);
+}
+
+static irqreturn_t hdmi_irq(int irq, void *dev_id)
+{
+       struct hdmi *hdmi = dev_id;
+
+       /* Process HPD: */
+       hdmi_connector_irq(hdmi->connector);
+
+       /* Process DDC: */
+       hdmi_i2c_irq(hdmi->i2c);
+
+       /* TODO audio.. */
+
+       return IRQ_HANDLED;
+}
+
+void hdmi_destroy(struct hdmi *hdmi)
+{
+       struct hdmi_phy *phy = hdmi->phy;
+
+       if (phy)
+               phy->funcs->destroy(phy);
+
+       if (hdmi->i2c)
+               hdmi_i2c_destroy(hdmi->i2c);
+
+       put_device(&hdmi->pdev->dev);
+}
+
+/* initialize connector */
+int hdmi_init(struct hdmi *hdmi, struct drm_device *dev,
+               struct drm_connector *connector)
+{
+       struct platform_device *pdev = hdmi_pdev;
+       struct hdmi_platform_config *config;
+       int ret;
+
+       if (!pdev) {
+               dev_err(dev->dev, "no hdmi device\n");
+               ret = -ENXIO;
+               goto fail;
+       }
+
+       config = pdev->dev.platform_data;
+
+       get_device(&pdev->dev);
+
+       hdmi->dev = dev;
+       hdmi->pdev = pdev;
+       hdmi->connector = connector;
+
+       /* not sure about which phy maps to which msm.. probably I miss some */
+       if (config->phy_init)
+               hdmi->phy = config->phy_init(hdmi);
+       else
+               hdmi->phy = ERR_PTR(-ENXIO);
+
+       if (IS_ERR(hdmi->phy)) {
+               ret = PTR_ERR(hdmi->phy);
+               dev_err(dev->dev, "failed to load phy: %d\n", ret);
+               hdmi->phy = NULL;
+               goto fail;
+       }
+
+       hdmi->mmio = msm_ioremap(pdev, "hdmi_msm_hdmi_addr", "HDMI");
+       if (IS_ERR(hdmi->mmio)) {
+               ret = PTR_ERR(hdmi->mmio);
+               goto fail;
+       }
+
+       hdmi->mvs = devm_regulator_get(&pdev->dev, "8901_hdmi_mvs");
+       if (IS_ERR(hdmi->mvs))
+               hdmi->mvs = devm_regulator_get(&pdev->dev, "hdmi_mvs");
+       if (IS_ERR(hdmi->mvs)) {
+               ret = PTR_ERR(hdmi->mvs);
+               dev_err(dev->dev, "failed to get mvs regulator: %d\n", ret);
+               goto fail;
+       }
+
+       hdmi->mpp0 = devm_regulator_get(&pdev->dev, "8901_mpp0");
+       if (IS_ERR(hdmi->mpp0))
+               hdmi->mpp0 = NULL;
+
+       hdmi->clk = devm_clk_get(&pdev->dev, "core_clk");
+       if (IS_ERR(hdmi->clk)) {
+               ret = PTR_ERR(hdmi->clk);
+               dev_err(dev->dev, "failed to get 'clk': %d\n", ret);
+               goto fail;
+       }
+
+       hdmi->m_pclk = devm_clk_get(&pdev->dev, "master_iface_clk");
+       if (IS_ERR(hdmi->m_pclk)) {
+               ret = PTR_ERR(hdmi->m_pclk);
+               dev_err(dev->dev, "failed to get 'm_pclk': %d\n", ret);
+               goto fail;
+       }
+
+       hdmi->s_pclk = devm_clk_get(&pdev->dev, "slave_iface_clk");
+       if (IS_ERR(hdmi->s_pclk)) {
+               ret = PTR_ERR(hdmi->s_pclk);
+               dev_err(dev->dev, "failed to get 's_pclk': %d\n", ret);
+               goto fail;
+       }
+
+       hdmi->i2c = hdmi_i2c_init(hdmi);
+       if (IS_ERR(hdmi->i2c)) {
+               ret = PTR_ERR(hdmi->i2c);
+               dev_err(dev->dev, "failed to get i2c: %d\n", ret);
+               hdmi->i2c = NULL;
+               goto fail;
+       }
+
+       hdmi->irq = platform_get_irq(pdev, 0);
+       if (hdmi->irq < 0) {
+               ret = hdmi->irq;
+               dev_err(dev->dev, "failed to get irq: %d\n", ret);
+               goto fail;
+       }
+
+       ret = devm_request_threaded_irq(&pdev->dev, hdmi->irq,
+                       NULL, hdmi_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+                       "hdmi_isr", hdmi);
+       if (ret < 0) {
+               dev_err(dev->dev, "failed to request IRQ%u: %d\n",
+                               hdmi->irq, ret);
+               goto fail;
+       }
+
+       return 0;
+
+fail:
+       if (hdmi)
+               hdmi_destroy(hdmi);
+
+       return ret;
+}
+
+/*
+ * The hdmi device:
+ */
+
+static int hdmi_dev_probe(struct platform_device *pdev)
+{
+       static struct hdmi_platform_config config = {};
+#ifdef CONFIG_OF
+       /* TODO */
+#else
+       if (cpu_is_apq8064()) {
+               config.phy_init      = hdmi_phy_8960_init;
+               config.ddc_clk_gpio  = 70;
+               config.ddc_data_gpio = 71;
+               config.hpd_gpio      = 72;
+               config.pmic_gpio     = 13 + NR_GPIO_IRQS;
+       } else if (cpu_is_msm8960()) {
+               config.phy_init      = hdmi_phy_8960_init;
+               config.ddc_clk_gpio  = 100;
+               config.ddc_data_gpio = 101;
+               config.hpd_gpio      = 102;
+               config.pmic_gpio     = -1;
+       } else if (cpu_is_msm8x60()) {
+               config.phy_init      = hdmi_phy_8x60_init;
+               config.ddc_clk_gpio  = 170;
+               config.ddc_data_gpio = 171;
+               config.hpd_gpio      = 172;
+               config.pmic_gpio     = -1;
+       }
+#endif
+       pdev->dev.platform_data = &config;
+       hdmi_pdev = pdev;
+       return 0;
+}
+
+static int hdmi_dev_remove(struct platform_device *pdev)
+{
+       hdmi_pdev = NULL;
+       return 0;
+}
+
+static struct platform_driver hdmi_driver = {
+       .probe = hdmi_dev_probe,
+       .remove = hdmi_dev_remove,
+       .driver.name = "hdmi_msm",
+};
+
+void __init hdmi_register(void)
+{
+       platform_driver_register(&hdmi_driver);
+}
+
+void __exit hdmi_unregister(void)
+{
+       platform_driver_unregister(&hdmi_driver);
+}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h
new file mode 100644 (file)
index 0000000..34703fe
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __HDMI_CONNECTOR_H__
+#define __HDMI_CONNECTOR_H__
+
+#include <linux/i2c.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include "msm_drv.h"
+#include "hdmi.xml.h"
+
+
+struct hdmi_phy;
+
+struct hdmi {
+       struct drm_device *dev;
+       struct platform_device *pdev;
+
+       void __iomem *mmio;
+
+       struct regulator *mvs;        /* HDMI_5V */
+       struct regulator *mpp0;       /* External 5V */
+
+       struct clk *clk;
+       struct clk *m_pclk;
+       struct clk *s_pclk;
+
+       struct hdmi_phy *phy;
+       struct i2c_adapter *i2c;
+       struct drm_connector *connector;
+
+       bool hdmi_mode;               /* are we in hdmi mode? */
+
+       int irq;
+};
+
+/* platform config data (ie. from DT, or pdata) */
+struct hdmi_platform_config {
+       struct hdmi_phy *(*phy_init)(struct hdmi *hdmi);
+       int ddc_clk_gpio, ddc_data_gpio, hpd_gpio, pmic_gpio;
+};
+
+void hdmi_set_mode(struct hdmi *hdmi, bool power_on);
+void hdmi_destroy(struct hdmi *hdmi);
+int hdmi_init(struct hdmi *hdmi, struct drm_device *dev,
+               struct drm_connector *connector);
+
+static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
+{
+       msm_writel(data, hdmi->mmio + reg);
+}
+
+static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg)
+{
+       return msm_readl(hdmi->mmio + reg);
+}
+
+/*
+ * The phy appears to be different, for example between 8960 and 8x60,
+ * so split the phy related functions out and load the correct one at
+ * runtime:
+ */
+
+struct hdmi_phy_funcs {
+       void (*destroy)(struct hdmi_phy *phy);
+       void (*reset)(struct hdmi_phy *phy);
+       void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock);
+       void (*powerdown)(struct hdmi_phy *phy);
+};
+
+struct hdmi_phy {
+       const struct hdmi_phy_funcs *funcs;
+};
+
+/*
+ * phy can be different on different generations:
+ */
+struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi);
+struct hdmi_phy *hdmi_phy_8x60_init(struct hdmi *hdmi);
+
+/*
+ * hdmi connector:
+ */
+
+void hdmi_connector_irq(struct drm_connector *connector);
+
+/*
+ * i2c adapter for ddc:
+ */
+
+void hdmi_i2c_irq(struct i2c_adapter *i2c);
+void hdmi_i2c_destroy(struct i2c_adapter *i2c);
+struct i2c_adapter *hdmi_i2c_init(struct hdmi *hdmi);
+
+#endif /* __HDMI_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h
new file mode 100644 (file)
index 0000000..f5fa486
--- /dev/null
@@ -0,0 +1,508 @@
+#ifndef HDMI_XML
+#define HDMI_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml                 (    595 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml           (  19332 bytes, from 2013-08-16 22:16:36)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml             (  11712 bytes, from 2013-08-17 17:13:43)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml            (    344 bytes, from 2013-08-11 19:26:32)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml         (   1544 bytes, from 2013-08-16 19:17:05)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml         (    600 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml           (  19288 bytes, from 2013-08-11 18:14:15)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+enum hdmi_hdcp_key_state {
+       NO_KEYS = 0,
+       NOT_CHECKED = 1,
+       CHECKING = 2,
+       KEYS_VALID = 3,
+       AKSV_INVALID = 4,
+       CHECKSUM_MISMATCH = 5,
+};
+
+enum hdmi_ddc_read_write {
+       DDC_WRITE = 0,
+       DDC_READ = 1,
+};
+
+enum hdmi_acr_cts {
+       ACR_NONE = 0,
+       ACR_32 = 1,
+       ACR_44 = 2,
+       ACR_48 = 3,
+};
+
+#define REG_HDMI_CTRL                                          0x00000000
+#define HDMI_CTRL_ENABLE                                       0x00000001
+#define HDMI_CTRL_HDMI                                         0x00000002
+#define HDMI_CTRL_ENCRYPTED                                    0x00000004
+
+#define REG_HDMI_AUDIO_PKT_CTRL1                               0x00000020
+#define HDMI_AUDIO_PKT_CTRL1_AUDIO_SAMPLE_SEND                 0x00000001
+
+#define REG_HDMI_ACR_PKT_CTRL                                  0x00000024
+#define HDMI_ACR_PKT_CTRL_CONT                                 0x00000001
+#define HDMI_ACR_PKT_CTRL_SEND                                 0x00000002
+#define HDMI_ACR_PKT_CTRL_SELECT__MASK                         0x00000030
+#define HDMI_ACR_PKT_CTRL_SELECT__SHIFT                                4
+static inline uint32_t HDMI_ACR_PKT_CTRL_SELECT(enum hdmi_acr_cts val)
+{
+       return ((val) << HDMI_ACR_PKT_CTRL_SELECT__SHIFT) & HDMI_ACR_PKT_CTRL_SELECT__MASK;
+}
+#define HDMI_ACR_PKT_CTRL_SOURCE                               0x00000100
+#define HDMI_ACR_PKT_CTRL_N_MULTIPLIER__MASK                   0x00070000
+#define HDMI_ACR_PKT_CTRL_N_MULTIPLIER__SHIFT                  16
+static inline uint32_t HDMI_ACR_PKT_CTRL_N_MULTIPLIER(uint32_t val)
+{
+       return ((val) << HDMI_ACR_PKT_CTRL_N_MULTIPLIER__SHIFT) & HDMI_ACR_PKT_CTRL_N_MULTIPLIER__MASK;
+}
+#define HDMI_ACR_PKT_CTRL_AUDIO_PRIORITY                       0x80000000
+
+#define REG_HDMI_VBI_PKT_CTRL                                  0x00000028
+#define HDMI_VBI_PKT_CTRL_GC_ENABLE                            0x00000010
+#define HDMI_VBI_PKT_CTRL_GC_EVERY_FRAME                       0x00000020
+#define HDMI_VBI_PKT_CTRL_ISRC_SEND                            0x00000100
+#define HDMI_VBI_PKT_CTRL_ISRC_CONTINUOUS                      0x00000200
+#define HDMI_VBI_PKT_CTRL_ACP_SEND                             0x00001000
+#define HDMI_VBI_PKT_CTRL_ACP_SRC_SW                           0x00002000
+
+#define REG_HDMI_INFOFRAME_CTRL0                               0x0000002c
+#define HDMI_INFOFRAME_CTRL0_AVI_SEND                          0x00000001
+#define HDMI_INFOFRAME_CTRL0_AVI_CONT                          0x00000002
+#define HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SEND                   0x00000010
+#define HDMI_INFOFRAME_CTRL0_AUDIO_INFO_CONT                   0x00000020
+#define HDMI_INFOFRAME_CTRL0_AUDIO_INFO_SOURCE                 0x00000040
+#define HDMI_INFOFRAME_CTRL0_AUDIO_INFO_UPDATE                 0x00000080
+
+#define REG_HDMI_GEN_PKT_CTRL                                  0x00000034
+#define HDMI_GEN_PKT_CTRL_GENERIC0_SEND                                0x00000001
+#define HDMI_GEN_PKT_CTRL_GENERIC0_CONT                                0x00000002
+#define HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE__MASK                        0x0000000c
+#define HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE__SHIFT               2
+static inline uint32_t HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE(uint32_t val)
+{
+       return ((val) << HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE__SHIFT) & HDMI_GEN_PKT_CTRL_GENERIC0_UPDATE__MASK;
+}
+#define HDMI_GEN_PKT_CTRL_GENERIC1_SEND                                0x00000010
+#define HDMI_GEN_PKT_CTRL_GENERIC1_CONT                                0x00000020
+#define HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK                  0x003f0000
+#define HDMI_GEN_PKT_CTRL_GENERIC0_LINE__SHIFT                 16
+static inline uint32_t HDMI_GEN_PKT_CTRL_GENERIC0_LINE(uint32_t val)
+{
+       return ((val) << HDMI_GEN_PKT_CTRL_GENERIC0_LINE__SHIFT) & HDMI_GEN_PKT_CTRL_GENERIC0_LINE__MASK;
+}
+#define HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK                  0x3f000000
+#define HDMI_GEN_PKT_CTRL_GENERIC1_LINE__SHIFT                 24
+static inline uint32_t HDMI_GEN_PKT_CTRL_GENERIC1_LINE(uint32_t val)
+{
+       return ((val) << HDMI_GEN_PKT_CTRL_GENERIC1_LINE__SHIFT) & HDMI_GEN_PKT_CTRL_GENERIC1_LINE__MASK;
+}
+
+#define REG_HDMI_GC                                            0x00000040
+#define HDMI_GC_MUTE                                           0x00000001
+
+#define REG_HDMI_AUDIO_PKT_CTRL2                               0x00000044
+#define HDMI_AUDIO_PKT_CTRL2_OVERRIDE                          0x00000001
+#define HDMI_AUDIO_PKT_CTRL2_LAYOUT                            0x00000002
+
+static inline uint32_t REG_HDMI_AVI_INFO(uint32_t i0) { return 0x0000006c + 0x4*i0; }
+
+#define REG_HDMI_GENERIC0_HDR                                  0x00000084
+
+static inline uint32_t REG_HDMI_GENERIC0(uint32_t i0) { return 0x00000088 + 0x4*i0; }
+
+#define REG_HDMI_GENERIC1_HDR                                  0x000000a4
+
+static inline uint32_t REG_HDMI_GENERIC1(uint32_t i0) { return 0x000000a8 + 0x4*i0; }
+
+static inline uint32_t REG_HDMI_ACR(uint32_t i0) { return 0x000000c4 + 0x8*i0; }
+
+static inline uint32_t REG_HDMI_ACR_0(uint32_t i0) { return 0x000000c4 + 0x8*i0; }
+#define HDMI_ACR_0_CTS__MASK                                   0xfffff000
+#define HDMI_ACR_0_CTS__SHIFT                                  12
+static inline uint32_t HDMI_ACR_0_CTS(uint32_t val)
+{
+       return ((val) << HDMI_ACR_0_CTS__SHIFT) & HDMI_ACR_0_CTS__MASK;
+}
+
+static inline uint32_t REG_HDMI_ACR_1(uint32_t i0) { return 0x000000c8 + 0x8*i0; }
+#define HDMI_ACR_1_N__MASK                                     0xffffffff
+#define HDMI_ACR_1_N__SHIFT                                    0
+static inline uint32_t HDMI_ACR_1_N(uint32_t val)
+{
+       return ((val) << HDMI_ACR_1_N__SHIFT) & HDMI_ACR_1_N__MASK;
+}
+
+#define REG_HDMI_AUDIO_INFO0                                   0x000000e4
+#define HDMI_AUDIO_INFO0_CHECKSUM__MASK                                0x000000ff
+#define HDMI_AUDIO_INFO0_CHECKSUM__SHIFT                       0
+static inline uint32_t HDMI_AUDIO_INFO0_CHECKSUM(uint32_t val)
+{
+       return ((val) << HDMI_AUDIO_INFO0_CHECKSUM__SHIFT) & HDMI_AUDIO_INFO0_CHECKSUM__MASK;
+}
+#define HDMI_AUDIO_INFO0_CC__MASK                              0x00000700
+#define HDMI_AUDIO_INFO0_CC__SHIFT                             8
+static inline uint32_t HDMI_AUDIO_INFO0_CC(uint32_t val)
+{
+       return ((val) << HDMI_AUDIO_INFO0_CC__SHIFT) & HDMI_AUDIO_INFO0_CC__MASK;
+}
+
+#define REG_HDMI_AUDIO_INFO1                                   0x000000e8
+#define HDMI_AUDIO_INFO1_CA__MASK                              0x000000ff
+#define HDMI_AUDIO_INFO1_CA__SHIFT                             0
+static inline uint32_t HDMI_AUDIO_INFO1_CA(uint32_t val)
+{
+       return ((val) << HDMI_AUDIO_INFO1_CA__SHIFT) & HDMI_AUDIO_INFO1_CA__MASK;
+}
+#define HDMI_AUDIO_INFO1_LSV__MASK                             0x00007800
+#define HDMI_AUDIO_INFO1_LSV__SHIFT                            11
+static inline uint32_t HDMI_AUDIO_INFO1_LSV(uint32_t val)
+{
+       return ((val) << HDMI_AUDIO_INFO1_LSV__SHIFT) & HDMI_AUDIO_INFO1_LSV__MASK;
+}
+#define HDMI_AUDIO_INFO1_DM_INH                                        0x00008000
+
+#define REG_HDMI_HDCP_CTRL                                     0x00000110
+#define HDMI_HDCP_CTRL_ENABLE                                  0x00000001
+#define HDMI_HDCP_CTRL_ENCRYPTION_ENABLE                       0x00000100
+
+#define REG_HDMI_HDCP_INT_CTRL                                 0x00000118
+
+#define REG_HDMI_HDCP_LINK0_STATUS                             0x0000011c
+#define HDMI_HDCP_LINK0_STATUS_AN_0_READY                      0x00000100
+#define HDMI_HDCP_LINK0_STATUS_AN_1_READY                      0x00000200
+#define HDMI_HDCP_LINK0_STATUS_KEY_STATE__MASK                 0x70000000
+#define HDMI_HDCP_LINK0_STATUS_KEY_STATE__SHIFT                        28
+static inline uint32_t HDMI_HDCP_LINK0_STATUS_KEY_STATE(enum hdmi_hdcp_key_state val)
+{
+       return ((val) << HDMI_HDCP_LINK0_STATUS_KEY_STATE__SHIFT) & HDMI_HDCP_LINK0_STATUS_KEY_STATE__MASK;
+}
+
+#define REG_HDMI_HDCP_RESET                                    0x00000130
+#define HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE                   0x00000001
+
+#define REG_HDMI_AUDIO_CFG                                     0x000001d0
+#define HDMI_AUDIO_CFG_ENGINE_ENABLE                           0x00000001
+#define HDMI_AUDIO_CFG_FIFO_WATERMARK__MASK                    0x000000f0
+#define HDMI_AUDIO_CFG_FIFO_WATERMARK__SHIFT                   4
+static inline uint32_t HDMI_AUDIO_CFG_FIFO_WATERMARK(uint32_t val)
+{
+       return ((val) << HDMI_AUDIO_CFG_FIFO_WATERMARK__SHIFT) & HDMI_AUDIO_CFG_FIFO_WATERMARK__MASK;
+}
+
+#define REG_HDMI_USEC_REFTIMER                                 0x00000208
+
+#define REG_HDMI_DDC_CTRL                                      0x0000020c
+#define HDMI_DDC_CTRL_GO                                       0x00000001
+#define HDMI_DDC_CTRL_SOFT_RESET                               0x00000002
+#define HDMI_DDC_CTRL_SEND_RESET                               0x00000004
+#define HDMI_DDC_CTRL_SW_STATUS_RESET                          0x00000008
+#define HDMI_DDC_CTRL_TRANSACTION_CNT__MASK                    0x00300000
+#define HDMI_DDC_CTRL_TRANSACTION_CNT__SHIFT                   20
+static inline uint32_t HDMI_DDC_CTRL_TRANSACTION_CNT(uint32_t val)
+{
+       return ((val) << HDMI_DDC_CTRL_TRANSACTION_CNT__SHIFT) & HDMI_DDC_CTRL_TRANSACTION_CNT__MASK;
+}
+
+#define REG_HDMI_DDC_INT_CTRL                                  0x00000214
+#define HDMI_DDC_INT_CTRL_SW_DONE_INT                          0x00000001
+#define HDMI_DDC_INT_CTRL_SW_DONE_ACK                          0x00000002
+#define HDMI_DDC_INT_CTRL_SW_DONE_MASK                         0x00000004
+
+#define REG_HDMI_DDC_SW_STATUS                                 0x00000218
+#define HDMI_DDC_SW_STATUS_NACK0                               0x00001000
+#define HDMI_DDC_SW_STATUS_NACK1                               0x00002000
+#define HDMI_DDC_SW_STATUS_NACK2                               0x00004000
+#define HDMI_DDC_SW_STATUS_NACK3                               0x00008000
+
+#define REG_HDMI_DDC_HW_STATUS                                 0x0000021c
+
+#define REG_HDMI_DDC_SPEED                                     0x00000220
+#define HDMI_DDC_SPEED_THRESHOLD__MASK                         0x00000003
+#define HDMI_DDC_SPEED_THRESHOLD__SHIFT                                0
+static inline uint32_t HDMI_DDC_SPEED_THRESHOLD(uint32_t val)
+{
+       return ((val) << HDMI_DDC_SPEED_THRESHOLD__SHIFT) & HDMI_DDC_SPEED_THRESHOLD__MASK;
+}
+#define HDMI_DDC_SPEED_PRESCALE__MASK                          0xffff0000
+#define HDMI_DDC_SPEED_PRESCALE__SHIFT                         16
+static inline uint32_t HDMI_DDC_SPEED_PRESCALE(uint32_t val)
+{
+       return ((val) << HDMI_DDC_SPEED_PRESCALE__SHIFT) & HDMI_DDC_SPEED_PRESCALE__MASK;
+}
+
+#define REG_HDMI_DDC_SETUP                                     0x00000224
+#define HDMI_DDC_SETUP_TIMEOUT__MASK                           0xff000000
+#define HDMI_DDC_SETUP_TIMEOUT__SHIFT                          24
+static inline uint32_t HDMI_DDC_SETUP_TIMEOUT(uint32_t val)
+{
+       return ((val) << HDMI_DDC_SETUP_TIMEOUT__SHIFT) & HDMI_DDC_SETUP_TIMEOUT__MASK;
+}
+
+static inline uint32_t REG_HDMI_I2C_TRANSACTION(uint32_t i0) { return 0x00000228 + 0x4*i0; }
+
+static inline uint32_t REG_HDMI_I2C_TRANSACTION_REG(uint32_t i0) { return 0x00000228 + 0x4*i0; }
+#define HDMI_I2C_TRANSACTION_REG_RW__MASK                      0x00000001
+#define HDMI_I2C_TRANSACTION_REG_RW__SHIFT                     0
+static inline uint32_t HDMI_I2C_TRANSACTION_REG_RW(enum hdmi_ddc_read_write val)
+{
+       return ((val) << HDMI_I2C_TRANSACTION_REG_RW__SHIFT) & HDMI_I2C_TRANSACTION_REG_RW__MASK;
+}
+#define HDMI_I2C_TRANSACTION_REG_STOP_ON_NACK                  0x00000100
+#define HDMI_I2C_TRANSACTION_REG_START                         0x00001000
+#define HDMI_I2C_TRANSACTION_REG_STOP                          0x00002000
+#define HDMI_I2C_TRANSACTION_REG_CNT__MASK                     0x00ff0000
+#define HDMI_I2C_TRANSACTION_REG_CNT__SHIFT                    16
+static inline uint32_t HDMI_I2C_TRANSACTION_REG_CNT(uint32_t val)
+{
+       return ((val) << HDMI_I2C_TRANSACTION_REG_CNT__SHIFT) & HDMI_I2C_TRANSACTION_REG_CNT__MASK;
+}
+
+#define REG_HDMI_DDC_DATA                                      0x00000238
+#define HDMI_DDC_DATA_DATA_RW__MASK                            0x00000001
+#define HDMI_DDC_DATA_DATA_RW__SHIFT                           0
+static inline uint32_t HDMI_DDC_DATA_DATA_RW(enum hdmi_ddc_read_write val)
+{
+       return ((val) << HDMI_DDC_DATA_DATA_RW__SHIFT) & HDMI_DDC_DATA_DATA_RW__MASK;
+}
+#define HDMI_DDC_DATA_DATA__MASK                               0x0000ff00
+#define HDMI_DDC_DATA_DATA__SHIFT                              8
+static inline uint32_t HDMI_DDC_DATA_DATA(uint32_t val)
+{
+       return ((val) << HDMI_DDC_DATA_DATA__SHIFT) & HDMI_DDC_DATA_DATA__MASK;
+}
+#define HDMI_DDC_DATA_INDEX__MASK                              0x00ff0000
+#define HDMI_DDC_DATA_INDEX__SHIFT                             16
+static inline uint32_t HDMI_DDC_DATA_INDEX(uint32_t val)
+{
+       return ((val) << HDMI_DDC_DATA_INDEX__SHIFT) & HDMI_DDC_DATA_INDEX__MASK;
+}
+#define HDMI_DDC_DATA_INDEX_WRITE                              0x80000000
+
+#define REG_HDMI_HPD_INT_STATUS                                        0x00000250
+#define HDMI_HPD_INT_STATUS_INT                                        0x00000001
+#define HDMI_HPD_INT_STATUS_CABLE_DETECTED                     0x00000002
+
+#define REG_HDMI_HPD_INT_CTRL                                  0x00000254
+#define HDMI_HPD_INT_CTRL_INT_ACK                              0x00000001
+#define HDMI_HPD_INT_CTRL_INT_CONNECT                          0x00000002
+#define HDMI_HPD_INT_CTRL_INT_EN                               0x00000004
+#define HDMI_HPD_INT_CTRL_RX_INT_ACK                           0x00000010
+#define HDMI_HPD_INT_CTRL_RX_INT_EN                            0x00000020
+#define HDMI_HPD_INT_CTRL_RCV_PLUGIN_DET_MASK                  0x00000200
+
+#define REG_HDMI_HPD_CTRL                                      0x00000258
+#define HDMI_HPD_CTRL_TIMEOUT__MASK                            0x00001fff
+#define HDMI_HPD_CTRL_TIMEOUT__SHIFT                           0
+static inline uint32_t HDMI_HPD_CTRL_TIMEOUT(uint32_t val)
+{
+       return ((val) << HDMI_HPD_CTRL_TIMEOUT__SHIFT) & HDMI_HPD_CTRL_TIMEOUT__MASK;
+}
+#define HDMI_HPD_CTRL_ENABLE                                   0x10000000
+
+#define REG_HDMI_DDC_REF                                       0x0000027c
+#define HDMI_DDC_REF_REFTIMER_ENABLE                           0x00010000
+#define HDMI_DDC_REF_REFTIMER__MASK                            0x0000ffff
+#define HDMI_DDC_REF_REFTIMER__SHIFT                           0
+static inline uint32_t HDMI_DDC_REF_REFTIMER(uint32_t val)
+{
+       return ((val) << HDMI_DDC_REF_REFTIMER__SHIFT) & HDMI_DDC_REF_REFTIMER__MASK;
+}
+
+#define REG_HDMI_ACTIVE_HSYNC                                  0x000002b4
+#define HDMI_ACTIVE_HSYNC_START__MASK                          0x00000fff
+#define HDMI_ACTIVE_HSYNC_START__SHIFT                         0
+static inline uint32_t HDMI_ACTIVE_HSYNC_START(uint32_t val)
+{
+       return ((val) << HDMI_ACTIVE_HSYNC_START__SHIFT) & HDMI_ACTIVE_HSYNC_START__MASK;
+}
+#define HDMI_ACTIVE_HSYNC_END__MASK                            0x0fff0000
+#define HDMI_ACTIVE_HSYNC_END__SHIFT                           16
+static inline uint32_t HDMI_ACTIVE_HSYNC_END(uint32_t val)
+{
+       return ((val) << HDMI_ACTIVE_HSYNC_END__SHIFT) & HDMI_ACTIVE_HSYNC_END__MASK;
+}
+
+#define REG_HDMI_ACTIVE_VSYNC                                  0x000002b8
+#define HDMI_ACTIVE_VSYNC_START__MASK                          0x00000fff
+#define HDMI_ACTIVE_VSYNC_START__SHIFT                         0
+static inline uint32_t HDMI_ACTIVE_VSYNC_START(uint32_t val)
+{
+       return ((val) << HDMI_ACTIVE_VSYNC_START__SHIFT) & HDMI_ACTIVE_VSYNC_START__MASK;
+}
+#define HDMI_ACTIVE_VSYNC_END__MASK                            0x0fff0000
+#define HDMI_ACTIVE_VSYNC_END__SHIFT                           16
+static inline uint32_t HDMI_ACTIVE_VSYNC_END(uint32_t val)
+{
+       return ((val) << HDMI_ACTIVE_VSYNC_END__SHIFT) & HDMI_ACTIVE_VSYNC_END__MASK;
+}
+
+#define REG_HDMI_VSYNC_ACTIVE_F2                               0x000002bc
+#define HDMI_VSYNC_ACTIVE_F2_START__MASK                       0x00000fff
+#define HDMI_VSYNC_ACTIVE_F2_START__SHIFT                      0
+static inline uint32_t HDMI_VSYNC_ACTIVE_F2_START(uint32_t val)
+{
+       return ((val) << HDMI_VSYNC_ACTIVE_F2_START__SHIFT) & HDMI_VSYNC_ACTIVE_F2_START__MASK;
+}
+#define HDMI_VSYNC_ACTIVE_F2_END__MASK                         0x0fff0000
+#define HDMI_VSYNC_ACTIVE_F2_END__SHIFT                                16
+static inline uint32_t HDMI_VSYNC_ACTIVE_F2_END(uint32_t val)
+{
+       return ((val) << HDMI_VSYNC_ACTIVE_F2_END__SHIFT) & HDMI_VSYNC_ACTIVE_F2_END__MASK;
+}
+
+#define REG_HDMI_TOTAL                                         0x000002c0
+#define HDMI_TOTAL_H_TOTAL__MASK                               0x00000fff
+#define HDMI_TOTAL_H_TOTAL__SHIFT                              0
+static inline uint32_t HDMI_TOTAL_H_TOTAL(uint32_t val)
+{
+       return ((val) << HDMI_TOTAL_H_TOTAL__SHIFT) & HDMI_TOTAL_H_TOTAL__MASK;
+}
+#define HDMI_TOTAL_V_TOTAL__MASK                               0x0fff0000
+#define HDMI_TOTAL_V_TOTAL__SHIFT                              16
+static inline uint32_t HDMI_TOTAL_V_TOTAL(uint32_t val)
+{
+       return ((val) << HDMI_TOTAL_V_TOTAL__SHIFT) & HDMI_TOTAL_V_TOTAL__MASK;
+}
+
+#define REG_HDMI_VSYNC_TOTAL_F2                                        0x000002c4
+#define HDMI_VSYNC_TOTAL_F2_V_TOTAL__MASK                      0x00000fff
+#define HDMI_VSYNC_TOTAL_F2_V_TOTAL__SHIFT                     0
+static inline uint32_t HDMI_VSYNC_TOTAL_F2_V_TOTAL(uint32_t val)
+{
+       return ((val) << HDMI_VSYNC_TOTAL_F2_V_TOTAL__SHIFT) & HDMI_VSYNC_TOTAL_F2_V_TOTAL__MASK;
+}
+
+#define REG_HDMI_FRAME_CTRL                                    0x000002c8
+#define HDMI_FRAME_CTRL_RGB_MUX_SEL_BGR                                0x00001000
+#define HDMI_FRAME_CTRL_VSYNC_LOW                              0x10000000
+#define HDMI_FRAME_CTRL_HSYNC_LOW                              0x20000000
+#define HDMI_FRAME_CTRL_INTERLACED_EN                          0x80000000
+
+#define REG_HDMI_PHY_CTRL                                      0x000002d4
+#define HDMI_PHY_CTRL_SW_RESET_PLL                             0x00000001
+#define HDMI_PHY_CTRL_SW_RESET_PLL_LOW                         0x00000002
+#define HDMI_PHY_CTRL_SW_RESET                                 0x00000004
+#define HDMI_PHY_CTRL_SW_RESET_LOW                             0x00000008
+
+#define REG_HDMI_AUD_INT                                       0x000002cc
+#define HDMI_AUD_INT_AUD_FIFO_URUN_INT                         0x00000001
+#define HDMI_AUD_INT_AUD_FIFO_URAN_MASK                                0x00000002
+#define HDMI_AUD_INT_AUD_SAM_DROP_INT                          0x00000004
+#define HDMI_AUD_INT_AUD_SAM_DROP_MASK                         0x00000008
+
+#define REG_HDMI_8x60_PHY_REG0                                 0x00000300
+#define HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__MASK                        0x0000001c
+#define HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__SHIFT               2
+static inline uint32_t HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(uint32_t val)
+{
+       return ((val) << HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__SHIFT) & HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__MASK;
+}
+
+#define REG_HDMI_8x60_PHY_REG1                                 0x00000304
+#define HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK                 0x000000f0
+#define HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__SHIFT                        4
+static inline uint32_t HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(uint32_t val)
+{
+       return ((val) << HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__SHIFT) & HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK;
+}
+#define HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK             0x0000000f
+#define HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__SHIFT            0
+static inline uint32_t HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(uint32_t val)
+{
+       return ((val) << HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__SHIFT) & HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK;
+}
+
+#define REG_HDMI_8x60_PHY_REG2                                 0x00000308
+#define HDMI_8x60_PHY_REG2_PD_DESER                            0x00000001
+#define HDMI_8x60_PHY_REG2_PD_DRIVE_1                          0x00000002
+#define HDMI_8x60_PHY_REG2_PD_DRIVE_2                          0x00000004
+#define HDMI_8x60_PHY_REG2_PD_DRIVE_3                          0x00000008
+#define HDMI_8x60_PHY_REG2_PD_DRIVE_4                          0x00000010
+#define HDMI_8x60_PHY_REG2_PD_PLL                              0x00000020
+#define HDMI_8x60_PHY_REG2_PD_PWRGEN                           0x00000040
+#define HDMI_8x60_PHY_REG2_RCV_SENSE_EN                                0x00000080
+
+#define REG_HDMI_8x60_PHY_REG3                                 0x0000030c
+#define HDMI_8x60_PHY_REG3_PLL_ENABLE                          0x00000001
+
+#define REG_HDMI_8x60_PHY_REG4                                 0x00000310
+
+#define REG_HDMI_8x60_PHY_REG5                                 0x00000314
+
+#define REG_HDMI_8x60_PHY_REG6                                 0x00000318
+
+#define REG_HDMI_8x60_PHY_REG7                                 0x0000031c
+
+#define REG_HDMI_8x60_PHY_REG8                                 0x00000320
+
+#define REG_HDMI_8x60_PHY_REG9                                 0x00000324
+
+#define REG_HDMI_8x60_PHY_REG10                                        0x00000328
+
+#define REG_HDMI_8x60_PHY_REG11                                        0x0000032c
+
+#define REG_HDMI_8x60_PHY_REG12                                        0x00000330
+#define HDMI_8x60_PHY_REG12_RETIMING_EN                                0x00000001
+#define HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN                 0x00000002
+#define HDMI_8x60_PHY_REG12_FORCE_LOCK                         0x00000010
+
+#define REG_HDMI_8960_PHY_REG0                                 0x00000400
+
+#define REG_HDMI_8960_PHY_REG1                                 0x00000404
+
+#define REG_HDMI_8960_PHY_REG2                                 0x00000408
+
+#define REG_HDMI_8960_PHY_REG3                                 0x0000040c
+
+#define REG_HDMI_8960_PHY_REG4                                 0x00000410
+
+#define REG_HDMI_8960_PHY_REG5                                 0x00000414
+
+#define REG_HDMI_8960_PHY_REG6                                 0x00000418
+
+#define REG_HDMI_8960_PHY_REG7                                 0x0000041c
+
+#define REG_HDMI_8960_PHY_REG8                                 0x00000420
+
+#define REG_HDMI_8960_PHY_REG9                                 0x00000424
+
+#define REG_HDMI_8960_PHY_REG10                                        0x00000428
+
+#define REG_HDMI_8960_PHY_REG11                                        0x0000042c
+
+#define REG_HDMI_8960_PHY_REG12                                        0x00000430
+
+
+#endif /* HDMI_XML */
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c
new file mode 100644 (file)
index 0000000..7d63f5f
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/gpio.h>
+
+#include "msm_connector.h"
+#include "hdmi.h"
+
+struct hdmi_connector {
+       struct msm_connector base;
+       struct hdmi hdmi;
+       unsigned long int pixclock;
+       bool enabled;
+};
+#define to_hdmi_connector(x) container_of(x, struct hdmi_connector, base)
+
+static int gpio_config(struct hdmi *hdmi, bool on)
+{
+       struct drm_device *dev = hdmi->dev;
+       struct hdmi_platform_config *config =
+                       hdmi->pdev->dev.platform_data;
+       int ret;
+
+       if (on) {
+               ret = gpio_request(config->ddc_clk_gpio, "HDMI_DDC_CLK");
+               if (ret) {
+                       dev_err(dev->dev, "'%s'(%d) gpio_request failed: %d\n",
+                               "HDMI_DDC_CLK", config->ddc_clk_gpio, ret);
+                       goto error1;
+               }
+               ret = gpio_request(config->ddc_data_gpio, "HDMI_DDC_DATA");
+               if (ret) {
+                       dev_err(dev->dev, "'%s'(%d) gpio_request failed: %d\n",
+                               "HDMI_DDC_DATA", config->ddc_data_gpio, ret);
+                       goto error2;
+               }
+               ret = gpio_request(config->hpd_gpio, "HDMI_HPD");
+               if (ret) {
+                       dev_err(dev->dev, "'%s'(%d) gpio_request failed: %d\n",
+                               "HDMI_HPD", config->hpd_gpio, ret);
+                       goto error3;
+               }
+               if (config->pmic_gpio != -1) {
+                       ret = gpio_request(config->pmic_gpio, "PMIC_HDMI_MUX_SEL");
+                       if (ret) {
+                               dev_err(dev->dev, "'%s'(%d) gpio_request failed: %d\n",
+                                       "PMIC_HDMI_MUX_SEL", config->pmic_gpio, ret);
+                               goto error4;
+                       }
+                       gpio_set_value_cansleep(config->pmic_gpio, 0);
+               }
+               DBG("gpio on");
+       } else {
+               gpio_free(config->ddc_clk_gpio);
+               gpio_free(config->ddc_data_gpio);
+               gpio_free(config->hpd_gpio);
+
+               if (config->pmic_gpio != -1) {
+                       gpio_set_value_cansleep(config->pmic_gpio, 1);
+                       gpio_free(config->pmic_gpio);
+               }
+               DBG("gpio off");
+       }
+
+       return 0;
+
+error4:
+       gpio_free(config->hpd_gpio);
+error3:
+       gpio_free(config->ddc_data_gpio);
+error2:
+       gpio_free(config->ddc_clk_gpio);
+error1:
+       return ret;
+}
+
+static int hpd_enable(struct hdmi_connector *hdmi_connector)
+{
+       struct hdmi *hdmi = &hdmi_connector->hdmi;
+       struct drm_device *dev = hdmi_connector->base.base.dev;
+       struct hdmi_phy *phy = hdmi->phy;
+       uint32_t hpd_ctrl;
+       int ret;
+
+       ret = gpio_config(hdmi, true);
+       if (ret) {
+               dev_err(dev->dev, "failed to configure GPIOs: %d\n", ret);
+               goto fail;
+       }
+
+       ret = clk_prepare_enable(hdmi->clk);
+       if (ret) {
+               dev_err(dev->dev, "failed to enable 'clk': %d\n", ret);
+               goto fail;
+       }
+
+       ret = clk_prepare_enable(hdmi->m_pclk);
+       if (ret) {
+               dev_err(dev->dev, "failed to enable 'm_pclk': %d\n", ret);
+               goto fail;
+       }
+
+       ret = clk_prepare_enable(hdmi->s_pclk);
+       if (ret) {
+               dev_err(dev->dev, "failed to enable 's_pclk': %d\n", ret);
+               goto fail;
+       }
+
+       if (hdmi->mpp0)
+               ret = regulator_enable(hdmi->mpp0);
+       if (!ret)
+               ret = regulator_enable(hdmi->mvs);
+       if (ret) {
+               dev_err(dev->dev, "failed to enable regulators: %d\n", ret);
+               goto fail;
+       }
+
+       hdmi_set_mode(hdmi, false);
+       phy->funcs->reset(phy);
+       hdmi_set_mode(hdmi, true);
+
+       hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);
+
+       /* enable HPD events: */
+       hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
+                       HDMI_HPD_INT_CTRL_INT_CONNECT |
+                       HDMI_HPD_INT_CTRL_INT_EN);
+
+       /* set timeout to 4.1ms (max) for hardware debounce */
+       hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
+       hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);
+
+       /* Toggle HPD circuit to trigger HPD sense */
+       hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
+                       ~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
+       hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
+                       HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
+
+       return 0;
+
+fail:
+       return ret;
+}
+
+static int hdp_disable(struct hdmi_connector *hdmi_connector)
+{
+       struct hdmi *hdmi = &hdmi_connector->hdmi;
+       struct drm_device *dev = hdmi_connector->base.base.dev;
+       int ret = 0;
+
+       /* Disable HPD interrupt */
+       hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);
+
+       hdmi_set_mode(hdmi, false);
+
+       if (hdmi->mpp0)
+               ret = regulator_disable(hdmi->mpp0);
+       if (!ret)
+               ret = regulator_disable(hdmi->mvs);
+       if (ret) {
+               dev_err(dev->dev, "failed to enable regulators: %d\n", ret);
+               goto fail;
+       }
+
+       clk_disable_unprepare(hdmi->clk);
+       clk_disable_unprepare(hdmi->m_pclk);
+       clk_disable_unprepare(hdmi->s_pclk);
+
+       ret = gpio_config(hdmi, false);
+       if (ret) {
+               dev_err(dev->dev, "failed to unconfigure GPIOs: %d\n", ret);
+               goto fail;
+       }
+
+       return 0;
+
+fail:
+       return ret;
+}
+
+void hdmi_connector_irq(struct drm_connector *connector)
+{
+       struct msm_connector *msm_connector = to_msm_connector(connector);
+       struct hdmi_connector *hdmi_connector = to_hdmi_connector(msm_connector);
+       struct hdmi *hdmi = &hdmi_connector->hdmi;
+       uint32_t hpd_int_status, hpd_int_ctrl;
+
+       /* Process HPD: */
+       hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+       hpd_int_ctrl   = hdmi_read(hdmi, REG_HDMI_HPD_INT_CTRL);
+
+       if ((hpd_int_ctrl & HDMI_HPD_INT_CTRL_INT_EN) &&
+                       (hpd_int_status & HDMI_HPD_INT_STATUS_INT)) {
+               bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED);
+
+               DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl);
+
+               /* ack the irq: */
+               hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
+                               hpd_int_ctrl | HDMI_HPD_INT_CTRL_INT_ACK);
+
+               drm_helper_hpd_irq_event(connector->dev);
+
+               /* detect disconnect if we are connected or visa versa: */
+               hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN;
+               if (!detected)
+                       hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_CONNECT;
+               hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl);
+       }
+}
+
+static enum drm_connector_status hdmi_connector_detect(
+               struct drm_connector *connector, bool force)
+{
+       struct msm_connector *msm_connector = to_msm_connector(connector);
+       struct hdmi_connector *hdmi_connector = to_hdmi_connector(msm_connector);
+       struct hdmi *hdmi = &hdmi_connector->hdmi;
+       uint32_t hpd_int_status;
+       int retry = 20;
+
+       hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+
+       /* sense seems to in some cases be momentarily de-asserted, don't
+        * let that trick us into thinking the monitor is gone:
+        */
+       while (retry-- && !(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED)) {
+               mdelay(10);
+               hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
+               DBG("status=%08x", hpd_int_status);
+       }
+
+       return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
+                       connector_status_connected : connector_status_disconnected;
+}
+
+static void hdmi_connector_destroy(struct drm_connector *connector)
+{
+       struct msm_connector *msm_connector = to_msm_connector(connector);
+       struct hdmi_connector *hdmi_connector = to_hdmi_connector(msm_connector);
+
+       hdp_disable(hdmi_connector);
+
+       drm_sysfs_connector_remove(connector);
+       drm_connector_cleanup(connector);
+
+       hdmi_destroy(&hdmi_connector->hdmi);
+
+       kfree(hdmi_connector);
+}
+
+static int hdmi_connector_get_modes(struct drm_connector *connector)
+{
+       struct msm_connector *msm_connector = to_msm_connector(connector);
+       struct hdmi_connector *hdmi_connector = to_hdmi_connector(msm_connector);
+       struct hdmi *hdmi = &hdmi_connector->hdmi;
+       struct edid *edid;
+       uint32_t hdmi_ctrl;
+       int ret = 0;
+
+       hdmi_ctrl = hdmi_read(hdmi, REG_HDMI_CTRL);
+       hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl | HDMI_CTRL_ENABLE);
+
+       edid = drm_get_edid(connector, hdmi->i2c);
+
+       hdmi_write(hdmi, REG_HDMI_CTRL, hdmi_ctrl);
+
+       drm_mode_connector_update_edid_property(connector, edid);
+
+       if (edid) {
+               ret = drm_add_edid_modes(connector, edid);
+               kfree(edid);
+       }
+
+       return ret;
+}
+
+static int hdmi_connector_mode_valid(struct drm_connector *connector,
+                                struct drm_display_mode *mode)
+{
+       struct msm_connector *msm_connector = to_msm_connector(connector);
+       struct msm_drm_private *priv = connector->dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       long actual, requested;
+
+       requested = 1000 * mode->clock;
+       actual = kms->funcs->round_pixclk(kms,
+                       requested, msm_connector->encoder);
+
+       DBG("requested=%ld, actual=%ld", requested, actual);
+
+       if (actual != requested)
+               return MODE_CLOCK_RANGE;
+
+       return 0;
+}
+
+static const struct drm_connector_funcs hdmi_connector_funcs = {
+       .dpms = drm_helper_connector_dpms,
+       .detect = hdmi_connector_detect,
+       .fill_modes = drm_helper_probe_single_connector_modes,
+       .destroy = hdmi_connector_destroy,
+};
+
+static const struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
+       .get_modes = hdmi_connector_get_modes,
+       .mode_valid = hdmi_connector_mode_valid,
+       .best_encoder = msm_connector_attached_encoder,
+};
+
+static void hdmi_connector_dpms(struct msm_connector *msm_connector, int mode)
+{
+       struct hdmi_connector *hdmi_connector = to_hdmi_connector(msm_connector);
+       struct hdmi *hdmi = &hdmi_connector->hdmi;
+       struct hdmi_phy *phy = hdmi->phy;
+       bool enabled = (mode == DRM_MODE_DPMS_ON);
+
+       DBG("mode=%d", mode);
+
+       if (enabled == hdmi_connector->enabled)
+               return;
+
+       if (enabled) {
+               phy->funcs->powerup(phy, hdmi_connector->pixclock);
+               hdmi_set_mode(hdmi, true);
+       } else {
+               hdmi_set_mode(hdmi, false);
+               phy->funcs->powerdown(phy);
+       }
+
+       hdmi_connector->enabled = enabled;
+}
+
+static void hdmi_connector_mode_set(struct msm_connector *msm_connector,
+               struct drm_display_mode *mode)
+{
+       struct hdmi_connector *hdmi_connector = to_hdmi_connector(msm_connector);
+       struct hdmi *hdmi = &hdmi_connector->hdmi;
+       int hstart, hend, vstart, vend;
+       uint32_t frame_ctrl;
+
+       hdmi_connector->pixclock = mode->clock * 1000;
+
+       hdmi->hdmi_mode = drm_match_cea_mode(mode) > 1;
+
+       hstart = mode->htotal - mode->hsync_start;
+       hend   = mode->htotal - mode->hsync_start + mode->hdisplay;
+
+       vstart = mode->vtotal - mode->vsync_start - 1;
+       vend   = mode->vtotal - mode->vsync_start + mode->vdisplay - 1;
+
+       DBG("htotal=%d, vtotal=%d, hstart=%d, hend=%d, vstart=%d, vend=%d",
+                       mode->htotal, mode->vtotal, hstart, hend, vstart, vend);
+
+       hdmi_write(hdmi, REG_HDMI_TOTAL,
+                       HDMI_TOTAL_H_TOTAL(mode->htotal - 1) |
+                       HDMI_TOTAL_V_TOTAL(mode->vtotal - 1));
+
+       hdmi_write(hdmi, REG_HDMI_ACTIVE_HSYNC,
+                       HDMI_ACTIVE_HSYNC_START(hstart) |
+                       HDMI_ACTIVE_HSYNC_END(hend));
+       hdmi_write(hdmi, REG_HDMI_ACTIVE_VSYNC,
+                       HDMI_ACTIVE_VSYNC_START(vstart) |
+                       HDMI_ACTIVE_VSYNC_END(vend));
+
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
+               hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2,
+                               HDMI_VSYNC_TOTAL_F2_V_TOTAL(mode->vtotal));
+               hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2,
+                               HDMI_VSYNC_ACTIVE_F2_START(vstart + 1) |
+                               HDMI_VSYNC_ACTIVE_F2_END(vend + 1));
+       } else {
+               hdmi_write(hdmi, REG_HDMI_VSYNC_TOTAL_F2,
+                               HDMI_VSYNC_TOTAL_F2_V_TOTAL(0));
+               hdmi_write(hdmi, REG_HDMI_VSYNC_ACTIVE_F2,
+                               HDMI_VSYNC_ACTIVE_F2_START(0) |
+                               HDMI_VSYNC_ACTIVE_F2_END(0));
+       }
+
+       frame_ctrl = 0;
+       if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+               frame_ctrl |= HDMI_FRAME_CTRL_HSYNC_LOW;
+       if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+               frame_ctrl |= HDMI_FRAME_CTRL_VSYNC_LOW;
+       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+               frame_ctrl |= HDMI_FRAME_CTRL_INTERLACED_EN;
+       DBG("frame_ctrl=%08x", frame_ctrl);
+       hdmi_write(hdmi, REG_HDMI_FRAME_CTRL, frame_ctrl);
+
+       // TODO until we have audio, this might be safest:
+       if (hdmi->hdmi_mode)
+               hdmi_write(hdmi, REG_HDMI_GC, HDMI_GC_MUTE);
+}
+
+static const struct msm_connector_funcs msm_connector_funcs = {
+               .dpms = hdmi_connector_dpms,
+               .mode_set = hdmi_connector_mode_set,
+};
+
+/* initialize connector */
+struct drm_connector *hdmi_connector_init(struct drm_device *dev,
+               struct drm_encoder *encoder)
+{
+       struct drm_connector *connector = NULL;
+       struct hdmi_connector *hdmi_connector;
+       int ret;
+
+       hdmi_connector = kzalloc(sizeof(*hdmi_connector), GFP_KERNEL);
+       if (!hdmi_connector) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       connector = &hdmi_connector->base.base;
+
+       msm_connector_init(&hdmi_connector->base,
+                       &msm_connector_funcs, encoder);
+       drm_connector_init(dev, connector, &hdmi_connector_funcs,
+                       DRM_MODE_CONNECTOR_HDMIA);
+       drm_connector_helper_add(connector, &hdmi_connector_helper_funcs);
+
+       connector->polled = DRM_CONNECTOR_POLL_HPD;
+
+       connector->interlace_allowed = 1;
+       connector->doublescan_allowed = 0;
+
+       drm_sysfs_connector_add(connector);
+
+       ret = hdmi_init(&hdmi_connector->hdmi, dev, connector);
+       if (ret)
+               goto fail;
+
+       ret = hpd_enable(hdmi_connector);
+       if (ret) {
+               dev_err(dev->dev, "failed to enable HPD: %d\n", ret);
+               goto fail;
+       }
+
+       drm_mode_connector_attach_encoder(connector, encoder);
+
+       return connector;
+
+fail:
+       if (connector)
+               hdmi_connector_destroy(connector);
+
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c
new file mode 100644 (file)
index 0000000..f4ab7f7
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hdmi.h"
+
+struct hdmi_i2c_adapter {
+       struct i2c_adapter base;
+       struct hdmi *hdmi;
+       bool sw_done;
+       wait_queue_head_t ddc_event;
+};
+#define to_hdmi_i2c_adapter(x) container_of(x, struct hdmi_i2c_adapter, base)
+
+static void init_ddc(struct hdmi_i2c_adapter *hdmi_i2c)
+{
+       struct hdmi *hdmi = hdmi_i2c->hdmi;
+
+       hdmi_write(hdmi, REG_HDMI_DDC_CTRL,
+                       HDMI_DDC_CTRL_SW_STATUS_RESET);
+       hdmi_write(hdmi, REG_HDMI_DDC_CTRL,
+                       HDMI_DDC_CTRL_SOFT_RESET);
+
+       hdmi_write(hdmi, REG_HDMI_DDC_SPEED,
+                       HDMI_DDC_SPEED_THRESHOLD(2) |
+                       HDMI_DDC_SPEED_PRESCALE(10));
+
+       hdmi_write(hdmi, REG_HDMI_DDC_SETUP,
+                       HDMI_DDC_SETUP_TIMEOUT(0xff));
+
+       /* enable reference timer for 27us */
+       hdmi_write(hdmi, REG_HDMI_DDC_REF,
+                       HDMI_DDC_REF_REFTIMER_ENABLE |
+                       HDMI_DDC_REF_REFTIMER(27));
+}
+
+static int ddc_clear_irq(struct hdmi_i2c_adapter *hdmi_i2c)
+{
+       struct hdmi *hdmi = hdmi_i2c->hdmi;
+       struct drm_device *dev = hdmi->dev;
+       uint32_t retry = 0xffff;
+       uint32_t ddc_int_ctrl;
+
+       do {
+               --retry;
+
+               hdmi_write(hdmi, REG_HDMI_DDC_INT_CTRL,
+                               HDMI_DDC_INT_CTRL_SW_DONE_ACK |
+                               HDMI_DDC_INT_CTRL_SW_DONE_MASK);
+
+               ddc_int_ctrl = hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL);
+
+       } while ((ddc_int_ctrl & HDMI_DDC_INT_CTRL_SW_DONE_INT) && retry);
+
+       if (!retry) {
+               dev_err(dev->dev, "timeout waiting for DDC\n");
+               return -ETIMEDOUT;
+       }
+
+       hdmi_i2c->sw_done = false;
+
+       return 0;
+}
+
+#define MAX_TRANSACTIONS 4
+
+static bool sw_done(struct hdmi_i2c_adapter *hdmi_i2c)
+{
+       struct hdmi *hdmi = hdmi_i2c->hdmi;
+
+       if (!hdmi_i2c->sw_done) {
+               uint32_t ddc_int_ctrl;
+
+               ddc_int_ctrl = hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL);
+
+               if ((ddc_int_ctrl & HDMI_DDC_INT_CTRL_SW_DONE_MASK) &&
+                               (ddc_int_ctrl & HDMI_DDC_INT_CTRL_SW_DONE_INT)) {
+                       hdmi_i2c->sw_done = true;
+                       hdmi_write(hdmi, REG_HDMI_DDC_INT_CTRL,
+                                       HDMI_DDC_INT_CTRL_SW_DONE_ACK);
+               }
+       }
+
+       return hdmi_i2c->sw_done;
+}
+
+static int hdmi_i2c_xfer(struct i2c_adapter *i2c,
+               struct i2c_msg *msgs, int num)
+{
+       struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c);
+       struct hdmi *hdmi = hdmi_i2c->hdmi;
+       struct drm_device *dev = hdmi->dev;
+       static const uint32_t nack[] = {
+                       HDMI_DDC_SW_STATUS_NACK0, HDMI_DDC_SW_STATUS_NACK1,
+                       HDMI_DDC_SW_STATUS_NACK2, HDMI_DDC_SW_STATUS_NACK3,
+       };
+       int indices[MAX_TRANSACTIONS];
+       int ret, i, j, index = 0;
+       uint32_t ddc_status, ddc_data, i2c_trans;
+
+       num = min(num, MAX_TRANSACTIONS);
+
+       WARN_ON(!(hdmi_read(hdmi, REG_HDMI_CTRL) & HDMI_CTRL_ENABLE));
+
+       if (num == 0)
+               return num;
+
+       init_ddc(hdmi_i2c);
+
+       ret = ddc_clear_irq(hdmi_i2c);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < num; i++) {
+               struct i2c_msg *p = &msgs[i];
+               uint32_t raw_addr = p->addr << 1;
+
+               if (p->flags & I2C_M_RD)
+                       raw_addr |= 1;
+
+               ddc_data = HDMI_DDC_DATA_DATA(raw_addr) |
+                               HDMI_DDC_DATA_DATA_RW(DDC_WRITE);
+
+               if (i == 0) {
+                       ddc_data |= HDMI_DDC_DATA_INDEX(0) |
+                                       HDMI_DDC_DATA_INDEX_WRITE;
+               }
+
+               hdmi_write(hdmi, REG_HDMI_DDC_DATA, ddc_data);
+               index++;
+
+               indices[i] = index;
+
+               if (p->flags & I2C_M_RD) {
+                       index += p->len;
+               } else {
+                       for (j = 0; j < p->len; j++) {
+                               ddc_data = HDMI_DDC_DATA_DATA(p->buf[j]) |
+                                               HDMI_DDC_DATA_DATA_RW(DDC_WRITE);
+                               hdmi_write(hdmi, REG_HDMI_DDC_DATA, ddc_data);
+                               index++;
+                       }
+               }
+
+               i2c_trans = HDMI_I2C_TRANSACTION_REG_CNT(p->len) |
+                               HDMI_I2C_TRANSACTION_REG_RW(
+                                               (p->flags & I2C_M_RD) ? DDC_READ : DDC_WRITE) |
+                               HDMI_I2C_TRANSACTION_REG_START;
+
+               if (i == (num - 1))
+                       i2c_trans |= HDMI_I2C_TRANSACTION_REG_STOP;
+
+               hdmi_write(hdmi, REG_HDMI_I2C_TRANSACTION(i), i2c_trans);
+       }
+
+       /* trigger the transfer: */
+       hdmi_write(hdmi, REG_HDMI_DDC_CTRL,
+                       HDMI_DDC_CTRL_TRANSACTION_CNT(num - 1) |
+                       HDMI_DDC_CTRL_GO);
+
+       ret = wait_event_timeout(hdmi_i2c->ddc_event, sw_done(hdmi_i2c), HZ/4);
+       if (ret <= 0) {
+               if (ret == 0)
+                       ret = -ETIMEDOUT;
+               dev_warn(dev->dev, "DDC timeout: %d\n", ret);
+               DBG("sw_status=%08x, hw_status=%08x, int_ctrl=%08x",
+                               hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS),
+                               hdmi_read(hdmi, REG_HDMI_DDC_HW_STATUS),
+                               hdmi_read(hdmi, REG_HDMI_DDC_INT_CTRL));
+               return ret;
+       }
+
+       ddc_status = hdmi_read(hdmi, REG_HDMI_DDC_SW_STATUS);
+
+       /* read back results of any read transactions: */
+       for (i = 0; i < num; i++) {
+               struct i2c_msg *p = &msgs[i];
+
+               if (!(p->flags & I2C_M_RD))
+                       continue;
+
+               /* check for NACK: */
+               if (ddc_status & nack[i]) {
+                       DBG("ddc_status=%08x", ddc_status);
+                       break;
+               }
+
+               ddc_data = HDMI_DDC_DATA_DATA_RW(DDC_READ) |
+                               HDMI_DDC_DATA_INDEX(indices[i]) |
+                               HDMI_DDC_DATA_INDEX_WRITE;
+
+               hdmi_write(hdmi, REG_HDMI_DDC_DATA, ddc_data);
+
+               /* discard first byte: */
+               hdmi_read(hdmi, REG_HDMI_DDC_DATA);
+
+               for (j = 0; j < p->len; j++) {
+                       ddc_data = hdmi_read(hdmi, REG_HDMI_DDC_DATA);
+                       p->buf[j] = FIELD(ddc_data, HDMI_DDC_DATA_DATA);
+               }
+       }
+
+       return i;
+}
+
+static u32 hdmi_i2c_func(struct i2c_adapter *adapter)
+{
+       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm hdmi_i2c_algorithm = {
+       .master_xfer    = hdmi_i2c_xfer,
+       .functionality  = hdmi_i2c_func,
+};
+
+void hdmi_i2c_irq(struct i2c_adapter *i2c)
+{
+       struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c);
+
+       if (sw_done(hdmi_i2c))
+               wake_up_all(&hdmi_i2c->ddc_event);
+}
+
+void hdmi_i2c_destroy(struct i2c_adapter *i2c)
+{
+       struct hdmi_i2c_adapter *hdmi_i2c = to_hdmi_i2c_adapter(i2c);
+       i2c_del_adapter(i2c);
+       kfree(hdmi_i2c);
+}
+
+struct i2c_adapter *hdmi_i2c_init(struct hdmi *hdmi)
+{
+       struct drm_device *dev = hdmi->dev;
+       struct hdmi_i2c_adapter *hdmi_i2c;
+       struct i2c_adapter *i2c = NULL;
+       int ret;
+
+       hdmi_i2c = kzalloc(sizeof(*hdmi_i2c), GFP_KERNEL);
+       if (!hdmi_i2c) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       i2c = &hdmi_i2c->base;
+
+       hdmi_i2c->hdmi = hdmi;
+       init_waitqueue_head(&hdmi_i2c->ddc_event);
+
+
+       i2c->owner = THIS_MODULE;
+       i2c->class = I2C_CLASS_DDC;
+       snprintf(i2c->name, sizeof(i2c->name), "msm hdmi i2c");
+       i2c->dev.parent = &hdmi->pdev->dev;
+       i2c->algo = &hdmi_i2c_algorithm;
+
+       ret = i2c_add_adapter(i2c);
+       if (ret) {
+               dev_err(dev->dev, "failed to register hdmi i2c: %d\n", ret);
+               goto fail;
+       }
+
+       return i2c;
+
+fail:
+       if (i2c)
+               hdmi_i2c_destroy(i2c);
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c
new file mode 100644 (file)
index 0000000..e5b7ed5
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hdmi.h"
+
+struct hdmi_phy_8960 {
+       struct hdmi_phy base;
+       struct hdmi *hdmi;
+};
+#define to_hdmi_phy_8960(x) container_of(x, struct hdmi_phy_8960, base)
+
+static void hdmi_phy_8960_destroy(struct hdmi_phy *phy)
+{
+       struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
+       kfree(phy_8960);
+}
+
+static void hdmi_phy_8960_reset(struct hdmi_phy *phy)
+{
+       struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
+       struct hdmi *hdmi = phy_8960->hdmi;
+       unsigned int val;
+
+       val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);
+
+       if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
+               /* pull low */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val & ~HDMI_PHY_CTRL_SW_RESET);
+       } else {
+               /* pull high */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val | HDMI_PHY_CTRL_SW_RESET);
+       }
+
+       if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
+               /* pull low */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
+       } else {
+               /* pull high */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val | HDMI_PHY_CTRL_SW_RESET_PLL);
+       }
+
+       msleep(100);
+
+       if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
+               /* pull high */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val | HDMI_PHY_CTRL_SW_RESET);
+       } else {
+               /* pull low */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val & ~HDMI_PHY_CTRL_SW_RESET);
+       }
+
+       if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
+               /* pull high */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val | HDMI_PHY_CTRL_SW_RESET_PLL);
+       } else {
+               /* pull low */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
+       }
+}
+
+static void hdmi_phy_8960_powerup(struct hdmi_phy *phy,
+               unsigned long int pixclock)
+{
+       struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
+       struct hdmi *hdmi = phy_8960->hdmi;
+
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG0, 0x1b);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG1, 0xf2);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG4, 0x00);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG5, 0x00);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG6, 0x00);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG7, 0x00);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG8, 0x00);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG9, 0x00);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG10, 0x00);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG11, 0x00);
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG3, 0x20);
+}
+
+static void hdmi_phy_8960_powerdown(struct hdmi_phy *phy)
+{
+       struct hdmi_phy_8960 *phy_8960 = to_hdmi_phy_8960(phy);
+       struct hdmi *hdmi = phy_8960->hdmi;
+
+       hdmi_write(hdmi, REG_HDMI_8960_PHY_REG2, 0x7f);
+}
+
+static const struct hdmi_phy_funcs hdmi_phy_8960_funcs = {
+               .destroy = hdmi_phy_8960_destroy,
+               .reset = hdmi_phy_8960_reset,
+               .powerup = hdmi_phy_8960_powerup,
+               .powerdown = hdmi_phy_8960_powerdown,
+};
+
+struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi)
+{
+       struct hdmi_phy_8960 *phy_8960;
+       struct hdmi_phy *phy = NULL;
+       int ret;
+
+       phy_8960 = kzalloc(sizeof(*phy_8960), GFP_KERNEL);
+       if (!phy_8960) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       phy = &phy_8960->base;
+
+       phy->funcs = &hdmi_phy_8960_funcs;
+
+       phy_8960->hdmi = hdmi;
+
+       return phy;
+
+fail:
+       if (phy)
+               hdmi_phy_8960_destroy(phy);
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c
new file mode 100644 (file)
index 0000000..391433c
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "hdmi.h"
+
+struct hdmi_phy_8x60 {
+       struct hdmi_phy base;
+       struct hdmi *hdmi;
+};
+#define to_hdmi_phy_8x60(x) container_of(x, struct hdmi_phy_8x60, base)
+
+static void hdmi_phy_8x60_destroy(struct hdmi_phy *phy)
+{
+       struct hdmi_phy_8x60 *phy_8x60 = to_hdmi_phy_8x60(phy);
+       kfree(phy_8x60);
+}
+
+static void hdmi_phy_8x60_reset(struct hdmi_phy *phy)
+{
+       struct hdmi_phy_8x60 *phy_8x60 = to_hdmi_phy_8x60(phy);
+       struct hdmi *hdmi = phy_8x60->hdmi;
+       unsigned int val;
+
+       val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);
+
+       if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
+               /* pull low */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val & ~HDMI_PHY_CTRL_SW_RESET);
+       } else {
+               /* pull high */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val | HDMI_PHY_CTRL_SW_RESET);
+       }
+
+       msleep(100);
+
+       if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
+               /* pull high */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val | HDMI_PHY_CTRL_SW_RESET);
+       } else {
+               /* pull low */
+               hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                               val & ~HDMI_PHY_CTRL_SW_RESET);
+       }
+}
+
+static void hdmi_phy_8x60_powerup(struct hdmi_phy *phy,
+               unsigned long int pixclock)
+{
+       struct hdmi_phy_8x60 *phy_8x60 = to_hdmi_phy_8x60(phy);
+       struct hdmi *hdmi = phy_8x60->hdmi;
+
+       /* De-serializer delay D/C for non-lbk mode: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG0,
+                       HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(3));
+
+       if (pixclock == 27000000) {
+               /* video_format == HDMI_VFRMT_720x480p60_16_9 */
+               hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG1,
+                               HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) |
+                               HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(3));
+       } else {
+               hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG1,
+                               HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) |
+                               HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(4));
+       }
+
+       /* No matter what, start from the power down mode: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2,
+                       HDMI_8x60_PHY_REG2_PD_PWRGEN |
+                       HDMI_8x60_PHY_REG2_PD_PLL |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+                       HDMI_8x60_PHY_REG2_PD_DESER);
+
+       /* Turn PowerGen on: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2,
+                       HDMI_8x60_PHY_REG2_PD_PLL |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+                       HDMI_8x60_PHY_REG2_PD_DESER);
+
+       /* Turn PLL power on: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2,
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+                       HDMI_8x60_PHY_REG2_PD_DESER);
+
+       /* Write to HIGH after PLL power down de-assert: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG3,
+                       HDMI_8x60_PHY_REG3_PLL_ENABLE);
+
+       /* ASIC power on; PHY REG9 = 0 */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG9, 0);
+
+       /* Enable PLL lock detect, PLL lock det will go high after lock
+        * Enable the re-time logic
+        */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG12,
+                       HDMI_8x60_PHY_REG12_RETIMING_EN |
+                       HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN);
+
+       /* Drivers are on: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2,
+                       HDMI_8x60_PHY_REG2_PD_DESER);
+
+       /* If the RX detector is needed: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2,
+                       HDMI_8x60_PHY_REG2_RCV_SENSE_EN |
+                       HDMI_8x60_PHY_REG2_PD_DESER);
+
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG4, 0);
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG5, 0);
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG6, 0);
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG7, 0);
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG8, 0);
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG9, 0);
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG10, 0);
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG11, 0);
+
+       /* If we want to use lock enable based on counting: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG12,
+                       HDMI_8x60_PHY_REG12_RETIMING_EN |
+                       HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN |
+                       HDMI_8x60_PHY_REG12_FORCE_LOCK);
+}
+
+static void hdmi_phy_8x60_powerdown(struct hdmi_phy *phy)
+{
+       struct hdmi_phy_8x60 *phy_8x60 = to_hdmi_phy_8x60(phy);
+       struct hdmi *hdmi = phy_8x60->hdmi;
+
+       /* Assert RESET PHY from controller */
+       hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
+                       HDMI_PHY_CTRL_SW_RESET);
+       udelay(10);
+       /* De-assert RESET PHY from controller */
+       hdmi_write(hdmi, REG_HDMI_PHY_CTRL, 0);
+       /* Turn off Driver */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2,
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+                       HDMI_8x60_PHY_REG2_PD_DESER);
+       udelay(10);
+       /* Disable PLL */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG3, 0);
+       /* Power down PHY, but keep RX-sense: */
+       hdmi_write(hdmi, REG_HDMI_8x60_PHY_REG2,
+                       HDMI_8x60_PHY_REG2_RCV_SENSE_EN |
+                       HDMI_8x60_PHY_REG2_PD_PWRGEN |
+                       HDMI_8x60_PHY_REG2_PD_PLL |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_4 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_3 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_2 |
+                       HDMI_8x60_PHY_REG2_PD_DRIVE_1 |
+                       HDMI_8x60_PHY_REG2_PD_DESER);
+}
+
+static const struct hdmi_phy_funcs hdmi_phy_8x60_funcs = {
+               .destroy = hdmi_phy_8x60_destroy,
+               .reset = hdmi_phy_8x60_reset,
+               .powerup = hdmi_phy_8x60_powerup,
+               .powerdown = hdmi_phy_8x60_powerdown,
+};
+
+struct hdmi_phy *hdmi_phy_8x60_init(struct hdmi *hdmi)
+{
+       struct hdmi_phy_8x60 *phy_8x60;
+       struct hdmi_phy *phy = NULL;
+       int ret;
+
+       phy_8x60 = kzalloc(sizeof(*phy_8x60), GFP_KERNEL);
+       if (!phy_8x60) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       phy = &phy_8x60->base;
+
+       phy->funcs = &hdmi_phy_8x60_funcs;
+
+       phy_8x60->hdmi = hdmi;
+
+       return phy;
+
+fail:
+       if (phy)
+               hdmi_phy_8x60_destroy(phy);
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h
new file mode 100644 (file)
index 0000000..bee3636
--- /dev/null
@@ -0,0 +1,50 @@
+#ifndef QFPROM_XML
+#define QFPROM_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml                 (    595 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml           (  19332 bytes, from 2013-08-16 22:16:36)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml             (  11712 bytes, from 2013-08-17 17:13:43)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml            (    344 bytes, from 2013-08-11 19:26:32)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml         (   1544 bytes, from 2013-08-16 19:17:05)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml         (    600 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml           (  19288 bytes, from 2013-08-11 18:14:15)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+#define REG_QFPROM_CONFIG_ROW0_LSB                             0x00000238
+#define QFPROM_CONFIG_ROW0_LSB_HDMI_DISABLE                    0x00200000
+#define QFPROM_CONFIG_ROW0_LSB_HDCP_DISABLE                    0x00400000
+
+
+#endif /* QFPROM_XML */
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/mdp4/mdp4.xml.h
new file mode 100644 (file)
index 0000000..bbeeebe
--- /dev/null
@@ -0,0 +1,1061 @@
+#ifndef MDP4_XML
+#define MDP4_XML
+
+/* Autogenerated file, DO NOT EDIT manually!
+
+This file was generated by the rules-ng-ng headergen tool in this git repository:
+http://0x04.net/cgit/index.cgi/rules-ng-ng
+git clone git://0x04.net/rules-ng-ng
+
+The rules-ng-ng source files this header was generated from are:
+- /home/robclark/src/freedreno/envytools/rnndb/msm.xml                 (    595 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml (   1453 bytes, from 2013-03-31 16:51:27)
+- /home/robclark/src/freedreno/envytools/rnndb/mdp4/mdp4.xml           (  19332 bytes, from 2013-08-16 22:16:36)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml             (  11712 bytes, from 2013-08-17 17:13:43)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml            (    344 bytes, from 2013-08-11 19:26:32)
+- /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml         (   1544 bytes, from 2013-08-16 19:17:05)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml         (    600 bytes, from 2013-07-05 19:21:12)
+- /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml           (  19288 bytes, from 2013-08-11 18:14:15)
+
+Copyright (C) 2013 by the following authors:
+- Rob Clark <robdclark@gmail.com> (robclark)
+
+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 (including the
+next paragraph) 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 COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
+*/
+
+
+enum mpd4_bpc {
+       BPC1 = 0,
+       BPC5 = 1,
+       BPC6 = 2,
+       BPC8 = 3,
+};
+
+enum mpd4_bpc_alpha {
+       BPC1A = 0,
+       BPC4A = 1,
+       BPC6A = 2,
+       BPC8A = 3,
+};
+
+enum mpd4_alpha_type {
+       FG_CONST = 0,
+       BG_CONST = 1,
+       FG_PIXEL = 2,
+       BG_PIXEL = 3,
+};
+
+enum mpd4_pipe {
+       VG1 = 0,
+       VG2 = 1,
+       RGB1 = 2,
+       RGB2 = 3,
+       RGB3 = 4,
+       VG3 = 5,
+       VG4 = 6,
+};
+
+enum mpd4_mixer {
+       MIXER0 = 0,
+       MIXER1 = 1,
+       MIXER2 = 2,
+};
+
+enum mpd4_mixer_stage_id {
+       STAGE_UNUSED = 0,
+       STAGE_BASE = 1,
+       STAGE0 = 2,
+       STAGE1 = 3,
+       STAGE2 = 4,
+       STAGE3 = 5,
+};
+
+enum mdp4_intf {
+       INTF_LCDC_DTV = 0,
+       INTF_DSI_VIDEO = 1,
+       INTF_DSI_CMD = 2,
+       INTF_EBI2_TV = 3,
+};
+
+enum mdp4_cursor_format {
+       CURSOR_ARGB = 1,
+       CURSOR_XRGB = 2,
+};
+
+enum mdp4_dma {
+       DMA_P = 0,
+       DMA_S = 1,
+       DMA_E = 2,
+};
+
+#define MDP4_IRQ_OVERLAY0_DONE                                 0x00000001
+#define MDP4_IRQ_OVERLAY1_DONE                                 0x00000002
+#define MDP4_IRQ_DMA_S_DONE                                    0x00000004
+#define MDP4_IRQ_DMA_E_DONE                                    0x00000008
+#define MDP4_IRQ_DMA_P_DONE                                    0x00000010
+#define MDP4_IRQ_VG1_HISTOGRAM                                 0x00000020
+#define MDP4_IRQ_VG2_HISTOGRAM                                 0x00000040
+#define MDP4_IRQ_PRIMARY_VSYNC                                 0x00000080
+#define MDP4_IRQ_PRIMARY_INTF_UDERRUN                          0x00000100
+#define MDP4_IRQ_EXTERNAL_VSYNC                                        0x00000200
+#define MDP4_IRQ_EXTERNAL_INTF_UDERRUN                         0x00000400
+#define MDP4_IRQ_PRIMARY_RDPTR                                 0x00000800
+#define MDP4_IRQ_DMA_P_HISTOGRAM                               0x00020000
+#define MDP4_IRQ_DMA_S_HISTOGRAM                               0x04000000
+#define MDP4_IRQ_OVERLAY2_DONE                                 0x40000000
+#define REG_MDP4_VERSION                                       0x00000000
+#define MDP4_VERSION_MINOR__MASK                               0x00ff0000
+#define MDP4_VERSION_MINOR__SHIFT                              16
+static inline uint32_t MDP4_VERSION_MINOR(uint32_t val)
+{
+       return ((val) << MDP4_VERSION_MINOR__SHIFT) & MDP4_VERSION_MINOR__MASK;
+}
+#define MDP4_VERSION_MAJOR__MASK                               0xff000000
+#define MDP4_VERSION_MAJOR__SHIFT                              24
+static inline uint32_t MDP4_VERSION_MAJOR(uint32_t val)
+{
+       return ((val) << MDP4_VERSION_MAJOR__SHIFT) & MDP4_VERSION_MAJOR__MASK;
+}
+
+#define REG_MDP4_OVLP0_KICK                                    0x00000004
+
+#define REG_MDP4_OVLP1_KICK                                    0x00000008
+
+#define REG_MDP4_OVLP2_KICK                                    0x000000d0
+
+#define REG_MDP4_DMA_P_KICK                                    0x0000000c
+
+#define REG_MDP4_DMA_S_KICK                                    0x00000010
+
+#define REG_MDP4_DMA_E_KICK                                    0x00000014
+
+#define REG_MDP4_DISP_STATUS                                   0x00000018
+
+#define REG_MDP4_DISP_INTF_SEL                                 0x00000038
+#define MDP4_DISP_INTF_SEL_PRIM__MASK                          0x00000003
+#define MDP4_DISP_INTF_SEL_PRIM__SHIFT                         0
+static inline uint32_t MDP4_DISP_INTF_SEL_PRIM(enum mdp4_intf val)
+{
+       return ((val) << MDP4_DISP_INTF_SEL_PRIM__SHIFT) & MDP4_DISP_INTF_SEL_PRIM__MASK;
+}
+#define MDP4_DISP_INTF_SEL_SEC__MASK                           0x0000000c
+#define MDP4_DISP_INTF_SEL_SEC__SHIFT                          2
+static inline uint32_t MDP4_DISP_INTF_SEL_SEC(enum mdp4_intf val)
+{
+       return ((val) << MDP4_DISP_INTF_SEL_SEC__SHIFT) & MDP4_DISP_INTF_SEL_SEC__MASK;
+}
+#define MDP4_DISP_INTF_SEL_EXT__MASK                           0x00000030
+#define MDP4_DISP_INTF_SEL_EXT__SHIFT                          4
+static inline uint32_t MDP4_DISP_INTF_SEL_EXT(enum mdp4_intf val)
+{
+       return ((val) << MDP4_DISP_INTF_SEL_EXT__SHIFT) & MDP4_DISP_INTF_SEL_EXT__MASK;
+}
+#define MDP4_DISP_INTF_SEL_DSI_VIDEO                           0x00000040
+#define MDP4_DISP_INTF_SEL_DSI_CMD                             0x00000080
+
+#define REG_MDP4_RESET_STATUS                                  0x0000003c
+
+#define REG_MDP4_READ_CNFG                                     0x0000004c
+
+#define REG_MDP4_INTR_ENABLE                                   0x00000050
+
+#define REG_MDP4_INTR_STATUS                                   0x00000054
+
+#define REG_MDP4_INTR_CLEAR                                    0x00000058
+
+#define REG_MDP4_EBI2_LCD0                                     0x00000060
+
+#define REG_MDP4_EBI2_LCD1                                     0x00000064
+
+#define REG_MDP4_PORTMAP_MODE                                  0x00000070
+
+#define REG_MDP4_CS_CONTROLLER0                                        0x000000c0
+
+#define REG_MDP4_CS_CONTROLLER1                                        0x000000c4
+
+#define REG_MDP4_LAYERMIXER2_IN_CFG                            0x000100f0
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE0__MASK                    0x00000007
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE0__SHIFT                   0
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE0(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE0__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE0__MASK;
+}
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE0_MIXER1                   0x00000008
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE1__MASK                    0x00000070
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE1__SHIFT                   4
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE1(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE1__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE1__MASK;
+}
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE1_MIXER1                   0x00000080
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE2__MASK                    0x00000700
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE2__SHIFT                   8
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE2(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE2__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE2__MASK;
+}
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE2_MIXER1                   0x00000800
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE3__MASK                    0x00007000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE3__SHIFT                   12
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE3(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE3__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE3__MASK;
+}
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE3_MIXER1                   0x00008000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE4__MASK                    0x00070000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE4__SHIFT                   16
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE4(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE4__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE4__MASK;
+}
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE4_MIXER1                   0x00080000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE5__MASK                    0x00700000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE5__SHIFT                   20
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE5(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE5__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE5__MASK;
+}
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE5_MIXER1                   0x00800000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE6__MASK                    0x07000000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE6__SHIFT                   24
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE6(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE6__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE6__MASK;
+}
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE6_MIXER1                   0x08000000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE7__MASK                    0x70000000
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE7__SHIFT                   28
+static inline uint32_t MDP4_LAYERMIXER2_IN_CFG_PIPE7(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER2_IN_CFG_PIPE7__SHIFT) & MDP4_LAYERMIXER2_IN_CFG_PIPE7__MASK;
+}
+#define MDP4_LAYERMIXER2_IN_CFG_PIPE7_MIXER1                   0x80000000
+
+#define REG_MDP4_LAYERMIXER_IN_CFG_UPDATE_METHOD               0x000100fc
+
+#define REG_MDP4_LAYERMIXER_IN_CFG                             0x00010100
+#define MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK                     0x00000007
+#define MDP4_LAYERMIXER_IN_CFG_PIPE0__SHIFT                    0
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE0(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE0__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK;
+}
+#define MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1                    0x00000008
+#define MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK                     0x00000070
+#define MDP4_LAYERMIXER_IN_CFG_PIPE1__SHIFT                    4
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE1(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE1__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK;
+}
+#define MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1                    0x00000080
+#define MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK                     0x00000700
+#define MDP4_LAYERMIXER_IN_CFG_PIPE2__SHIFT                    8
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE2(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE2__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK;
+}
+#define MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1                    0x00000800
+#define MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK                     0x00007000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE3__SHIFT                    12
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE3(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE3__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK;
+}
+#define MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1                    0x00008000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK                     0x00070000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE4__SHIFT                    16
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE4(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE4__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK;
+}
+#define MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1                    0x00080000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK                     0x00700000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE5__SHIFT                    20
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE5(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE5__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK;
+}
+#define MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1                    0x00800000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK                     0x07000000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE6__SHIFT                    24
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE6(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE6__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK;
+}
+#define MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1                    0x08000000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE7__MASK                     0x70000000
+#define MDP4_LAYERMIXER_IN_CFG_PIPE7__SHIFT                    28
+static inline uint32_t MDP4_LAYERMIXER_IN_CFG_PIPE7(enum mpd4_mixer_stage_id val)
+{
+       return ((val) << MDP4_LAYERMIXER_IN_CFG_PIPE7__SHIFT) & MDP4_LAYERMIXER_IN_CFG_PIPE7__MASK;
+}
+#define MDP4_LAYERMIXER_IN_CFG_PIPE7_MIXER1                    0x80000000
+
+#define REG_MDP4_VG2_SRC_FORMAT                                        0x00030050
+
+#define REG_MDP4_VG2_CONST_COLOR                               0x00031008
+
+#define REG_MDP4_OVERLAY_FLUSH                                 0x00018000
+#define MDP4_OVERLAY_FLUSH_OVLP0                               0x00000001
+#define MDP4_OVERLAY_FLUSH_OVLP1                               0x00000002
+#define MDP4_OVERLAY_FLUSH_VG1                                 0x00000004
+#define MDP4_OVERLAY_FLUSH_VG2                                 0x00000008
+#define MDP4_OVERLAY_FLUSH_RGB1                                        0x00000010
+#define MDP4_OVERLAY_FLUSH_RGB2                                        0x00000020
+
+static inline uint32_t __offset_OVLP(uint32_t idx)
+{
+       switch (idx) {
+               case 0: return 0x00010000;
+               case 1: return 0x00018000;
+               case 2: return 0x00088000;
+               default: return INVALID_IDX(idx);
+       }
+}
+static inline uint32_t REG_MDP4_OVLP(uint32_t i0) { return 0x00000000 + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_CFG(uint32_t i0) { return 0x00000004 + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_SIZE(uint32_t i0) { return 0x00000008 + __offset_OVLP(i0); }
+#define MDP4_OVLP_SIZE_HEIGHT__MASK                            0xffff0000
+#define MDP4_OVLP_SIZE_HEIGHT__SHIFT                           16
+static inline uint32_t MDP4_OVLP_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val) << MDP4_OVLP_SIZE_HEIGHT__SHIFT) & MDP4_OVLP_SIZE_HEIGHT__MASK;
+}
+#define MDP4_OVLP_SIZE_WIDTH__MASK                             0x0000ffff
+#define MDP4_OVLP_SIZE_WIDTH__SHIFT                            0
+static inline uint32_t MDP4_OVLP_SIZE_WIDTH(uint32_t val)
+{
+       return ((val) << MDP4_OVLP_SIZE_WIDTH__SHIFT) & MDP4_OVLP_SIZE_WIDTH__MASK;
+}
+
+static inline uint32_t REG_MDP4_OVLP_BASE(uint32_t i0) { return 0x0000000c + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_STRIDE(uint32_t i0) { return 0x00000010 + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_OPMODE(uint32_t i0) { return 0x00000014 + __offset_OVLP(i0); }
+
+static inline uint32_t __offset_STAGE(uint32_t idx)
+{
+       switch (idx) {
+               case 0: return 0x00000104;
+               case 1: return 0x00000124;
+               case 2: return 0x00000144;
+               case 3: return 0x00000160;
+               default: return INVALID_IDX(idx);
+       }
+}
+static inline uint32_t REG_MDP4_OVLP_STAGE(uint32_t i0, uint32_t i1) { return 0x00000000 + __offset_OVLP(i0) + __offset_STAGE(i1); }
+
+static inline uint32_t REG_MDP4_OVLP_STAGE_OP(uint32_t i0, uint32_t i1) { return 0x00000000 + __offset_OVLP(i0) + __offset_STAGE(i1); }
+#define MDP4_OVLP_STAGE_OP_FG_ALPHA__MASK                      0x00000003
+#define MDP4_OVLP_STAGE_OP_FG_ALPHA__SHIFT                     0
+static inline uint32_t MDP4_OVLP_STAGE_OP_FG_ALPHA(enum mpd4_alpha_type val)
+{
+       return ((val) << MDP4_OVLP_STAGE_OP_FG_ALPHA__SHIFT) & MDP4_OVLP_STAGE_OP_FG_ALPHA__MASK;
+}
+#define MDP4_OVLP_STAGE_OP_FG_INV_ALPHA                                0x00000004
+#define MDP4_OVLP_STAGE_OP_FG_MOD_ALPHA                                0x00000008
+#define MDP4_OVLP_STAGE_OP_BG_ALPHA__MASK                      0x00000030
+#define MDP4_OVLP_STAGE_OP_BG_ALPHA__SHIFT                     4
+static inline uint32_t MDP4_OVLP_STAGE_OP_BG_ALPHA(enum mpd4_alpha_type val)
+{
+       return ((val) << MDP4_OVLP_STAGE_OP_BG_ALPHA__SHIFT) & MDP4_OVLP_STAGE_OP_BG_ALPHA__MASK;
+}
+#define MDP4_OVLP_STAGE_OP_BG_INV_ALPHA                                0x00000040
+#define MDP4_OVLP_STAGE_OP_BG_MOD_ALPHA                                0x00000080
+#define MDP4_OVLP_STAGE_OP_FG_TRANSP                           0x00000100
+#define MDP4_OVLP_STAGE_OP_BG_TRANSP                           0x00000200
+
+static inline uint32_t REG_MDP4_OVLP_STAGE_FG_ALPHA(uint32_t i0, uint32_t i1) { return 0x00000004 + __offset_OVLP(i0) + __offset_STAGE(i1); }
+
+static inline uint32_t REG_MDP4_OVLP_STAGE_BG_ALPHA(uint32_t i0, uint32_t i1) { return 0x00000008 + __offset_OVLP(i0) + __offset_STAGE(i1); }
+
+static inline uint32_t REG_MDP4_OVLP_STAGE_TRANSP_LOW0(uint32_t i0, uint32_t i1) { return 0x0000000c + __offset_OVLP(i0) + __offset_STAGE(i1); }
+
+static inline uint32_t REG_MDP4_OVLP_STAGE_TRANSP_LOW1(uint32_t i0, uint32_t i1) { return 0x00000010 + __offset_OVLP(i0) + __offset_STAGE(i1); }
+
+static inline uint32_t REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(uint32_t i0, uint32_t i1) { return 0x00000014 + __offset_OVLP(i0) + __offset_STAGE(i1); }
+
+static inline uint32_t REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(uint32_t i0, uint32_t i1) { return 0x00000018 + __offset_OVLP(i0) + __offset_STAGE(i1); }
+
+static inline uint32_t __offset_STAGE_CO3(uint32_t idx)
+{
+       switch (idx) {
+               case 0: return 0x00001004;
+               case 1: return 0x00001404;
+               case 2: return 0x00001804;
+               case 3: return 0x00001b84;
+               default: return INVALID_IDX(idx);
+       }
+}
+static inline uint32_t REG_MDP4_OVLP_STAGE_CO3(uint32_t i0, uint32_t i1) { return 0x00000000 + __offset_OVLP(i0) + __offset_STAGE_CO3(i1); }
+
+static inline uint32_t REG_MDP4_OVLP_STAGE_CO3_SEL(uint32_t i0, uint32_t i1) { return 0x00000000 + __offset_OVLP(i0) + __offset_STAGE_CO3(i1); }
+#define MDP4_OVLP_STAGE_CO3_SEL_FG_ALPHA                       0x00000001
+
+static inline uint32_t REG_MDP4_OVLP_TRANSP_LOW0(uint32_t i0) { return 0x00000180 + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_TRANSP_LOW1(uint32_t i0) { return 0x00000184 + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_TRANSP_HIGH0(uint32_t i0) { return 0x00000188 + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_TRANSP_HIGH1(uint32_t i0) { return 0x0000018c + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_CONFIG(uint32_t i0) { return 0x00000200 + __offset_OVLP(i0); }
+
+static inline uint32_t REG_MDP4_OVLP_CSC(uint32_t i0) { return 0x00002000 + __offset_OVLP(i0); }
+
+
+static inline uint32_t REG_MDP4_OVLP_CSC_MV(uint32_t i0, uint32_t i1) { return 0x00002400 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_MV_VAL(uint32_t i0, uint32_t i1) { return 0x00002400 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_PRE_BV(uint32_t i0, uint32_t i1) { return 0x00002500 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_PRE_BV_VAL(uint32_t i0, uint32_t i1) { return 0x00002500 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_POST_BV(uint32_t i0, uint32_t i1) { return 0x00002580 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_POST_BV_VAL(uint32_t i0, uint32_t i1) { return 0x00002580 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_PRE_LV(uint32_t i0, uint32_t i1) { return 0x00002600 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_PRE_LV_VAL(uint32_t i0, uint32_t i1) { return 0x00002600 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_POST_LV(uint32_t i0, uint32_t i1) { return 0x00002680 + __offset_OVLP(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_OVLP_CSC_POST_LV_VAL(uint32_t i0, uint32_t i1) { return 0x00002680 + __offset_OVLP(i0) + 0x4*i1; }
+
+#define REG_MDP4_DMA_P_OP_MODE                                 0x00090070
+
+static inline uint32_t REG_MDP4_LUTN(uint32_t i0) { return 0x00094800 + 0x400*i0; }
+
+static inline uint32_t REG_MDP4_LUTN_LUT(uint32_t i0, uint32_t i1) { return 0x00094800 + 0x400*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_LUTN_LUT_VAL(uint32_t i0, uint32_t i1) { return 0x00094800 + 0x400*i0 + 0x4*i1; }
+
+#define REG_MDP4_DMA_S_OP_MODE                                 0x000a0028
+
+static inline uint32_t REG_MDP4_DMA_E_QUANT(uint32_t i0) { return 0x000b0070 + 0x4*i0; }
+
+static inline uint32_t __offset_DMA(enum mdp4_dma idx)
+{
+       switch (idx) {
+               case DMA_P: return 0x00090000;
+               case DMA_S: return 0x000a0000;
+               case DMA_E: return 0x000b0000;
+               default: return INVALID_IDX(idx);
+       }
+}
+static inline uint32_t REG_MDP4_DMA(enum mdp4_dma i0) { return 0x00000000 + __offset_DMA(i0); }
+
+static inline uint32_t REG_MDP4_DMA_CONFIG(enum mdp4_dma i0) { return 0x00000000 + __offset_DMA(i0); }
+#define MDP4_DMA_CONFIG_G_BPC__MASK                            0x00000003
+#define MDP4_DMA_CONFIG_G_BPC__SHIFT                           0
+static inline uint32_t MDP4_DMA_CONFIG_G_BPC(enum mpd4_bpc val)
+{
+       return ((val) << MDP4_DMA_CONFIG_G_BPC__SHIFT) & MDP4_DMA_CONFIG_G_BPC__MASK;
+}
+#define MDP4_DMA_CONFIG_B_BPC__MASK                            0x0000000c
+#define MDP4_DMA_CONFIG_B_BPC__SHIFT                           2
+static inline uint32_t MDP4_DMA_CONFIG_B_BPC(enum mpd4_bpc val)
+{
+       return ((val) << MDP4_DMA_CONFIG_B_BPC__SHIFT) & MDP4_DMA_CONFIG_B_BPC__MASK;
+}
+#define MDP4_DMA_CONFIG_R_BPC__MASK                            0x00000030
+#define MDP4_DMA_CONFIG_R_BPC__SHIFT                           4
+static inline uint32_t MDP4_DMA_CONFIG_R_BPC(enum mpd4_bpc val)
+{
+       return ((val) << MDP4_DMA_CONFIG_R_BPC__SHIFT) & MDP4_DMA_CONFIG_R_BPC__MASK;
+}
+#define MDP4_DMA_CONFIG_PACK_ALIGN_MSB                         0x00000080
+#define MDP4_DMA_CONFIG_PACK__MASK                             0x0000ff00
+#define MDP4_DMA_CONFIG_PACK__SHIFT                            8
+static inline uint32_t MDP4_DMA_CONFIG_PACK(uint32_t val)
+{
+       return ((val) << MDP4_DMA_CONFIG_PACK__SHIFT) & MDP4_DMA_CONFIG_PACK__MASK;
+}
+#define MDP4_DMA_CONFIG_DEFLKR_EN                              0x01000000
+#define MDP4_DMA_CONFIG_DITHER_EN                              0x01000000
+
+static inline uint32_t REG_MDP4_DMA_SRC_SIZE(enum mdp4_dma i0) { return 0x00000004 + __offset_DMA(i0); }
+#define MDP4_DMA_SRC_SIZE_HEIGHT__MASK                         0xffff0000
+#define MDP4_DMA_SRC_SIZE_HEIGHT__SHIFT                                16
+static inline uint32_t MDP4_DMA_SRC_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val) << MDP4_DMA_SRC_SIZE_HEIGHT__SHIFT) & MDP4_DMA_SRC_SIZE_HEIGHT__MASK;
+}
+#define MDP4_DMA_SRC_SIZE_WIDTH__MASK                          0x0000ffff
+#define MDP4_DMA_SRC_SIZE_WIDTH__SHIFT                         0
+static inline uint32_t MDP4_DMA_SRC_SIZE_WIDTH(uint32_t val)
+{
+       return ((val) << MDP4_DMA_SRC_SIZE_WIDTH__SHIFT) & MDP4_DMA_SRC_SIZE_WIDTH__MASK;
+}
+
+static inline uint32_t REG_MDP4_DMA_SRC_BASE(enum mdp4_dma i0) { return 0x00000008 + __offset_DMA(i0); }
+
+static inline uint32_t REG_MDP4_DMA_SRC_STRIDE(enum mdp4_dma i0) { return 0x0000000c + __offset_DMA(i0); }
+
+static inline uint32_t REG_MDP4_DMA_DST_SIZE(enum mdp4_dma i0) { return 0x00000010 + __offset_DMA(i0); }
+#define MDP4_DMA_DST_SIZE_HEIGHT__MASK                         0xffff0000
+#define MDP4_DMA_DST_SIZE_HEIGHT__SHIFT                                16
+static inline uint32_t MDP4_DMA_DST_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val) << MDP4_DMA_DST_SIZE_HEIGHT__SHIFT) & MDP4_DMA_DST_SIZE_HEIGHT__MASK;
+}
+#define MDP4_DMA_DST_SIZE_WIDTH__MASK                          0x0000ffff
+#define MDP4_DMA_DST_SIZE_WIDTH__SHIFT                         0
+static inline uint32_t MDP4_DMA_DST_SIZE_WIDTH(uint32_t val)
+{
+       return ((val) << MDP4_DMA_DST_SIZE_WIDTH__SHIFT) & MDP4_DMA_DST_SIZE_WIDTH__MASK;
+}
+
+static inline uint32_t REG_MDP4_DMA_CURSOR_SIZE(enum mdp4_dma i0) { return 0x00000044 + __offset_DMA(i0); }
+#define MDP4_DMA_CURSOR_SIZE_WIDTH__MASK                       0x0000007f
+#define MDP4_DMA_CURSOR_SIZE_WIDTH__SHIFT                      0
+static inline uint32_t MDP4_DMA_CURSOR_SIZE_WIDTH(uint32_t val)
+{
+       return ((val) << MDP4_DMA_CURSOR_SIZE_WIDTH__SHIFT) & MDP4_DMA_CURSOR_SIZE_WIDTH__MASK;
+}
+#define MDP4_DMA_CURSOR_SIZE_HEIGHT__MASK                      0x007f0000
+#define MDP4_DMA_CURSOR_SIZE_HEIGHT__SHIFT                     16
+static inline uint32_t MDP4_DMA_CURSOR_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val) << MDP4_DMA_CURSOR_SIZE_HEIGHT__SHIFT) & MDP4_DMA_CURSOR_SIZE_HEIGHT__MASK;
+}
+
+static inline uint32_t REG_MDP4_DMA_CURSOR_BASE(enum mdp4_dma i0) { return 0x00000048 + __offset_DMA(i0); }
+
+static inline uint32_t REG_MDP4_DMA_CURSOR_POS(enum mdp4_dma i0) { return 0x0000004c + __offset_DMA(i0); }
+#define MDP4_DMA_CURSOR_POS_X__MASK                            0x0000ffff
+#define MDP4_DMA_CURSOR_POS_X__SHIFT                           0
+static inline uint32_t MDP4_DMA_CURSOR_POS_X(uint32_t val)
+{
+       return ((val) << MDP4_DMA_CURSOR_POS_X__SHIFT) & MDP4_DMA_CURSOR_POS_X__MASK;
+}
+#define MDP4_DMA_CURSOR_POS_Y__MASK                            0xffff0000
+#define MDP4_DMA_CURSOR_POS_Y__SHIFT                           16
+static inline uint32_t MDP4_DMA_CURSOR_POS_Y(uint32_t val)
+{
+       return ((val) << MDP4_DMA_CURSOR_POS_Y__SHIFT) & MDP4_DMA_CURSOR_POS_Y__MASK;
+}
+
+static inline uint32_t REG_MDP4_DMA_CURSOR_BLEND_CONFIG(enum mdp4_dma i0) { return 0x00000060 + __offset_DMA(i0); }
+#define MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN                 0x00000001
+#define MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT__MASK              0x00000006
+#define MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT__SHIFT             1
+static inline uint32_t MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(enum mdp4_cursor_format val)
+{
+       return ((val) << MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT__SHIFT) & MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT__MASK;
+}
+#define MDP4_DMA_CURSOR_BLEND_CONFIG_TRANSP_EN                 0x00000008
+
+static inline uint32_t REG_MDP4_DMA_CURSOR_BLEND_PARAM(enum mdp4_dma i0) { return 0x00000064 + __offset_DMA(i0); }
+
+static inline uint32_t REG_MDP4_DMA_BLEND_TRANS_LOW(enum mdp4_dma i0) { return 0x00000068 + __offset_DMA(i0); }
+
+static inline uint32_t REG_MDP4_DMA_BLEND_TRANS_HIGH(enum mdp4_dma i0) { return 0x0000006c + __offset_DMA(i0); }
+
+static inline uint32_t REG_MDP4_DMA_FETCH_CONFIG(enum mdp4_dma i0) { return 0x00001004 + __offset_DMA(i0); }
+
+static inline uint32_t REG_MDP4_DMA_CSC(enum mdp4_dma i0) { return 0x00003000 + __offset_DMA(i0); }
+
+
+static inline uint32_t REG_MDP4_DMA_CSC_MV(enum mdp4_dma i0, uint32_t i1) { return 0x00003400 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_MV_VAL(enum mdp4_dma i0, uint32_t i1) { return 0x00003400 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_PRE_BV(enum mdp4_dma i0, uint32_t i1) { return 0x00003500 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_PRE_BV_VAL(enum mdp4_dma i0, uint32_t i1) { return 0x00003500 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_POST_BV(enum mdp4_dma i0, uint32_t i1) { return 0x00003580 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_POST_BV_VAL(enum mdp4_dma i0, uint32_t i1) { return 0x00003580 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_PRE_LV(enum mdp4_dma i0, uint32_t i1) { return 0x00003600 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_PRE_LV_VAL(enum mdp4_dma i0, uint32_t i1) { return 0x00003600 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_POST_LV(enum mdp4_dma i0, uint32_t i1) { return 0x00003680 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_DMA_CSC_POST_LV_VAL(enum mdp4_dma i0, uint32_t i1) { return 0x00003680 + __offset_DMA(i0) + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE(enum mpd4_pipe i0) { return 0x00020000 + 0x10000*i0; }
+
+static inline uint32_t REG_MDP4_PIPE_SRC_SIZE(enum mpd4_pipe i0) { return 0x00020000 + 0x10000*i0; }
+#define MDP4_PIPE_SRC_SIZE_HEIGHT__MASK                                0xffff0000
+#define MDP4_PIPE_SRC_SIZE_HEIGHT__SHIFT                       16
+static inline uint32_t MDP4_PIPE_SRC_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_SIZE_HEIGHT__SHIFT) & MDP4_PIPE_SRC_SIZE_HEIGHT__MASK;
+}
+#define MDP4_PIPE_SRC_SIZE_WIDTH__MASK                         0x0000ffff
+#define MDP4_PIPE_SRC_SIZE_WIDTH__SHIFT                                0
+static inline uint32_t MDP4_PIPE_SRC_SIZE_WIDTH(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_SIZE_WIDTH__SHIFT) & MDP4_PIPE_SRC_SIZE_WIDTH__MASK;
+}
+
+static inline uint32_t REG_MDP4_PIPE_SRC_XY(enum mpd4_pipe i0) { return 0x00020004 + 0x10000*i0; }
+#define MDP4_PIPE_SRC_XY_Y__MASK                               0xffff0000
+#define MDP4_PIPE_SRC_XY_Y__SHIFT                              16
+static inline uint32_t MDP4_PIPE_SRC_XY_Y(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_XY_Y__SHIFT) & MDP4_PIPE_SRC_XY_Y__MASK;
+}
+#define MDP4_PIPE_SRC_XY_X__MASK                               0x0000ffff
+#define MDP4_PIPE_SRC_XY_X__SHIFT                              0
+static inline uint32_t MDP4_PIPE_SRC_XY_X(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_XY_X__SHIFT) & MDP4_PIPE_SRC_XY_X__MASK;
+}
+
+static inline uint32_t REG_MDP4_PIPE_DST_SIZE(enum mpd4_pipe i0) { return 0x00020008 + 0x10000*i0; }
+#define MDP4_PIPE_DST_SIZE_HEIGHT__MASK                                0xffff0000
+#define MDP4_PIPE_DST_SIZE_HEIGHT__SHIFT                       16
+static inline uint32_t MDP4_PIPE_DST_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_DST_SIZE_HEIGHT__SHIFT) & MDP4_PIPE_DST_SIZE_HEIGHT__MASK;
+}
+#define MDP4_PIPE_DST_SIZE_WIDTH__MASK                         0x0000ffff
+#define MDP4_PIPE_DST_SIZE_WIDTH__SHIFT                                0
+static inline uint32_t MDP4_PIPE_DST_SIZE_WIDTH(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_DST_SIZE_WIDTH__SHIFT) & MDP4_PIPE_DST_SIZE_WIDTH__MASK;
+}
+
+static inline uint32_t REG_MDP4_PIPE_DST_XY(enum mpd4_pipe i0) { return 0x0002000c + 0x10000*i0; }
+#define MDP4_PIPE_DST_XY_Y__MASK                               0xffff0000
+#define MDP4_PIPE_DST_XY_Y__SHIFT                              16
+static inline uint32_t MDP4_PIPE_DST_XY_Y(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_DST_XY_Y__SHIFT) & MDP4_PIPE_DST_XY_Y__MASK;
+}
+#define MDP4_PIPE_DST_XY_X__MASK                               0x0000ffff
+#define MDP4_PIPE_DST_XY_X__SHIFT                              0
+static inline uint32_t MDP4_PIPE_DST_XY_X(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_DST_XY_X__SHIFT) & MDP4_PIPE_DST_XY_X__MASK;
+}
+
+static inline uint32_t REG_MDP4_PIPE_SRCP0_BASE(enum mpd4_pipe i0) { return 0x00020010 + 0x10000*i0; }
+
+static inline uint32_t REG_MDP4_PIPE_SRCP1_BASE(enum mpd4_pipe i0) { return 0x00020014 + 0x10000*i0; }
+
+static inline uint32_t REG_MDP4_PIPE_SRCP2_BASE(enum mpd4_pipe i0) { return 0x00020018 + 0x10000*i0; }
+
+static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_A(enum mpd4_pipe i0) { return 0x00020040 + 0x10000*i0; }
+#define MDP4_PIPE_SRC_STRIDE_A_P0__MASK                                0x0000ffff
+#define MDP4_PIPE_SRC_STRIDE_A_P0__SHIFT                       0
+static inline uint32_t MDP4_PIPE_SRC_STRIDE_A_P0(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_STRIDE_A_P0__SHIFT) & MDP4_PIPE_SRC_STRIDE_A_P0__MASK;
+}
+#define MDP4_PIPE_SRC_STRIDE_A_P1__MASK                                0xffff0000
+#define MDP4_PIPE_SRC_STRIDE_A_P1__SHIFT                       16
+static inline uint32_t MDP4_PIPE_SRC_STRIDE_A_P1(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_STRIDE_A_P1__SHIFT) & MDP4_PIPE_SRC_STRIDE_A_P1__MASK;
+}
+
+static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_B(enum mpd4_pipe i0) { return 0x00020044 + 0x10000*i0; }
+#define MDP4_PIPE_SRC_STRIDE_B_P2__MASK                                0x0000ffff
+#define MDP4_PIPE_SRC_STRIDE_B_P2__SHIFT                       0
+static inline uint32_t MDP4_PIPE_SRC_STRIDE_B_P2(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_STRIDE_B_P2__SHIFT) & MDP4_PIPE_SRC_STRIDE_B_P2__MASK;
+}
+#define MDP4_PIPE_SRC_STRIDE_B_P3__MASK                                0xffff0000
+#define MDP4_PIPE_SRC_STRIDE_B_P3__SHIFT                       16
+static inline uint32_t MDP4_PIPE_SRC_STRIDE_B_P3(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_STRIDE_B_P3__SHIFT) & MDP4_PIPE_SRC_STRIDE_B_P3__MASK;
+}
+
+static inline uint32_t REG_MDP4_PIPE_FRAME_SIZE(enum mpd4_pipe i0) { return 0x00020048 + 0x10000*i0; }
+#define MDP4_PIPE_FRAME_SIZE_HEIGHT__MASK                      0xffff0000
+#define MDP4_PIPE_FRAME_SIZE_HEIGHT__SHIFT                     16
+static inline uint32_t MDP4_PIPE_FRAME_SIZE_HEIGHT(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_FRAME_SIZE_HEIGHT__SHIFT) & MDP4_PIPE_FRAME_SIZE_HEIGHT__MASK;
+}
+#define MDP4_PIPE_FRAME_SIZE_WIDTH__MASK                       0x0000ffff
+#define MDP4_PIPE_FRAME_SIZE_WIDTH__SHIFT                      0
+static inline uint32_t MDP4_PIPE_FRAME_SIZE_WIDTH(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_FRAME_SIZE_WIDTH__SHIFT) & MDP4_PIPE_FRAME_SIZE_WIDTH__MASK;
+}
+
+static inline uint32_t REG_MDP4_PIPE_SRC_FORMAT(enum mpd4_pipe i0) { return 0x00020050 + 0x10000*i0; }
+#define MDP4_PIPE_SRC_FORMAT_G_BPC__MASK                       0x00000003
+#define MDP4_PIPE_SRC_FORMAT_G_BPC__SHIFT                      0
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_G_BPC(enum mpd4_bpc val)
+{
+       return ((val) << MDP4_PIPE_SRC_FORMAT_G_BPC__SHIFT) & MDP4_PIPE_SRC_FORMAT_G_BPC__MASK;
+}
+#define MDP4_PIPE_SRC_FORMAT_B_BPC__MASK                       0x0000000c
+#define MDP4_PIPE_SRC_FORMAT_B_BPC__SHIFT                      2
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_B_BPC(enum mpd4_bpc val)
+{
+       return ((val) << MDP4_PIPE_SRC_FORMAT_B_BPC__SHIFT) & MDP4_PIPE_SRC_FORMAT_B_BPC__MASK;
+}
+#define MDP4_PIPE_SRC_FORMAT_R_BPC__MASK                       0x00000030
+#define MDP4_PIPE_SRC_FORMAT_R_BPC__SHIFT                      4
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_R_BPC(enum mpd4_bpc val)
+{
+       return ((val) << MDP4_PIPE_SRC_FORMAT_R_BPC__SHIFT) & MDP4_PIPE_SRC_FORMAT_R_BPC__MASK;
+}
+#define MDP4_PIPE_SRC_FORMAT_A_BPC__MASK                       0x000000c0
+#define MDP4_PIPE_SRC_FORMAT_A_BPC__SHIFT                      6
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_A_BPC(enum mpd4_bpc_alpha val)
+{
+       return ((val) << MDP4_PIPE_SRC_FORMAT_A_BPC__SHIFT) & MDP4_PIPE_SRC_FORMAT_A_BPC__MASK;
+}
+#define MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE                      0x00000100
+#define MDP4_PIPE_SRC_FORMAT_CPP__MASK                         0x00000600
+#define MDP4_PIPE_SRC_FORMAT_CPP__SHIFT                                9
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_CPP(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_FORMAT_CPP__SHIFT) & MDP4_PIPE_SRC_FORMAT_CPP__MASK;
+}
+#define MDP4_PIPE_SRC_FORMAT_ROTATED_90                                0x00001000
+#define MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT__MASK                        0x00006000
+#define MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT__SHIFT               13
+static inline uint32_t MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT__SHIFT) & MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT__MASK;
+}
+#define MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT                      0x00020000
+#define MDP4_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB                  0x00040000
+#define MDP4_PIPE_SRC_FORMAT_SOLID_FILL                                0x00400000
+
+static inline uint32_t REG_MDP4_PIPE_SRC_UNPACK(enum mpd4_pipe i0) { return 0x00020054 + 0x10000*i0; }
+#define MDP4_PIPE_SRC_UNPACK_ELEM0__MASK                       0x000000ff
+#define MDP4_PIPE_SRC_UNPACK_ELEM0__SHIFT                      0
+static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM0(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_UNPACK_ELEM0__SHIFT) & MDP4_PIPE_SRC_UNPACK_ELEM0__MASK;
+}
+#define MDP4_PIPE_SRC_UNPACK_ELEM1__MASK                       0x0000ff00
+#define MDP4_PIPE_SRC_UNPACK_ELEM1__SHIFT                      8
+static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM1(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_UNPACK_ELEM1__SHIFT) & MDP4_PIPE_SRC_UNPACK_ELEM1__MASK;
+}
+#define MDP4_PIPE_SRC_UNPACK_ELEM2__MASK                       0x00ff0000
+#define MDP4_PIPE_SRC_UNPACK_ELEM2__SHIFT                      16
+static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM2(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_UNPACK_ELEM2__SHIFT) & MDP4_PIPE_SRC_UNPACK_ELEM2__MASK;
+}
+#define MDP4_PIPE_SRC_UNPACK_ELEM3__MASK                       0xff000000
+#define MDP4_PIPE_SRC_UNPACK_ELEM3__SHIFT                      24
+static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM3(uint32_t val)
+{
+       return ((val) << MDP4_PIPE_SRC_UNPACK_ELEM3__SHIFT) & MDP4_PIPE_SRC_UNPACK_ELEM3__MASK;
+}
+
+static inline uint32_t REG_MDP4_PIPE_OP_MODE(enum mpd4_pipe i0) { return 0x00020058 + 0x10000*i0; }
+#define MDP4_PIPE_OP_MODE_SCALEX_EN                            0x00000001
+#define MDP4_PIPE_OP_MODE_SCALEY_EN                            0x00000002
+#define MDP4_PIPE_OP_MODE_SRC_YCBCR                            0x00000200
+#define MDP4_PIPE_OP_MODE_DST_YCBCR                            0x00000400
+#define MDP4_PIPE_OP_MODE_CSC_EN                               0x00000800
+#define MDP4_PIPE_OP_MODE_FLIP_LR                              0x00002000
+#define MDP4_PIPE_OP_MODE_FLIP_UD                              0x00004000
+#define MDP4_PIPE_OP_MODE_DITHER_EN                            0x00008000
+#define MDP4_PIPE_OP_MODE_IGC_LUT_EN                           0x00010000
+#define MDP4_PIPE_OP_MODE_DEINT_EN                             0x00040000
+#define MDP4_PIPE_OP_MODE_DEINT_ODD_REF                                0x00080000
+
+static inline uint32_t REG_MDP4_PIPE_PHASEX_STEP(enum mpd4_pipe i0) { return 0x0002005c + 0x10000*i0; }
+
+static inline uint32_t REG_MDP4_PIPE_PHASEY_STEP(enum mpd4_pipe i0) { return 0x00020060 + 0x10000*i0; }
+
+static inline uint32_t REG_MDP4_PIPE_FETCH_CONFIG(enum mpd4_pipe i0) { return 0x00021004 + 0x10000*i0; }
+
+static inline uint32_t REG_MDP4_PIPE_SOLID_COLOR(enum mpd4_pipe i0) { return 0x00021008 + 0x10000*i0; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC(enum mpd4_pipe i0) { return 0x00024000 + 0x10000*i0; }
+
+
+static inline uint32_t REG_MDP4_PIPE_CSC_MV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024400 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_MV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024400 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_PRE_BV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024500 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_PRE_BV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024500 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_POST_BV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024580 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_POST_BV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024580 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_PRE_LV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024600 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_PRE_LV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024600 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_POST_LV(enum mpd4_pipe i0, uint32_t i1) { return 0x00024680 + 0x10000*i0 + 0x4*i1; }
+
+static inline uint32_t REG_MDP4_PIPE_CSC_POST_LV_VAL(enum mpd4_pipe i0, uint32_t i1) { return 0x00024680 + 0x10000*i0 + 0x4*i1; }
+
+#define REG_MDP4_LCDC                                          0x000c0000
+
+#define REG_MDP4_LCDC_ENABLE                                   0x000c0000
+
+#define REG_MDP4_LCDC_HSYNC_CTRL                               0x000c0004
+#define MDP4_LCDC_HSYNC_CTRL_PULSEW__MASK                      0x0000ffff
+#define MDP4_LCDC_HSYNC_CTRL_PULSEW__SHIFT                     0
+static inline uint32_t MDP4_LCDC_HSYNC_CTRL_PULSEW(uint32_t val)
+{
+       return ((val) << MDP4_LCDC_HSYNC_CTRL_PULSEW__SHIFT) & MDP4_LCDC_HSYNC_CTRL_PULSEW__MASK;
+}
+#define MDP4_LCDC_HSYNC_CTRL_PERIOD__MASK                      0xffff0000
+#define MDP4_LCDC_HSYNC_CTRL_PERIOD__SHIFT                     16
+static inline uint32_t MDP4_LCDC_HSYNC_CTRL_PERIOD(uint32_t val)
+{
+       return ((val) << MDP4_LCDC_HSYNC_CTRL_PERIOD__SHIFT) & MDP4_LCDC_HSYNC_CTRL_PERIOD__MASK;
+}
+
+#define REG_MDP4_LCDC_VSYNC_PERIOD                             0x000c0008
+
+#define REG_MDP4_LCDC_VSYNC_LEN                                        0x000c000c
+
+#define REG_MDP4_LCDC_DISPLAY_HCTRL                            0x000c0010
+#define MDP4_LCDC_DISPLAY_HCTRL_START__MASK                    0x0000ffff
+#define MDP4_LCDC_DISPLAY_HCTRL_START__SHIFT                   0
+static inline uint32_t MDP4_LCDC_DISPLAY_HCTRL_START(uint32_t val)
+{
+       return ((val) << MDP4_LCDC_DISPLAY_HCTRL_START__SHIFT) & MDP4_LCDC_DISPLAY_HCTRL_START__MASK;
+}
+#define MDP4_LCDC_DISPLAY_HCTRL_END__MASK                      0xffff0000
+#define MDP4_LCDC_DISPLAY_HCTRL_END__SHIFT                     16
+static inline uint32_t MDP4_LCDC_DISPLAY_HCTRL_END(uint32_t val)
+{
+       return ((val) << MDP4_LCDC_DISPLAY_HCTRL_END__SHIFT) & MDP4_LCDC_DISPLAY_HCTRL_END__MASK;
+}
+
+#define REG_MDP4_LCDC_DISPLAY_VSTART                           0x000c0014
+
+#define REG_MDP4_LCDC_DISPLAY_VEND                             0x000c0018
+
+#define REG_MDP4_LCDC_ACTIVE_HCTL                              0x000c001c
+#define MDP4_LCDC_ACTIVE_HCTL_START__MASK                      0x00007fff
+#define MDP4_LCDC_ACTIVE_HCTL_START__SHIFT                     0
+static inline uint32_t MDP4_LCDC_ACTIVE_HCTL_START(uint32_t val)
+{
+       return ((val) << MDP4_LCDC_ACTIVE_HCTL_START__SHIFT) & MDP4_LCDC_ACTIVE_HCTL_START__MASK;
+}
+#define MDP4_LCDC_ACTIVE_HCTL_END__MASK                                0x7fff0000
+#define MDP4_LCDC_ACTIVE_HCTL_END__SHIFT                       16
+static inline uint32_t MDP4_LCDC_ACTIVE_HCTL_END(uint32_t val)
+{
+       return ((val) << MDP4_LCDC_ACTIVE_HCTL_END__SHIFT) & MDP4_LCDC_ACTIVE_HCTL_END__MASK;
+}
+#define MDP4_LCDC_ACTIVE_HCTL_ACTIVE_START_X                   0x80000000
+
+#define REG_MDP4_LCDC_ACTIVE_VSTART                            0x000c0020
+
+#define REG_MDP4_LCDC_ACTIVE_VEND                              0x000c0024
+
+#define REG_MDP4_LCDC_BORDER_CLR                               0x000c0028
+
+#define REG_MDP4_LCDC_UNDERFLOW_CLR                            0x000c002c
+#define MDP4_LCDC_UNDERFLOW_CLR_COLOR__MASK                    0x00ffffff
+#define MDP4_LCDC_UNDERFLOW_CLR_COLOR__SHIFT                   0
+static inline uint32_t MDP4_LCDC_UNDERFLOW_CLR_COLOR(uint32_t val)
+{
+       return ((val) << MDP4_LCDC_UNDERFLOW_CLR_COLOR__SHIFT) & MDP4_LCDC_UNDERFLOW_CLR_COLOR__MASK;
+}
+#define MDP4_LCDC_UNDERFLOW_CLR_ENABLE_RECOVERY                        0x80000000
+
+#define REG_MDP4_LCDC_HSYNC_SKEW                               0x000c0030
+
+#define REG_MDP4_LCDC_TEST_CNTL                                        0x000c0034
+
+#define REG_MDP4_LCDC_CTRL_POLARITY                            0x000c0038
+#define MDP4_LCDC_CTRL_POLARITY_HSYNC_LOW                      0x00000001
+#define MDP4_LCDC_CTRL_POLARITY_VSYNC_LOW                      0x00000002
+#define MDP4_LCDC_CTRL_POLARITY_DATA_EN_LOW                    0x00000004
+
+#define REG_MDP4_DTV                                           0x000d0000
+
+#define REG_MDP4_DTV_ENABLE                                    0x000d0000
+
+#define REG_MDP4_DTV_HSYNC_CTRL                                        0x000d0004
+#define MDP4_DTV_HSYNC_CTRL_PULSEW__MASK                       0x0000ffff
+#define MDP4_DTV_HSYNC_CTRL_PULSEW__SHIFT                      0
+static inline uint32_t MDP4_DTV_HSYNC_CTRL_PULSEW(uint32_t val)
+{
+       return ((val) << MDP4_DTV_HSYNC_CTRL_PULSEW__SHIFT) & MDP4_DTV_HSYNC_CTRL_PULSEW__MASK;
+}
+#define MDP4_DTV_HSYNC_CTRL_PERIOD__MASK                       0xffff0000
+#define MDP4_DTV_HSYNC_CTRL_PERIOD__SHIFT                      16
+static inline uint32_t MDP4_DTV_HSYNC_CTRL_PERIOD(uint32_t val)
+{
+       return ((val) << MDP4_DTV_HSYNC_CTRL_PERIOD__SHIFT) & MDP4_DTV_HSYNC_CTRL_PERIOD__MASK;
+}
+
+#define REG_MDP4_DTV_VSYNC_PERIOD                              0x000d0008
+
+#define REG_MDP4_DTV_VSYNC_LEN                                 0x000d000c
+
+#define REG_MDP4_DTV_DISPLAY_HCTRL                             0x000d0018
+#define MDP4_DTV_DISPLAY_HCTRL_START__MASK                     0x0000ffff
+#define MDP4_DTV_DISPLAY_HCTRL_START__SHIFT                    0
+static inline uint32_t MDP4_DTV_DISPLAY_HCTRL_START(uint32_t val)
+{
+       return ((val) << MDP4_DTV_DISPLAY_HCTRL_START__SHIFT) & MDP4_DTV_DISPLAY_HCTRL_START__MASK;
+}
+#define MDP4_DTV_DISPLAY_HCTRL_END__MASK                       0xffff0000
+#define MDP4_DTV_DISPLAY_HCTRL_END__SHIFT                      16
+static inline uint32_t MDP4_DTV_DISPLAY_HCTRL_END(uint32_t val)
+{
+       return ((val) << MDP4_DTV_DISPLAY_HCTRL_END__SHIFT) & MDP4_DTV_DISPLAY_HCTRL_END__MASK;
+}
+
+#define REG_MDP4_DTV_DISPLAY_VSTART                            0x000d001c
+
+#define REG_MDP4_DTV_DISPLAY_VEND                              0x000d0020
+
+#define REG_MDP4_DTV_ACTIVE_HCTL                               0x000d002c
+#define MDP4_DTV_ACTIVE_HCTL_START__MASK                       0x00007fff
+#define MDP4_DTV_ACTIVE_HCTL_START__SHIFT                      0
+static inline uint32_t MDP4_DTV_ACTIVE_HCTL_START(uint32_t val)
+{
+       return ((val) << MDP4_DTV_ACTIVE_HCTL_START__SHIFT) & MDP4_DTV_ACTIVE_HCTL_START__MASK;
+}
+#define MDP4_DTV_ACTIVE_HCTL_END__MASK                         0x7fff0000
+#define MDP4_DTV_ACTIVE_HCTL_END__SHIFT                                16
+static inline uint32_t MDP4_DTV_ACTIVE_HCTL_END(uint32_t val)
+{
+       return ((val) << MDP4_DTV_ACTIVE_HCTL_END__SHIFT) & MDP4_DTV_ACTIVE_HCTL_END__MASK;
+}
+#define MDP4_DTV_ACTIVE_HCTL_ACTIVE_START_X                    0x80000000
+
+#define REG_MDP4_DTV_ACTIVE_VSTART                             0x000d0030
+
+#define REG_MDP4_DTV_ACTIVE_VEND                               0x000d0038
+
+#define REG_MDP4_DTV_BORDER_CLR                                        0x000d0040
+
+#define REG_MDP4_DTV_UNDERFLOW_CLR                             0x000d0044
+#define MDP4_DTV_UNDERFLOW_CLR_COLOR__MASK                     0x00ffffff
+#define MDP4_DTV_UNDERFLOW_CLR_COLOR__SHIFT                    0
+static inline uint32_t MDP4_DTV_UNDERFLOW_CLR_COLOR(uint32_t val)
+{
+       return ((val) << MDP4_DTV_UNDERFLOW_CLR_COLOR__SHIFT) & MDP4_DTV_UNDERFLOW_CLR_COLOR__MASK;
+}
+#define MDP4_DTV_UNDERFLOW_CLR_ENABLE_RECOVERY                 0x80000000
+
+#define REG_MDP4_DTV_HSYNC_SKEW                                        0x000d0048
+
+#define REG_MDP4_DTV_TEST_CNTL                                 0x000d004c
+
+#define REG_MDP4_DTV_CTRL_POLARITY                             0x000d0050
+#define MDP4_DTV_CTRL_POLARITY_HSYNC_LOW                       0x00000001
+#define MDP4_DTV_CTRL_POLARITY_VSYNC_LOW                       0x00000002
+#define MDP4_DTV_CTRL_POLARITY_DATA_EN_LOW                     0x00000004
+
+#define REG_MDP4_DSI                                           0x000e0000
+
+#define REG_MDP4_DSI_ENABLE                                    0x000e0000
+
+#define REG_MDP4_DSI_HSYNC_CTRL                                        0x000e0004
+#define MDP4_DSI_HSYNC_CTRL_PULSEW__MASK                       0x0000ffff
+#define MDP4_DSI_HSYNC_CTRL_PULSEW__SHIFT                      0
+static inline uint32_t MDP4_DSI_HSYNC_CTRL_PULSEW(uint32_t val)
+{
+       return ((val) << MDP4_DSI_HSYNC_CTRL_PULSEW__SHIFT) & MDP4_DSI_HSYNC_CTRL_PULSEW__MASK;
+}
+#define MDP4_DSI_HSYNC_CTRL_PERIOD__MASK                       0xffff0000
+#define MDP4_DSI_HSYNC_CTRL_PERIOD__SHIFT                      16
+static inline uint32_t MDP4_DSI_HSYNC_CTRL_PERIOD(uint32_t val)
+{
+       return ((val) << MDP4_DSI_HSYNC_CTRL_PERIOD__SHIFT) & MDP4_DSI_HSYNC_CTRL_PERIOD__MASK;
+}
+
+#define REG_MDP4_DSI_VSYNC_PERIOD                              0x000e0008
+
+#define REG_MDP4_DSI_VSYNC_LEN                                 0x000e000c
+
+#define REG_MDP4_DSI_DISPLAY_HCTRL                             0x000e0010
+#define MDP4_DSI_DISPLAY_HCTRL_START__MASK                     0x0000ffff
+#define MDP4_DSI_DISPLAY_HCTRL_START__SHIFT                    0
+static inline uint32_t MDP4_DSI_DISPLAY_HCTRL_START(uint32_t val)
+{
+       return ((val) << MDP4_DSI_DISPLAY_HCTRL_START__SHIFT) & MDP4_DSI_DISPLAY_HCTRL_START__MASK;
+}
+#define MDP4_DSI_DISPLAY_HCTRL_END__MASK                       0xffff0000
+#define MDP4_DSI_DISPLAY_HCTRL_END__SHIFT                      16
+static inline uint32_t MDP4_DSI_DISPLAY_HCTRL_END(uint32_t val)
+{
+       return ((val) << MDP4_DSI_DISPLAY_HCTRL_END__SHIFT) & MDP4_DSI_DISPLAY_HCTRL_END__MASK;
+}
+
+#define REG_MDP4_DSI_DISPLAY_VSTART                            0x000e0014
+
+#define REG_MDP4_DSI_DISPLAY_VEND                              0x000e0018
+
+#define REG_MDP4_DSI_ACTIVE_HCTL                               0x000e001c
+#define MDP4_DSI_ACTIVE_HCTL_START__MASK                       0x00007fff
+#define MDP4_DSI_ACTIVE_HCTL_START__SHIFT                      0
+static inline uint32_t MDP4_DSI_ACTIVE_HCTL_START(uint32_t val)
+{
+       return ((val) << MDP4_DSI_ACTIVE_HCTL_START__SHIFT) & MDP4_DSI_ACTIVE_HCTL_START__MASK;
+}
+#define MDP4_DSI_ACTIVE_HCTL_END__MASK                         0x7fff0000
+#define MDP4_DSI_ACTIVE_HCTL_END__SHIFT                                16
+static inline uint32_t MDP4_DSI_ACTIVE_HCTL_END(uint32_t val)
+{
+       return ((val) << MDP4_DSI_ACTIVE_HCTL_END__SHIFT) & MDP4_DSI_ACTIVE_HCTL_END__MASK;
+}
+#define MDP4_DSI_ACTIVE_HCTL_ACTIVE_START_X                    0x80000000
+
+#define REG_MDP4_DSI_ACTIVE_VSTART                             0x000e0020
+
+#define REG_MDP4_DSI_ACTIVE_VEND                               0x000e0024
+
+#define REG_MDP4_DSI_BORDER_CLR                                        0x000e0028
+
+#define REG_MDP4_DSI_UNDERFLOW_CLR                             0x000e002c
+#define MDP4_DSI_UNDERFLOW_CLR_COLOR__MASK                     0x00ffffff
+#define MDP4_DSI_UNDERFLOW_CLR_COLOR__SHIFT                    0
+static inline uint32_t MDP4_DSI_UNDERFLOW_CLR_COLOR(uint32_t val)
+{
+       return ((val) << MDP4_DSI_UNDERFLOW_CLR_COLOR__SHIFT) & MDP4_DSI_UNDERFLOW_CLR_COLOR__MASK;
+}
+#define MDP4_DSI_UNDERFLOW_CLR_ENABLE_RECOVERY                 0x80000000
+
+#define REG_MDP4_DSI_HSYNC_SKEW                                        0x000e0030
+
+#define REG_MDP4_DSI_TEST_CNTL                                 0x000e0034
+
+#define REG_MDP4_DSI_CTRL_POLARITY                             0x000e0038
+#define MDP4_DSI_CTRL_POLARITY_HSYNC_LOW                       0x00000001
+#define MDP4_DSI_CTRL_POLARITY_VSYNC_LOW                       0x00000002
+#define MDP4_DSI_CTRL_POLARITY_DATA_EN_LOW                     0x00000004
+
+
+#endif /* MDP4_XML */
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp4/mdp4_crtc.c
new file mode 100644 (file)
index 0000000..bda0fc4
--- /dev/null
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mdp4_kms.h"
+
+#include <drm/drm_mode.h>
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+#include "drm_flip_work.h"
+
+struct mdp4_crtc {
+       struct drm_crtc base;
+       char name[8];
+       struct drm_plane *plane;
+       int id;
+       int ovlp;
+       enum mdp4_dma dma;
+       bool enabled;
+
+       /* which mixer/encoder we route output to: */
+       int mixer;
+
+       struct {
+               spinlock_t lock;
+               bool stale;
+               uint32_t width, height;
+
+               /* next cursor to scan-out: */
+               uint32_t next_iova;
+               struct drm_gem_object *next_bo;
+
+               /* current cursor being scanned out: */
+               struct drm_gem_object *scanout_bo;
+       } cursor;
+
+
+       /* if there is a pending flip, these will be non-null: */
+       struct drm_pending_vblank_event *event;
+       struct work_struct pageflip_work;
+
+       /* the fb that we currently hold a scanout ref to: */
+       struct drm_framebuffer *fb;
+
+       /* for unref'ing framebuffers after scanout completes: */
+       struct drm_flip_work unref_fb_work;
+
+       /* for unref'ing cursor bo's after scanout completes: */
+       struct drm_flip_work unref_cursor_work;
+
+       struct mdp4_irq vblank;
+       struct mdp4_irq err;
+};
+#define to_mdp4_crtc(x) container_of(x, struct mdp4_crtc, base)
+
+static struct mdp4_kms *get_kms(struct drm_crtc *crtc)
+{
+       struct msm_drm_private *priv = crtc->dev->dev_private;
+       return to_mdp4_kms(priv->kms);
+}
+
+static void update_fb(struct drm_crtc *crtc, bool async,
+               struct drm_framebuffer *new_fb)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct drm_framebuffer *old_fb = mdp4_crtc->fb;
+
+       if (old_fb)
+               drm_flip_work_queue(&mdp4_crtc->unref_fb_work, old_fb);
+
+       /* grab reference to incoming scanout fb: */
+       drm_framebuffer_reference(new_fb);
+       mdp4_crtc->base.fb = new_fb;
+       mdp4_crtc->fb = new_fb;
+
+       if (!async) {
+               /* enable vblank to pick up the old_fb */
+               mdp4_irq_register(get_kms(crtc), &mdp4_crtc->vblank);
+       }
+}
+
+static void complete_flip(struct drm_crtc *crtc, bool canceled)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct drm_pending_vblank_event *event;
+       unsigned long flags;
+
+       spin_lock_irqsave(&dev->event_lock, flags);
+       event = mdp4_crtc->event;
+       if (event) {
+               mdp4_crtc->event = NULL;
+               if (canceled)
+                       event->base.destroy(&event->base);
+               else
+                       drm_send_vblank_event(dev, mdp4_crtc->id, event);
+       }
+       spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static void crtc_flush(struct drm_crtc *crtc)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct mdp4_kms *mdp4_kms = get_kms(crtc);
+       uint32_t flush = 0;
+
+       flush |= pipe2flush(mdp4_plane_pipe(mdp4_crtc->plane));
+       flush |= ovlp2flush(mdp4_crtc->ovlp);
+
+       DBG("%s: flush=%08x", mdp4_crtc->name, flush);
+
+       mdp4_write(mdp4_kms, REG_MDP4_OVERLAY_FLUSH, flush);
+}
+
+static void pageflip_worker(struct work_struct *work)
+{
+       struct mdp4_crtc *mdp4_crtc =
+               container_of(work, struct mdp4_crtc, pageflip_work);
+       struct drm_crtc *crtc = &mdp4_crtc->base;
+
+       mdp4_plane_set_scanout(mdp4_crtc->plane, crtc->fb);
+       crtc_flush(crtc);
+
+       /* enable vblank to complete flip: */
+       mdp4_irq_register(get_kms(crtc), &mdp4_crtc->vblank);
+}
+
+static void unref_fb_worker(struct drm_flip_work *work, void *val)
+{
+       struct mdp4_crtc *mdp4_crtc =
+               container_of(work, struct mdp4_crtc, unref_fb_work);
+       struct drm_device *dev = mdp4_crtc->base.dev;
+
+       mutex_lock(&dev->mode_config.mutex);
+       drm_framebuffer_unreference(val);
+       mutex_unlock(&dev->mode_config.mutex);
+}
+
+static void unref_cursor_worker(struct drm_flip_work *work, void *val)
+{
+       struct mdp4_crtc *mdp4_crtc =
+               container_of(work, struct mdp4_crtc, unref_cursor_work);
+       struct mdp4_kms *mdp4_kms = get_kms(&mdp4_crtc->base);
+
+       msm_gem_put_iova(val, mdp4_kms->id);
+       drm_gem_object_unreference_unlocked(val);
+}
+
+static void mdp4_crtc_destroy(struct drm_crtc *crtc)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+
+       mdp4_crtc->plane->funcs->destroy(mdp4_crtc->plane);
+
+       drm_crtc_cleanup(crtc);
+       drm_flip_work_cleanup(&mdp4_crtc->unref_fb_work);
+       drm_flip_work_cleanup(&mdp4_crtc->unref_cursor_work);
+
+       kfree(mdp4_crtc);
+}
+
+static void mdp4_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct mdp4_kms *mdp4_kms = get_kms(crtc);
+       bool enabled = (mode == DRM_MODE_DPMS_ON);
+
+       DBG("%s: mode=%d", mdp4_crtc->name, mode);
+
+       if (enabled != mdp4_crtc->enabled) {
+               if (enabled) {
+                       mdp4_enable(mdp4_kms);
+                       mdp4_irq_register(mdp4_kms, &mdp4_crtc->err);
+               } else {
+                       mdp4_irq_unregister(mdp4_kms, &mdp4_crtc->err);
+                       mdp4_disable(mdp4_kms);
+               }
+               mdp4_crtc->enabled = enabled;
+       }
+}
+
+static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc,
+               const struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void blend_setup(struct drm_crtc *crtc)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct mdp4_kms *mdp4_kms = get_kms(crtc);
+       int i, ovlp = mdp4_crtc->ovlp;
+       uint32_t mixer_cfg = 0;
+
+       /*
+        * This probably would also need to be triggered by any attached
+        * plane when it changes.. for now since we are only using a single
+        * private plane, the configuration is hard-coded:
+        */
+
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW0(ovlp), 0);
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_LOW1(ovlp), 0);
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH0(ovlp), 0);
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_TRANSP_HIGH1(ovlp), 0);
+
+       for (i = 0; i < 4; i++) {
+               mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_FG_ALPHA(ovlp, i), 0);
+               mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_BG_ALPHA(ovlp, i), 0);
+               mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_OP(ovlp, i),
+                               MDP4_OVLP_STAGE_OP_FG_ALPHA(FG_CONST) |
+                               MDP4_OVLP_STAGE_OP_BG_ALPHA(BG_CONST));
+               mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_CO3(ovlp, i), 0);
+               mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW0(ovlp, i), 0);
+               mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_LOW1(ovlp, i), 0);
+               mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH0(ovlp, i), 0);
+               mdp4_write(mdp4_kms, REG_MDP4_OVLP_STAGE_TRANSP_HIGH1(ovlp, i), 0);
+       }
+
+       /* TODO single register for all CRTCs, so this won't work properly
+        * when multiple CRTCs are active..
+        */
+       switch (mdp4_plane_pipe(mdp4_crtc->plane)) {
+       case VG1:
+               mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE0(STAGE_BASE) |
+                       COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
+               break;
+       case VG2:
+               mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE1(STAGE_BASE) |
+                       COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
+               break;
+       case RGB1:
+               mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE2(STAGE_BASE) |
+                       COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
+               break;
+       case RGB2:
+               mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE3(STAGE_BASE) |
+                       COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
+               break;
+       case RGB3:
+               mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE4(STAGE_BASE) |
+                       COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
+               break;
+       case VG3:
+               mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE5(STAGE_BASE) |
+                       COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
+               break;
+       case VG4:
+               mixer_cfg = MDP4_LAYERMIXER_IN_CFG_PIPE6(STAGE_BASE) |
+                       COND(mdp4_crtc->mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
+               break;
+       default:
+               WARN_ON("invalid pipe");
+               break;
+       }
+       mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG, mixer_cfg);
+}
+
+static int mdp4_crtc_mode_set(struct drm_crtc *crtc,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode,
+               int x, int y,
+               struct drm_framebuffer *old_fb)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct mdp4_kms *mdp4_kms = get_kms(crtc);
+       enum mdp4_dma dma = mdp4_crtc->dma;
+       int ret, ovlp = mdp4_crtc->ovlp;
+
+       mode = adjusted_mode;
+
+       DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
+                       mdp4_crtc->name, mode->base.id, mode->name,
+                       mode->vrefresh, mode->clock,
+                       mode->hdisplay, mode->hsync_start,
+                       mode->hsync_end, mode->htotal,
+                       mode->vdisplay, mode->vsync_start,
+                       mode->vsync_end, mode->vtotal,
+                       mode->type, mode->flags);
+
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_SIZE(dma),
+                       MDP4_DMA_SRC_SIZE_WIDTH(mode->hdisplay) |
+                       MDP4_DMA_SRC_SIZE_HEIGHT(mode->vdisplay));
+
+       /* take data from pipe: */
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_BASE(dma), 0);
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_SRC_STRIDE(dma),
+                       crtc->fb->pitches[0]);
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_DST_SIZE(dma),
+                       MDP4_DMA_DST_SIZE_WIDTH(0) |
+                       MDP4_DMA_DST_SIZE_HEIGHT(0));
+
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_BASE(ovlp), 0);
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_SIZE(ovlp),
+                       MDP4_OVLP_SIZE_WIDTH(mode->hdisplay) |
+                       MDP4_OVLP_SIZE_HEIGHT(mode->vdisplay));
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_STRIDE(ovlp),
+                       crtc->fb->pitches[0]);
+
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_CFG(ovlp), 1);
+
+       update_fb(crtc, false, crtc->fb);
+
+       ret = mdp4_plane_mode_set(mdp4_crtc->plane, crtc, crtc->fb,
+                       0, 0, mode->hdisplay, mode->vdisplay,
+                       x << 16, y << 16,
+                       mode->hdisplay << 16, mode->vdisplay << 16);
+       if (ret) {
+               dev_err(crtc->dev->dev, "%s: failed to set mode on plane: %d\n",
+                               mdp4_crtc->name, ret);
+               return ret;
+       }
+
+       if (dma == DMA_E) {
+               mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(0), 0x00ff0000);
+               mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(1), 0x00ff0000);
+               mdp4_write(mdp4_kms, REG_MDP4_DMA_E_QUANT(2), 0x00ff0000);
+       }
+
+       return 0;
+}
+
+static void mdp4_crtc_prepare(struct drm_crtc *crtc)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       DBG("%s", mdp4_crtc->name);
+       /* make sure we hold a ref to mdp clks while setting up mode: */
+       mdp4_enable(get_kms(crtc));
+       mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void mdp4_crtc_commit(struct drm_crtc *crtc)
+{
+       mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
+       crtc_flush(crtc);
+       /* drop the ref to mdp clk's that we got in prepare: */
+       mdp4_disable(get_kms(crtc));
+}
+
+static int mdp4_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
+               struct drm_framebuffer *old_fb)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct drm_plane *plane = mdp4_crtc->plane;
+       struct drm_display_mode *mode = &crtc->mode;
+
+       update_fb(crtc, false, crtc->fb);
+
+       return mdp4_plane_mode_set(plane, crtc, crtc->fb,
+                       0, 0, mode->hdisplay, mode->vdisplay,
+                       x << 16, y << 16,
+                       mode->hdisplay << 16, mode->vdisplay << 16);
+}
+
+static void mdp4_crtc_load_lut(struct drm_crtc *crtc)
+{
+}
+
+static int mdp4_crtc_page_flip(struct drm_crtc *crtc,
+               struct drm_framebuffer *new_fb,
+               struct drm_pending_vblank_event *event)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct drm_gem_object *obj;
+
+       if (mdp4_crtc->event) {
+               dev_err(dev->dev, "already pending flip!\n");
+               return -EBUSY;
+       }
+
+       obj = msm_framebuffer_bo(new_fb, 0);
+
+       mdp4_crtc->event = event;
+       update_fb(crtc, true, new_fb);
+
+       return msm_gem_queue_inactive_work(obj,
+                       &mdp4_crtc->pageflip_work);
+}
+
+static int mdp4_crtc_set_property(struct drm_crtc *crtc,
+               struct drm_property *property, uint64_t val)
+{
+       // XXX
+       return -EINVAL;
+}
+
+#define CURSOR_WIDTH 64
+#define CURSOR_HEIGHT 64
+
+/* called from IRQ to update cursor related registers (if needed).  The
+ * cursor registers, other than x/y position, appear not to be double
+ * buffered, and changing them other than from vblank seems to trigger
+ * underflow.
+ */
+static void update_cursor(struct drm_crtc *crtc)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       enum mdp4_dma dma = mdp4_crtc->dma;
+       unsigned long flags;
+
+       spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
+       if (mdp4_crtc->cursor.stale) {
+               struct mdp4_kms *mdp4_kms = get_kms(crtc);
+               struct drm_gem_object *next_bo = mdp4_crtc->cursor.next_bo;
+               struct drm_gem_object *prev_bo = mdp4_crtc->cursor.scanout_bo;
+               uint32_t iova = mdp4_crtc->cursor.next_iova;
+
+               if (next_bo) {
+                       /* take a obj ref + iova ref when we start scanning out: */
+                       drm_gem_object_reference(next_bo);
+                       msm_gem_get_iova_locked(next_bo, mdp4_kms->id, &iova);
+
+                       /* enable cursor: */
+                       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_SIZE(dma),
+                                       MDP4_DMA_CURSOR_SIZE_WIDTH(mdp4_crtc->cursor.width) |
+                                       MDP4_DMA_CURSOR_SIZE_HEIGHT(mdp4_crtc->cursor.height));
+                       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), iova);
+                       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma),
+                                       MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB) |
+                                       MDP4_DMA_CURSOR_BLEND_CONFIG_CURSOR_EN);
+               } else {
+                       /* disable cursor: */
+                       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BASE(dma), 0);
+                       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_BLEND_CONFIG(dma),
+                                       MDP4_DMA_CURSOR_BLEND_CONFIG_FORMAT(CURSOR_ARGB));
+               }
+
+               /* and drop the iova ref + obj rev when done scanning out: */
+               if (prev_bo)
+                       drm_flip_work_queue(&mdp4_crtc->unref_cursor_work, prev_bo);
+
+               mdp4_crtc->cursor.scanout_bo = next_bo;
+               mdp4_crtc->cursor.stale = false;
+       }
+       spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
+}
+
+static int mdp4_crtc_cursor_set(struct drm_crtc *crtc,
+               struct drm_file *file_priv, uint32_t handle,
+               uint32_t width, uint32_t height)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct mdp4_kms *mdp4_kms = get_kms(crtc);
+       struct drm_device *dev = crtc->dev;
+       struct drm_gem_object *cursor_bo, *old_bo;
+       unsigned long flags;
+       uint32_t iova;
+       int ret;
+
+       if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) {
+               dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height);
+               return -EINVAL;
+       }
+
+       if (handle) {
+               cursor_bo = drm_gem_object_lookup(dev, file_priv, handle);
+               if (!cursor_bo)
+                       return -ENOENT;
+       } else {
+               cursor_bo = NULL;
+       }
+
+       if (cursor_bo) {
+               ret = msm_gem_get_iova(cursor_bo, mdp4_kms->id, &iova);
+               if (ret)
+                       goto fail;
+       } else {
+               iova = 0;
+       }
+
+       spin_lock_irqsave(&mdp4_crtc->cursor.lock, flags);
+       old_bo = mdp4_crtc->cursor.next_bo;
+       mdp4_crtc->cursor.next_bo   = cursor_bo;
+       mdp4_crtc->cursor.next_iova = iova;
+       mdp4_crtc->cursor.width     = width;
+       mdp4_crtc->cursor.height    = height;
+       mdp4_crtc->cursor.stale     = true;
+       spin_unlock_irqrestore(&mdp4_crtc->cursor.lock, flags);
+
+       if (old_bo) {
+               /* drop our previous reference: */
+               msm_gem_put_iova(old_bo, mdp4_kms->id);
+               drm_gem_object_unreference_unlocked(old_bo);
+       }
+
+       return 0;
+
+fail:
+       drm_gem_object_unreference_unlocked(cursor_bo);
+       return ret;
+}
+
+static int mdp4_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct mdp4_kms *mdp4_kms = get_kms(crtc);
+       enum mdp4_dma dma = mdp4_crtc->dma;
+
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_CURSOR_POS(dma),
+                       MDP4_DMA_CURSOR_POS_X(x) |
+                       MDP4_DMA_CURSOR_POS_Y(y));
+
+       return 0;
+}
+
+static const struct drm_crtc_funcs mdp4_crtc_funcs = {
+       .set_config = drm_crtc_helper_set_config,
+       .destroy = mdp4_crtc_destroy,
+       .page_flip = mdp4_crtc_page_flip,
+       .set_property = mdp4_crtc_set_property,
+       .cursor_set = mdp4_crtc_cursor_set,
+       .cursor_move = mdp4_crtc_cursor_move,
+};
+
+static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = {
+       .dpms = mdp4_crtc_dpms,
+       .mode_fixup = mdp4_crtc_mode_fixup,
+       .mode_set = mdp4_crtc_mode_set,
+       .prepare = mdp4_crtc_prepare,
+       .commit = mdp4_crtc_commit,
+       .mode_set_base = mdp4_crtc_mode_set_base,
+       .load_lut = mdp4_crtc_load_lut,
+};
+
+static void mdp4_crtc_vblank_irq(struct mdp4_irq *irq, uint32_t irqstatus)
+{
+       struct mdp4_crtc *mdp4_crtc = container_of(irq, struct mdp4_crtc, vblank);
+       struct drm_crtc *crtc = &mdp4_crtc->base;
+       struct msm_drm_private *priv = crtc->dev->dev_private;
+
+       update_cursor(crtc);
+       complete_flip(crtc, false);
+       mdp4_irq_unregister(get_kms(crtc), &mdp4_crtc->vblank);
+
+       drm_flip_work_commit(&mdp4_crtc->unref_fb_work, priv->wq);
+       drm_flip_work_commit(&mdp4_crtc->unref_cursor_work, priv->wq);
+}
+
+static void mdp4_crtc_err_irq(struct mdp4_irq *irq, uint32_t irqstatus)
+{
+       struct mdp4_crtc *mdp4_crtc = container_of(irq, struct mdp4_crtc, err);
+       struct drm_crtc *crtc = &mdp4_crtc->base;
+       DBG("%s: error: %08x", mdp4_crtc->name, irqstatus);
+       crtc_flush(crtc);
+}
+
+uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       return mdp4_crtc->vblank.irqmask;
+}
+
+void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc)
+{
+       complete_flip(crtc, true);
+}
+
+/* set dma config, ie. the format the encoder wants. */
+void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct mdp4_kms *mdp4_kms = get_kms(crtc);
+
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_CONFIG(mdp4_crtc->dma), config);
+}
+
+/* set interface for routing crtc->encoder: */
+void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf)
+{
+       struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc);
+       struct mdp4_kms *mdp4_kms = get_kms(crtc);
+       uint32_t intf_sel;
+
+       intf_sel = mdp4_read(mdp4_kms, REG_MDP4_DISP_INTF_SEL);
+
+       switch (mdp4_crtc->dma) {
+       case DMA_P:
+               intf_sel &= ~MDP4_DISP_INTF_SEL_PRIM__MASK;
+               intf_sel |= MDP4_DISP_INTF_SEL_PRIM(intf);
+               break;
+       case DMA_S:
+               intf_sel &= ~MDP4_DISP_INTF_SEL_SEC__MASK;
+               intf_sel |= MDP4_DISP_INTF_SEL_SEC(intf);
+               break;
+       case DMA_E:
+               intf_sel &= ~MDP4_DISP_INTF_SEL_EXT__MASK;
+               intf_sel |= MDP4_DISP_INTF_SEL_EXT(intf);
+               break;
+       }
+
+       if (intf == INTF_DSI_VIDEO) {
+               intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_CMD;
+               intf_sel |= MDP4_DISP_INTF_SEL_DSI_VIDEO;
+               mdp4_crtc->mixer = 0;
+       } else if (intf == INTF_DSI_CMD) {
+               intf_sel &= ~MDP4_DISP_INTF_SEL_DSI_VIDEO;
+               intf_sel |= MDP4_DISP_INTF_SEL_DSI_CMD;
+               mdp4_crtc->mixer = 0;
+       } else if (intf == INTF_LCDC_DTV){
+               mdp4_crtc->mixer = 1;
+       }
+
+       blend_setup(crtc);
+
+       DBG("%s: intf_sel=%08x", mdp4_crtc->name, intf_sel);
+
+       mdp4_write(mdp4_kms, REG_MDP4_DISP_INTF_SEL, intf_sel);
+}
+
+static const char *dma_names[] = {
+               "DMA_P", "DMA_S", "DMA_E",
+};
+
+/* initialize crtc */
+struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
+               struct drm_plane *plane, int id, int ovlp_id,
+               enum mdp4_dma dma_id)
+{
+       struct drm_crtc *crtc = NULL;
+       struct mdp4_crtc *mdp4_crtc;
+       int ret;
+
+       mdp4_crtc = kzalloc(sizeof(*mdp4_crtc), GFP_KERNEL);
+       if (!mdp4_crtc) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       crtc = &mdp4_crtc->base;
+
+       mdp4_crtc->plane = plane;
+       mdp4_crtc->plane->crtc = crtc;
+
+       mdp4_crtc->ovlp = ovlp_id;
+       mdp4_crtc->dma = dma_id;
+
+       mdp4_crtc->vblank.irqmask = dma2irq(mdp4_crtc->dma);
+       mdp4_crtc->vblank.irq = mdp4_crtc_vblank_irq;
+
+       mdp4_crtc->err.irqmask = dma2err(mdp4_crtc->dma);
+       mdp4_crtc->err.irq = mdp4_crtc_err_irq;
+
+       snprintf(mdp4_crtc->name, sizeof(mdp4_crtc->name), "%s:%d",
+                       dma_names[dma_id], ovlp_id);
+
+       spin_lock_init(&mdp4_crtc->cursor.lock);
+
+       ret = drm_flip_work_init(&mdp4_crtc->unref_fb_work, 16,
+                       "unref fb", unref_fb_worker);
+       if (ret)
+               goto fail;
+
+       ret = drm_flip_work_init(&mdp4_crtc->unref_cursor_work, 64,
+                       "unref cursor", unref_cursor_worker);
+
+       INIT_WORK(&mdp4_crtc->pageflip_work, pageflip_worker);
+
+       drm_crtc_init(dev, crtc, &mdp4_crtc_funcs);
+       drm_crtc_helper_add(crtc, &mdp4_crtc_helper_funcs);
+
+       mdp4_plane_install_properties(mdp4_crtc->plane, &crtc->base);
+
+       return crtc;
+
+fail:
+       if (crtc)
+               mdp4_crtc_destroy(crtc);
+
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_dtv_encoder.c b/drivers/gpu/drm/msm/mdp4/mdp4_dtv_encoder.c
new file mode 100644 (file)
index 0000000..06d49e3
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <mach/clk.h>
+
+#include "mdp4_kms.h"
+#include "msm_connector.h"
+
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+
+
+struct mdp4_dtv_encoder {
+       struct drm_encoder base;
+       struct clk *src_clk;
+       struct clk *hdmi_clk;
+       struct clk *mdp_clk;
+       unsigned long int pixclock;
+       bool enabled;
+       uint32_t bsc;
+};
+#define to_mdp4_dtv_encoder(x) container_of(x, struct mdp4_dtv_encoder, base)
+
+static struct mdp4_kms *get_kms(struct drm_encoder *encoder)
+{
+       struct msm_drm_private *priv = encoder->dev->dev_private;
+       return to_mdp4_kms(priv->kms);
+}
+
+#ifdef CONFIG_MSM_BUS_SCALING
+#include <mach/board.h>
+/* not ironically named at all.. no, really.. */
+static void bs_init(struct mdp4_dtv_encoder *mdp4_dtv_encoder)
+{
+       struct drm_device *dev = mdp4_dtv_encoder->base.dev;
+       struct lcdc_platform_data *dtv_pdata = mdp4_find_pdata("dtv.0");
+
+       if (!dtv_pdata) {
+               dev_err(dev->dev, "could not find dtv pdata\n");
+               return;
+       }
+
+       if (dtv_pdata->bus_scale_table) {
+               mdp4_dtv_encoder->bsc = msm_bus_scale_register_client(
+                               dtv_pdata->bus_scale_table);
+               DBG("bus scale client: %08x", mdp4_dtv_encoder->bsc);
+               DBG("lcdc_power_save: %p", dtv_pdata->lcdc_power_save);
+               if (dtv_pdata->lcdc_power_save)
+                       dtv_pdata->lcdc_power_save(1);
+       }
+}
+
+static void bs_fini(struct mdp4_dtv_encoder *mdp4_dtv_encoder)
+{
+       if (mdp4_dtv_encoder->bsc) {
+               msm_bus_scale_unregister_client(mdp4_dtv_encoder->bsc);
+               mdp4_dtv_encoder->bsc = 0;
+       }
+}
+
+static void bs_set(struct mdp4_dtv_encoder *mdp4_dtv_encoder, int idx)
+{
+       if (mdp4_dtv_encoder->bsc) {
+               DBG("set bus scaling: %d", idx);
+               msm_bus_scale_client_update_request(mdp4_dtv_encoder->bsc, idx);
+       }
+}
+#else
+static void bs_init(struct mdp4_dtv_encoder *mdp4_dtv_encoder) {}
+static void bs_fini(struct mdp4_dtv_encoder *mdp4_dtv_encoder) {}
+static void bs_set(struct mdp4_dtv_encoder *mdp4_dtv_encoder, int idx) {}
+#endif
+
+static void mdp4_dtv_encoder_destroy(struct drm_encoder *encoder)
+{
+       struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+       bs_fini(mdp4_dtv_encoder);
+       drm_encoder_cleanup(encoder);
+       kfree(mdp4_dtv_encoder);
+}
+
+static const struct drm_encoder_funcs mdp4_dtv_encoder_funcs = {
+       .destroy = mdp4_dtv_encoder_destroy,
+};
+
+static void mdp4_dtv_encoder_dpms(struct drm_encoder *encoder, int mode)
+{
+       struct drm_device *dev = encoder->dev;
+       struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+       struct msm_connector *msm_connector = get_connector(encoder);
+       struct mdp4_kms *mdp4_kms = get_kms(encoder);
+       bool enabled = (mode == DRM_MODE_DPMS_ON);
+
+       DBG("mode=%d", mode);
+
+       if (enabled == mdp4_dtv_encoder->enabled)
+               return;
+
+       if (enabled) {
+               unsigned long pc = mdp4_dtv_encoder->pixclock;
+               int ret;
+
+               bs_set(mdp4_dtv_encoder, 1);
+
+               if (msm_connector)
+                       msm_connector->funcs->dpms(msm_connector, mode);
+
+               DBG("setting src_clk=%lu", pc);
+
+               ret = clk_set_rate(mdp4_dtv_encoder->src_clk, pc);
+               if (ret)
+                       dev_err(dev->dev, "failed to set src_clk to %lu: %d\n", pc, ret);
+               clk_prepare_enable(mdp4_dtv_encoder->src_clk);
+               ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk);
+               if (ret)
+                       dev_err(dev->dev, "failed to enable hdmi_clk: %d\n", ret);
+               ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk);
+               if (ret)
+                       dev_err(dev->dev, "failed to enabled mdp_clk: %d\n", ret);
+
+               mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1);
+       } else {
+               mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0);
+
+               /*
+                * Wait for a vsync so we know the ENABLE=0 latched before
+                * the (connector) source of the vsync's gets disabled,
+                * otherwise we end up in a funny state if we re-enable
+                * before the disable latches, which results that some of
+                * the settings changes for the new modeset (like new
+                * scanout buffer) don't latch properly..
+                */
+               mdp4_irq_wait(mdp4_kms, MDP4_IRQ_EXTERNAL_VSYNC);
+
+               clk_disable_unprepare(mdp4_dtv_encoder->src_clk);
+               clk_disable_unprepare(mdp4_dtv_encoder->hdmi_clk);
+               clk_disable_unprepare(mdp4_dtv_encoder->mdp_clk);
+
+               if (msm_connector)
+                       msm_connector->funcs->dpms(msm_connector, mode);
+
+               bs_set(mdp4_dtv_encoder, 0);
+       }
+
+       mdp4_dtv_encoder->enabled = enabled;
+}
+
+static bool mdp4_dtv_encoder_mode_fixup(struct drm_encoder *encoder,
+               const struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       return true;
+}
+
+static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder,
+               struct drm_display_mode *mode,
+               struct drm_display_mode *adjusted_mode)
+{
+       struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+       struct msm_connector *msm_connector = get_connector(encoder);
+       struct mdp4_kms *mdp4_kms = get_kms(encoder);
+       uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol;
+       uint32_t display_v_start, display_v_end;
+       uint32_t hsync_start_x, hsync_end_x;
+
+       mode = adjusted_mode;
+
+       DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
+                       mode->base.id, mode->name,
+                       mode->vrefresh, mode->clock,
+                       mode->hdisplay, mode->hsync_start,
+                       mode->hsync_end, mode->htotal,
+                       mode->vdisplay, mode->vsync_start,
+                       mode->vsync_end, mode->vtotal,
+                       mode->type, mode->flags);
+
+       mdp4_dtv_encoder->pixclock = mode->clock * 1000;
+
+       DBG("pixclock=%lu", mdp4_dtv_encoder->pixclock);
+
+       ctrl_pol = 0;
+       if (mode->flags & DRM_MODE_FLAG_NHSYNC)
+               ctrl_pol |= MDP4_DTV_CTRL_POLARITY_HSYNC_LOW;
+       if (mode->flags & DRM_MODE_FLAG_NVSYNC)
+               ctrl_pol |= MDP4_DTV_CTRL_POLARITY_VSYNC_LOW;
+       /* probably need to get DATA_EN polarity from panel.. */
+
+       dtv_hsync_skew = 0;  /* get this from panel? */
+
+       hsync_start_x = (mode->htotal - mode->hsync_start);
+       hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1;
+
+       vsync_period = mode->vtotal * mode->htotal;
+       vsync_len = (mode->vsync_end - mode->vsync_start) * mode->htotal;
+       display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew;
+       display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1;
+
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_HSYNC_CTRL,
+                       MDP4_DTV_HSYNC_CTRL_PULSEW(mode->hsync_end - mode->hsync_start) |
+                       MDP4_DTV_HSYNC_CTRL_PERIOD(mode->htotal));
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_VSYNC_PERIOD, vsync_period);
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_VSYNC_LEN, vsync_len);
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_HCTRL,
+                       MDP4_DTV_DISPLAY_HCTRL_START(hsync_start_x) |
+                       MDP4_DTV_DISPLAY_HCTRL_END(hsync_end_x));
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_VSTART, display_v_start);
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_DISPLAY_VEND, display_v_end);
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_BORDER_CLR, 0);
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_UNDERFLOW_CLR,
+                       MDP4_DTV_UNDERFLOW_CLR_ENABLE_RECOVERY |
+                       MDP4_DTV_UNDERFLOW_CLR_COLOR(0xff));
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_HSYNC_SKEW, dtv_hsync_skew);
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_CTRL_POLARITY, ctrl_pol);
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_HCTL,
+                       MDP4_DTV_ACTIVE_HCTL_START(0) |
+                       MDP4_DTV_ACTIVE_HCTL_END(0));
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VSTART, 0);
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VEND, 0);
+
+       if (msm_connector)
+               msm_connector->funcs->mode_set(msm_connector, mode);
+}
+
+static void mdp4_dtv_encoder_prepare(struct drm_encoder *encoder)
+{
+       mdp4_dtv_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
+}
+
+static void mdp4_dtv_encoder_commit(struct drm_encoder *encoder)
+{
+       mdp4_crtc_set_config(encoder->crtc,
+                       MDP4_DMA_CONFIG_R_BPC(BPC8) |
+                       MDP4_DMA_CONFIG_G_BPC(BPC8) |
+                       MDP4_DMA_CONFIG_B_BPC(BPC8) |
+                       MDP4_DMA_CONFIG_PACK(0x21));
+       mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV);
+       mdp4_dtv_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
+}
+
+static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = {
+       .dpms = mdp4_dtv_encoder_dpms,
+       .mode_fixup = mdp4_dtv_encoder_mode_fixup,
+       .mode_set = mdp4_dtv_encoder_mode_set,
+       .prepare = mdp4_dtv_encoder_prepare,
+       .commit = mdp4_dtv_encoder_commit,
+};
+
+long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate)
+{
+       struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder);
+       return clk_round_rate(mdp4_dtv_encoder->src_clk, rate);
+}
+
+/* initialize encoder */
+struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev)
+{
+       struct drm_encoder *encoder = NULL;
+       struct mdp4_dtv_encoder *mdp4_dtv_encoder;
+       int ret;
+
+       mdp4_dtv_encoder = kzalloc(sizeof(*mdp4_dtv_encoder), GFP_KERNEL);
+       if (!mdp4_dtv_encoder) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       encoder = &mdp4_dtv_encoder->base;
+
+       drm_encoder_init(dev, encoder, &mdp4_dtv_encoder_funcs,
+                        DRM_MODE_ENCODER_TMDS);
+       drm_encoder_helper_add(encoder, &mdp4_dtv_encoder_helper_funcs);
+
+       mdp4_dtv_encoder->src_clk = devm_clk_get(dev->dev, "src_clk");
+       if (IS_ERR(mdp4_dtv_encoder->src_clk)) {
+               dev_err(dev->dev, "failed to get src_clk\n");
+               ret = PTR_ERR(mdp4_dtv_encoder->src_clk);
+               goto fail;
+       }
+
+       mdp4_dtv_encoder->hdmi_clk = devm_clk_get(dev->dev, "hdmi_clk");
+       if (IS_ERR(mdp4_dtv_encoder->hdmi_clk)) {
+               dev_err(dev->dev, "failed to get hdmi_clk\n");
+               ret = PTR_ERR(mdp4_dtv_encoder->hdmi_clk);
+               goto fail;
+       }
+
+       mdp4_dtv_encoder->mdp_clk = devm_clk_get(dev->dev, "mdp_clk");
+       if (IS_ERR(mdp4_dtv_encoder->mdp_clk)) {
+               dev_err(dev->dev, "failed to get mdp_clk\n");
+               ret = PTR_ERR(mdp4_dtv_encoder->mdp_clk);
+               goto fail;
+       }
+
+       bs_init(mdp4_dtv_encoder);
+
+       return encoder;
+
+fail:
+       if (encoder)
+               mdp4_dtv_encoder_destroy(encoder);
+
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_format.c b/drivers/gpu/drm/msm/mdp4/mdp4_format.c
new file mode 100644 (file)
index 0000000..7b645f2
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "msm_drv.h"
+#include "mdp4_kms.h"
+
+#define FMT(name, a, r, g, b, e0, e1, e2, e3, alpha, tight, c, cnt) { \
+               .base = { .pixel_format = DRM_FORMAT_ ## name }, \
+               .bpc_a = BPC ## a ## A,                          \
+               .bpc_r = BPC ## r,                               \
+               .bpc_g = BPC ## g,                               \
+               .bpc_b = BPC ## b,                               \
+               .unpack = { e0, e1, e2, e3 },                    \
+               .alpha_enable = alpha,                           \
+               .unpack_tight = tight,                           \
+               .cpp = c,                                        \
+               .unpack_count = cnt,                             \
+       }
+
+#define BPC0A 0
+
+static const struct mdp4_format formats[] = {
+       /*  name      a  r  g  b   e0 e1 e2 e3  alpha   tight  cpp cnt */
+       FMT(ARGB8888, 8, 8, 8, 8,  1, 0, 2, 3,  true,   true,  4,  4),
+       FMT(XRGB8888, 8, 8, 8, 8,  1, 0, 2, 3,  false,  true,  4,  4),
+       FMT(RGB888,   0, 8, 8, 8,  1, 0, 2, 0,  false,  true,  3,  3),
+       FMT(BGR888,   0, 8, 8, 8,  2, 0, 1, 0,  false,  true,  3,  3),
+       FMT(RGB565,   0, 5, 6, 5,  1, 0, 2, 0,  false,  true,  2,  3),
+       FMT(BGR565,   0, 5, 6, 5,  2, 0, 1, 0,  false,  true,  2,  3),
+};
+
+const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format)
+{
+       int i;
+       for (i = 0; i < ARRAY_SIZE(formats); i++) {
+               const struct mdp4_format *f = &formats[i];
+               if (f->base.pixel_format == format)
+                       return &f->base;
+       }
+       return NULL;
+}
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/mdp4/mdp4_irq.c
new file mode 100644 (file)
index 0000000..5c6b7fc
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "msm_drv.h"
+#include "mdp4_kms.h"
+
+
+struct mdp4_irq_wait {
+       struct mdp4_irq irq;
+       int count;
+};
+
+static DECLARE_WAIT_QUEUE_HEAD(wait_event);
+
+static DEFINE_SPINLOCK(list_lock);
+
+static void update_irq(struct mdp4_kms *mdp4_kms)
+{
+       struct mdp4_irq *irq;
+       uint32_t irqmask = mdp4_kms->vblank_mask;
+
+       BUG_ON(!spin_is_locked(&list_lock));
+
+       list_for_each_entry(irq, &mdp4_kms->irq_list, node)
+               irqmask |= irq->irqmask;
+
+       mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, irqmask);
+}
+
+static void update_irq_unlocked(struct mdp4_kms *mdp4_kms)
+{
+       unsigned long flags;
+       spin_lock_irqsave(&list_lock, flags);
+       update_irq(mdp4_kms);
+       spin_unlock_irqrestore(&list_lock, flags);
+}
+
+static void mdp4_irq_error_handler(struct mdp4_irq *irq, uint32_t irqstatus)
+{
+       DRM_ERROR("errors: %08x\n", irqstatus);
+}
+
+void mdp4_irq_preinstall(struct msm_kms *kms)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, 0xffffffff);
+}
+
+int mdp4_irq_postinstall(struct msm_kms *kms)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       struct mdp4_irq *error_handler = &mdp4_kms->error_handler;
+
+       INIT_LIST_HEAD(&mdp4_kms->irq_list);
+
+       error_handler->irq = mdp4_irq_error_handler;
+       error_handler->irqmask = MDP4_IRQ_PRIMARY_INTF_UDERRUN |
+                       MDP4_IRQ_EXTERNAL_INTF_UDERRUN;
+
+       mdp4_irq_register(mdp4_kms, error_handler);
+
+       return 0;
+}
+
+void mdp4_irq_uninstall(struct msm_kms *kms)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       mdp4_write(mdp4_kms, REG_MDP4_INTR_ENABLE, 0x00000000);
+}
+
+irqreturn_t mdp4_irq(struct msm_kms *kms)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       struct drm_device *dev = mdp4_kms->dev;
+       struct msm_drm_private *priv = dev->dev_private;
+       struct mdp4_irq *handler, *n;
+       unsigned long flags;
+       unsigned int id;
+       uint32_t status;
+
+       status = mdp4_read(mdp4_kms, REG_MDP4_INTR_STATUS);
+       mdp4_write(mdp4_kms, REG_MDP4_INTR_CLEAR, status);
+
+       VERB("status=%08x", status);
+
+       for (id = 0; id < priv->num_crtcs; id++)
+               if (status & mdp4_crtc_vblank(priv->crtcs[id]))
+                       drm_handle_vblank(dev, id);
+
+       spin_lock_irqsave(&list_lock, flags);
+       mdp4_kms->in_irq = true;
+       list_for_each_entry_safe(handler, n, &mdp4_kms->irq_list, node) {
+               if (handler->irqmask & status) {
+                       spin_unlock_irqrestore(&list_lock, flags);
+                       handler->irq(handler, handler->irqmask & status);
+                       spin_lock_irqsave(&list_lock, flags);
+               }
+       }
+       mdp4_kms->in_irq = false;
+       update_irq(mdp4_kms);
+       spin_unlock_irqrestore(&list_lock, flags);
+
+       return IRQ_HANDLED;
+}
+
+int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       unsigned long flags;
+
+       spin_lock_irqsave(&list_lock, flags);
+       mdp4_kms->vblank_mask |= mdp4_crtc_vblank(crtc);
+       update_irq(mdp4_kms);
+       spin_unlock_irqrestore(&list_lock, flags);
+
+       return 0;
+}
+
+void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       unsigned long flags;
+
+       spin_lock_irqsave(&list_lock, flags);
+       mdp4_kms->vblank_mask &= ~mdp4_crtc_vblank(crtc);
+       update_irq(mdp4_kms);
+       spin_unlock_irqrestore(&list_lock, flags);
+}
+
+static void wait_irq(struct mdp4_irq *irq, uint32_t irqstatus)
+{
+       struct mdp4_irq_wait *wait =
+                       container_of(irq, struct mdp4_irq_wait, irq);
+       wait->count--;
+       wake_up_all(&wait_event);
+}
+
+void mdp4_irq_wait(struct mdp4_kms *mdp4_kms, uint32_t irqmask)
+{
+       struct mdp4_irq_wait wait = {
+               .irq = {
+                       .irq = wait_irq,
+                       .irqmask = irqmask,
+               },
+               .count = 1,
+       };
+       mdp4_irq_register(mdp4_kms, &wait.irq);
+       wait_event(wait_event, (wait.count <= 0));
+       mdp4_irq_unregister(mdp4_kms, &wait.irq);
+}
+
+void mdp4_irq_register(struct mdp4_kms *mdp4_kms, struct mdp4_irq *irq)
+{
+       unsigned long flags;
+       bool needs_update = false;
+
+       spin_lock_irqsave(&list_lock, flags);
+
+       if (!irq->registered) {
+               irq->registered = true;
+               list_add(&irq->node, &mdp4_kms->irq_list);
+               needs_update = !mdp4_kms->in_irq;
+       }
+
+       spin_unlock_irqrestore(&list_lock, flags);
+
+       if (needs_update)
+               update_irq_unlocked(mdp4_kms);
+}
+
+void mdp4_irq_unregister(struct mdp4_kms *mdp4_kms, struct mdp4_irq *irq)
+{
+       unsigned long flags;
+       bool needs_update = false;
+
+       spin_lock_irqsave(&list_lock, flags);
+
+       if (irq->registered) {
+               irq->registered = false;
+               list_del(&irq->node);
+               needs_update = !mdp4_kms->in_irq;
+       }
+
+       spin_unlock_irqrestore(&list_lock, flags);
+
+       if (needs_update)
+               update_irq_unlocked(mdp4_kms);
+}
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp4/mdp4_kms.c
new file mode 100644 (file)
index 0000000..960cd89
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "msm_drv.h"
+#include "mdp4_kms.h"
+
+#include <mach/iommu.h>
+
+static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev);
+
+static int mdp4_hw_init(struct msm_kms *kms)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       struct drm_device *dev = mdp4_kms->dev;
+       uint32_t version, major, minor, dmap_cfg, vg_cfg;
+       unsigned long clk;
+       int ret = 0;
+
+       pm_runtime_get_sync(dev->dev);
+
+       version = mdp4_read(mdp4_kms, REG_MDP4_VERSION);
+
+       major = FIELD(version, MDP4_VERSION_MAJOR);
+       minor = FIELD(version, MDP4_VERSION_MINOR);
+
+       DBG("found MDP version v%d.%d", major, minor);
+
+       if (major != 4) {
+               dev_err(dev->dev, "unexpected MDP version: v%d.%d\n",
+                               major, minor);
+               ret = -ENXIO;
+               goto out;
+       }
+
+       mdp4_kms->rev = minor;
+
+       if (mdp4_kms->dsi_pll_vdda) {
+               if ((mdp4_kms->rev == 2) || (mdp4_kms->rev == 4)) {
+                       ret = regulator_set_voltage(mdp4_kms->dsi_pll_vdda,
+                                       1200000, 1200000);
+                       if (ret) {
+                               dev_err(dev->dev,
+                                       "failed to set dsi_pll_vdda voltage: %d\n", ret);
+                               goto out;
+                       }
+               }
+       }
+
+       if (mdp4_kms->dsi_pll_vddio) {
+               if (mdp4_kms->rev == 2) {
+                       ret = regulator_set_voltage(mdp4_kms->dsi_pll_vddio,
+                                       1800000, 1800000);
+                       if (ret) {
+                               dev_err(dev->dev,
+                                       "failed to set dsi_pll_vddio voltage: %d\n", ret);
+                               goto out;
+                       }
+               }
+       }
+
+       if (mdp4_kms->rev > 1) {
+               mdp4_write(mdp4_kms, REG_MDP4_CS_CONTROLLER0, 0x0707ffff);
+               mdp4_write(mdp4_kms, REG_MDP4_CS_CONTROLLER1, 0x03073f3f);
+       }
+
+       mdp4_write(mdp4_kms, REG_MDP4_PORTMAP_MODE, 0x3);
+
+       /* max read pending cmd config, 3 pending requests: */
+       mdp4_write(mdp4_kms, REG_MDP4_READ_CNFG, 0x02222);
+
+       clk = clk_get_rate(mdp4_kms->clk);
+
+       if ((mdp4_kms->rev >= 1) || (clk >= 90000000)) {
+               dmap_cfg = 0x47;     /* 16 bytes-burst x 8 req */
+               vg_cfg = 0x47;       /* 16 bytes-burs x 8 req */
+       } else {
+               dmap_cfg = 0x27;     /* 8 bytes-burst x 8 req */
+               vg_cfg = 0x43;       /* 16 bytes-burst x 4 req */
+       }
+
+       DBG("fetch config: dmap=%02x, vg=%02x", dmap_cfg, vg_cfg);
+
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_FETCH_CONFIG(DMA_P), dmap_cfg);
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_FETCH_CONFIG(DMA_E), dmap_cfg);
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(VG1), vg_cfg);
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(VG2), vg_cfg);
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(RGB1), vg_cfg);
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_FETCH_CONFIG(RGB2), vg_cfg);
+
+       if (mdp4_kms->rev >= 2)
+               mdp4_write(mdp4_kms, REG_MDP4_LAYERMIXER_IN_CFG_UPDATE_METHOD, 1);
+
+       /* disable CSC matrix / YUV by default: */
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(VG1), 0);
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(VG2), 0);
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_P_OP_MODE, 0);
+       mdp4_write(mdp4_kms, REG_MDP4_DMA_S_OP_MODE, 0);
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_CSC_CONFIG(1), 0);
+       mdp4_write(mdp4_kms, REG_MDP4_OVLP_CSC_CONFIG(2), 0);
+
+       if (mdp4_kms->rev > 1)
+               mdp4_write(mdp4_kms, REG_MDP4_RESET_STATUS, 1);
+
+out:
+       pm_runtime_put_sync(dev->dev);
+
+       return ret;
+}
+
+static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate,
+               struct drm_encoder *encoder)
+{
+       /* if we had >1 encoder, we'd need something more clever: */
+       return mdp4_dtv_round_pixclk(encoder, rate);
+}
+
+static void mdp4_preclose(struct msm_kms *kms, struct drm_file *file)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       struct msm_drm_private *priv = mdp4_kms->dev->dev_private;
+       unsigned i;
+
+       for (i = 0; i < priv->num_crtcs; i++)
+               mdp4_crtc_cancel_pending_flip(priv->crtcs[i]);
+}
+
+static void mdp4_destroy(struct msm_kms *kms)
+{
+       struct mdp4_kms *mdp4_kms = to_mdp4_kms(kms);
+       kfree(mdp4_kms);
+}
+
+static const struct msm_kms_funcs kms_funcs = {
+               .hw_init         = mdp4_hw_init,
+               .irq_preinstall  = mdp4_irq_preinstall,
+               .irq_postinstall = mdp4_irq_postinstall,
+               .irq_uninstall   = mdp4_irq_uninstall,
+               .irq             = mdp4_irq,
+               .enable_vblank   = mdp4_enable_vblank,
+               .disable_vblank  = mdp4_disable_vblank,
+               .get_format      = mdp4_get_format,
+               .round_pixclk    = mdp4_round_pixclk,
+               .preclose        = mdp4_preclose,
+               .destroy         = mdp4_destroy,
+};
+
+int mdp4_disable(struct mdp4_kms *mdp4_kms)
+{
+       DBG("");
+
+       clk_disable_unprepare(mdp4_kms->clk);
+       if (mdp4_kms->pclk)
+               clk_disable_unprepare(mdp4_kms->pclk);
+       clk_disable_unprepare(mdp4_kms->lut_clk);
+
+       return 0;
+}
+
+int mdp4_enable(struct mdp4_kms *mdp4_kms)
+{
+       DBG("");
+
+       clk_prepare_enable(mdp4_kms->clk);
+       if (mdp4_kms->pclk)
+               clk_prepare_enable(mdp4_kms->pclk);
+       clk_prepare_enable(mdp4_kms->lut_clk);
+
+       return 0;
+}
+
+static int modeset_init(struct mdp4_kms *mdp4_kms)
+{
+       struct drm_device *dev = mdp4_kms->dev;
+       struct msm_drm_private *priv = dev->dev_private;
+       struct drm_plane *plane;
+       struct drm_crtc *crtc;
+       struct drm_encoder *encoder;
+       struct drm_connector *connector;
+       int ret;
+
+       /*
+        *  NOTE: this is a bit simplistic until we add support
+        * for more than just RGB1->DMA_E->DTV->HDMI
+        */
+
+       /* the CRTCs get constructed with a private plane: */
+       plane = mdp4_plane_init(dev, RGB1, true);
+       if (IS_ERR(plane)) {
+               dev_err(dev->dev, "failed to construct plane for RGB1\n");
+               ret = PTR_ERR(plane);
+               goto fail;
+       }
+
+       crtc  = mdp4_crtc_init(dev, plane, priv->num_crtcs, 1, DMA_E);
+       if (IS_ERR(crtc)) {
+               dev_err(dev->dev, "failed to construct crtc for DMA_E\n");
+               ret = PTR_ERR(crtc);
+               goto fail;
+       }
+       priv->crtcs[priv->num_crtcs++] = crtc;
+
+       encoder = mdp4_dtv_encoder_init(dev);
+       if (IS_ERR(encoder)) {
+               dev_err(dev->dev, "failed to construct DTV encoder\n");
+               ret = PTR_ERR(encoder);
+               goto fail;
+       }
+       encoder->possible_crtcs = 0x1;     /* DTV can be hooked to DMA_E */
+       priv->encoders[priv->num_encoders++] = encoder;
+
+       connector = hdmi_connector_init(dev, encoder);
+       if (IS_ERR(connector)) {
+               dev_err(dev->dev, "failed to construct HDMI connector\n");
+               ret = PTR_ERR(connector);
+               goto fail;
+       }
+       priv->connectors[priv->num_connectors++] = connector;
+
+       return 0;
+
+fail:
+       return ret;
+}
+
+static const char *iommu_ports[] = {
+               "mdp_port0_cb0", "mdp_port1_cb0",
+};
+
+struct msm_kms *mdp4_kms_init(struct drm_device *dev)
+{
+       struct platform_device *pdev = dev->platformdev;
+       struct mdp4_platform_config *config = mdp4_get_config(pdev);
+       struct mdp4_kms *mdp4_kms;
+       struct msm_kms *kms = NULL;
+       int ret;
+
+       mdp4_kms = kzalloc(sizeof(*mdp4_kms), GFP_KERNEL);
+       if (!mdp4_kms) {
+               dev_err(dev->dev, "failed to allocate kms\n");
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       kms = &mdp4_kms->base;
+       kms->funcs = &kms_funcs;
+
+       mdp4_kms->dev = dev;
+
+       mdp4_kms->mmio = msm_ioremap(pdev, NULL, "MDP4");
+       if (IS_ERR(mdp4_kms->mmio)) {
+               ret = PTR_ERR(mdp4_kms->mmio);
+               goto fail;
+       }
+
+       mdp4_kms->dsi_pll_vdda = devm_regulator_get(&pdev->dev, "dsi_pll_vdda");
+       if (IS_ERR(mdp4_kms->dsi_pll_vdda))
+               mdp4_kms->dsi_pll_vdda = NULL;
+
+       mdp4_kms->dsi_pll_vddio = devm_regulator_get(&pdev->dev, "dsi_pll_vddio");
+       if (IS_ERR(mdp4_kms->dsi_pll_vddio))
+               mdp4_kms->dsi_pll_vddio = NULL;
+
+       mdp4_kms->vdd = devm_regulator_get(&pdev->dev, "vdd");
+       if (IS_ERR(mdp4_kms->vdd))
+               mdp4_kms->vdd = NULL;
+
+       if (mdp4_kms->vdd) {
+               ret = regulator_enable(mdp4_kms->vdd);
+               if (ret) {
+                       dev_err(dev->dev, "failed to enable regulator vdd: %d\n", ret);
+                       goto fail;
+               }
+       }
+
+       mdp4_kms->clk = devm_clk_get(&pdev->dev, "core_clk");
+       if (IS_ERR(mdp4_kms->clk)) {
+               dev_err(dev->dev, "failed to get core_clk\n");
+               ret = PTR_ERR(mdp4_kms->clk);
+               goto fail;
+       }
+
+       mdp4_kms->pclk = devm_clk_get(&pdev->dev, "iface_clk");
+       if (IS_ERR(mdp4_kms->pclk))
+               mdp4_kms->pclk = NULL;
+
+       // XXX if (rev >= MDP_REV_42) { ???
+       mdp4_kms->lut_clk = devm_clk_get(&pdev->dev, "lut_clk");
+       if (IS_ERR(mdp4_kms->lut_clk)) {
+               dev_err(dev->dev, "failed to get lut_clk\n");
+               ret = PTR_ERR(mdp4_kms->lut_clk);
+               goto fail;
+       }
+
+       clk_set_rate(mdp4_kms->clk, config->max_clk);
+       clk_set_rate(mdp4_kms->lut_clk, config->max_clk);
+
+       if (!config->iommu) {
+               dev_err(dev->dev, "no iommu\n");
+               ret = -ENXIO;
+               goto fail;
+       }
+
+       /* make sure things are off before attaching iommu (bootloader could
+        * have left things on, in which case we'll start getting faults if
+        * we don't disable):
+        */
+       mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0);
+       mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0);
+       mdp4_write(mdp4_kms, REG_MDP4_DSI_ENABLE, 0);
+       mdelay(16);
+
+       ret = msm_iommu_attach(dev, config->iommu,
+                       iommu_ports, ARRAY_SIZE(iommu_ports));
+       if (ret)
+               goto fail;
+
+       mdp4_kms->id = msm_register_iommu(dev, config->iommu);
+       if (mdp4_kms->id < 0) {
+               ret = mdp4_kms->id;
+               dev_err(dev->dev, "failed to register mdp4 iommu: %d\n", ret);
+               goto fail;
+       }
+
+       ret = modeset_init(mdp4_kms);
+       if (ret) {
+               dev_err(dev->dev, "modeset_init failed: %d\n", ret);
+               goto fail;
+       }
+
+       return kms;
+
+fail:
+       if (kms)
+               mdp4_destroy(kms);
+       return ERR_PTR(ret);
+}
+
+static struct mdp4_platform_config *mdp4_get_config(struct platform_device *dev)
+{
+       static struct mdp4_platform_config config = {};
+#ifdef CONFIG_OF
+       /* TODO */
+#else
+       if (cpu_is_apq8064())
+               config.max_clk = 266667000;
+       else
+               config.max_clk = 200000000;
+
+       config.iommu = msm_get_iommu_domain(DISPLAY_READ_DOMAIN);
+#endif
+       return &config;
+}
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp4/mdp4_kms.h
new file mode 100644 (file)
index 0000000..1e83554
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MDP4_KMS_H__
+#define __MDP4_KMS_H__
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#include "msm_drv.h"
+#include "mdp4.xml.h"
+
+
+/* For transiently registering for different MDP4 irqs that various parts
+ * of the KMS code need during setup/configuration.  We these are not
+ * necessarily the same as what drm_vblank_get/put() are requesting, and
+ * the hysteresis in drm_vblank_put() is not necessarily desirable for
+ * internal housekeeping related irq usage.
+ */
+struct mdp4_irq {
+       struct list_head node;
+       uint32_t irqmask;
+       bool registered;
+       void (*irq)(struct mdp4_irq *irq, uint32_t irqstatus);
+};
+
+struct mdp4_kms {
+       struct msm_kms base;
+
+       struct drm_device *dev;
+
+       int rev;
+
+       /* mapper-id used to request GEM buffer mapped for scanout: */
+       int id;
+
+       void __iomem *mmio;
+
+       struct regulator *dsi_pll_vdda;
+       struct regulator *dsi_pll_vddio;
+       struct regulator *vdd;
+
+       struct clk *clk;
+       struct clk *pclk;
+       struct clk *lut_clk;
+
+       /* irq handling: */
+       bool in_irq;
+       struct list_head irq_list;    /* list of mdp4_irq */
+       uint32_t vblank_mask;         /* irq bits set for userspace vblank */
+       struct mdp4_irq error_handler;
+};
+#define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base)
+
+/* platform config data (ie. from DT, or pdata) */
+struct mdp4_platform_config {
+       struct iommu_domain *iommu;
+       uint32_t max_clk;
+};
+
+struct mdp4_format {
+       struct msm_format base;
+       enum mpd4_bpc bpc_r, bpc_g, bpc_b;
+       enum mpd4_bpc_alpha bpc_a;
+       uint8_t unpack[4];
+       bool alpha_enable, unpack_tight;
+       uint8_t cpp, unpack_count;
+};
+#define to_mdp4_format(x) container_of(x, struct mdp4_format, base)
+
+static inline void mdp4_write(struct mdp4_kms *mdp4_kms, u32 reg, u32 data)
+{
+       msm_writel(data, mdp4_kms->mmio + reg);
+}
+
+static inline u32 mdp4_read(struct mdp4_kms *mdp4_kms, u32 reg)
+{
+       return msm_readl(mdp4_kms->mmio + reg);
+}
+
+static inline uint32_t pipe2flush(enum mpd4_pipe pipe)
+{
+       switch (pipe) {
+       case VG1:      return MDP4_OVERLAY_FLUSH_VG1;
+       case VG2:      return MDP4_OVERLAY_FLUSH_VG2;
+       case RGB1:     return MDP4_OVERLAY_FLUSH_RGB1;
+       case RGB2:     return MDP4_OVERLAY_FLUSH_RGB1;
+       default:       return 0;
+       }
+}
+
+static inline uint32_t ovlp2flush(int ovlp)
+{
+       switch (ovlp) {
+       case 0:        return MDP4_OVERLAY_FLUSH_OVLP0;
+       case 1:        return MDP4_OVERLAY_FLUSH_OVLP1;
+       default:       return 0;
+       }
+}
+
+static inline uint32_t dma2irq(enum mdp4_dma dma)
+{
+       switch (dma) {
+       case DMA_P:    return MDP4_IRQ_DMA_P_DONE;
+       case DMA_S:    return MDP4_IRQ_DMA_S_DONE;
+       case DMA_E:    return MDP4_IRQ_DMA_E_DONE;
+       default:       return 0;
+       }
+}
+
+static inline uint32_t dma2err(enum mdp4_dma dma)
+{
+       switch (dma) {
+       case DMA_P:    return MDP4_IRQ_PRIMARY_INTF_UDERRUN;
+       case DMA_S:    return 0;  // ???
+       case DMA_E:    return MDP4_IRQ_EXTERNAL_INTF_UDERRUN;
+       default:       return 0;
+       }
+}
+
+int mdp4_disable(struct mdp4_kms *mdp4_kms);
+int mdp4_enable(struct mdp4_kms *mdp4_kms);
+
+void mdp4_irq_preinstall(struct msm_kms *kms);
+int mdp4_irq_postinstall(struct msm_kms *kms);
+void mdp4_irq_uninstall(struct msm_kms *kms);
+irqreturn_t mdp4_irq(struct msm_kms *kms);
+void mdp4_irq_wait(struct mdp4_kms *mdp4_kms, uint32_t irqmask);
+void mdp4_irq_register(struct mdp4_kms *mdp4_kms, struct mdp4_irq *irq);
+void mdp4_irq_unregister(struct mdp4_kms *mdp4_kms, struct mdp4_irq *irq);
+int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
+
+const struct msm_format *mdp4_get_format(struct msm_kms *kms, uint32_t format);
+
+void mdp4_plane_install_properties(struct drm_plane *plane,
+               struct drm_mode_object *obj);
+void mdp4_plane_set_scanout(struct drm_plane *plane,
+               struct drm_framebuffer *fb);
+int mdp4_plane_mode_set(struct drm_plane *plane,
+               struct drm_crtc *crtc, struct drm_framebuffer *fb,
+               int crtc_x, int crtc_y,
+               unsigned int crtc_w, unsigned int crtc_h,
+               uint32_t src_x, uint32_t src_y,
+               uint32_t src_w, uint32_t src_h);
+enum mpd4_pipe mdp4_plane_pipe(struct drm_plane *plane);
+struct drm_plane *mdp4_plane_init(struct drm_device *dev,
+               enum mpd4_pipe pipe_id, bool private_plane);
+
+uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
+void mdp4_crtc_cancel_pending_flip(struct drm_crtc *crtc);
+void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
+void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf);
+struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
+               struct drm_plane *plane, int id, int ovlp_id,
+               enum mdp4_dma dma_id);
+
+long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
+struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev);
+
+#ifdef CONFIG_MSM_BUS_SCALING
+static inline int match_dev_name(struct device *dev, void *data)
+{
+       return !strcmp(dev_name(dev), data);
+}
+/* bus scaling data is associated with extra pointless platform devices,
+ * "dtv", etc.. this is a bit of a hack, but we need a way for encoders
+ * to find their pdata to make the bus-scaling stuff work.
+ */
+static inline void *mdp4_find_pdata(const char *devname)
+{
+       struct device *dev;
+       dev = bus_find_device(&platform_bus_type, NULL,
+                       (void *)devname, match_dev_name);
+       return dev ? dev->platform_data : NULL;
+}
+#endif
+
+#endif /* __MDP4_KMS_H__ */
diff --git a/drivers/gpu/drm/msm/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp4/mdp4_plane.c
new file mode 100644 (file)
index 0000000..3468229
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "mdp4_kms.h"
+
+
+struct mdp4_plane {
+       struct drm_plane base;
+       const char *name;
+
+       enum mpd4_pipe pipe;
+
+       uint32_t nformats;
+       uint32_t formats[32];
+
+       bool enabled;
+};
+#define to_mdp4_plane(x) container_of(x, struct mdp4_plane, base)
+
+static struct mdp4_kms *get_kms(struct drm_plane *plane)
+{
+       struct msm_drm_private *priv = plane->dev->dev_private;
+       return to_mdp4_kms(priv->kms);
+}
+
+static int mdp4_plane_update(struct drm_plane *plane,
+               struct drm_crtc *crtc, struct drm_framebuffer *fb,
+               int crtc_x, int crtc_y,
+               unsigned int crtc_w, unsigned int crtc_h,
+               uint32_t src_x, uint32_t src_y,
+               uint32_t src_w, uint32_t src_h)
+{
+       struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+
+       mdp4_plane->enabled = true;
+
+       if (plane->fb)
+               drm_framebuffer_unreference(plane->fb);
+
+       drm_framebuffer_reference(fb);
+
+       return mdp4_plane_mode_set(plane, crtc, fb,
+                       crtc_x, crtc_y, crtc_w, crtc_h,
+                       src_x, src_y, src_w, src_h);
+}
+
+static int mdp4_plane_disable(struct drm_plane *plane)
+{
+       struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+       DBG("%s: TODO", mdp4_plane->name); // XXX
+       return 0;
+}
+
+static void mdp4_plane_destroy(struct drm_plane *plane)
+{
+       struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+
+       mdp4_plane_disable(plane);
+       drm_plane_cleanup(plane);
+
+       kfree(mdp4_plane);
+}
+
+/* helper to install properties which are common to planes and crtcs */
+void mdp4_plane_install_properties(struct drm_plane *plane,
+               struct drm_mode_object *obj)
+{
+       // XXX
+}
+
+int mdp4_plane_set_property(struct drm_plane *plane,
+               struct drm_property *property, uint64_t val)
+{
+       // XXX
+       return -EINVAL;
+}
+
+static const struct drm_plane_funcs mdp4_plane_funcs = {
+               .update_plane = mdp4_plane_update,
+               .disable_plane = mdp4_plane_disable,
+               .destroy = mdp4_plane_destroy,
+               .set_property = mdp4_plane_set_property,
+};
+
+void mdp4_plane_set_scanout(struct drm_plane *plane,
+               struct drm_framebuffer *fb)
+{
+       struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+       struct mdp4_kms *mdp4_kms = get_kms(plane);
+       enum mpd4_pipe pipe = mdp4_plane->pipe;
+       uint32_t iova;
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe),
+                       MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) |
+                       MDP4_PIPE_SRC_STRIDE_A_P1(fb->pitches[1]));
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_B(pipe),
+                       MDP4_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) |
+                       MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3]));
+
+       msm_gem_get_iova(msm_framebuffer_bo(fb, 0), mdp4_kms->id, &iova);
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), iova);
+
+       plane->fb = fb;
+}
+
+#define MDP4_VG_PHASE_STEP_DEFAULT     0x20000000
+
+int mdp4_plane_mode_set(struct drm_plane *plane,
+               struct drm_crtc *crtc, struct drm_framebuffer *fb,
+               int crtc_x, int crtc_y,
+               unsigned int crtc_w, unsigned int crtc_h,
+               uint32_t src_x, uint32_t src_y,
+               uint32_t src_w, uint32_t src_h)
+{
+       struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+       struct mdp4_kms *mdp4_kms = get_kms(plane);
+       enum mpd4_pipe pipe = mdp4_plane->pipe;
+       const struct mdp4_format *format;
+       uint32_t op_mode = 0;
+       uint32_t phasex_step = MDP4_VG_PHASE_STEP_DEFAULT;
+       uint32_t phasey_step = MDP4_VG_PHASE_STEP_DEFAULT;
+
+       /* src values are in Q16 fixed point, convert to integer: */
+       src_x = src_x >> 16;
+       src_y = src_y >> 16;
+       src_w = src_w >> 16;
+       src_h = src_h >> 16;
+
+       if (src_w != crtc_w) {
+               op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN;
+               /* TODO calc phasex_step */
+       }
+
+       if (src_h != crtc_h) {
+               op_mode |= MDP4_PIPE_OP_MODE_SCALEY_EN;
+               /* TODO calc phasey_step */
+       }
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_SIZE(pipe),
+                       MDP4_PIPE_SRC_SIZE_WIDTH(src_w) |
+                       MDP4_PIPE_SRC_SIZE_HEIGHT(src_h));
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_XY(pipe),
+                       MDP4_PIPE_SRC_XY_X(src_x) |
+                       MDP4_PIPE_SRC_XY_Y(src_y));
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_SIZE(pipe),
+                       MDP4_PIPE_DST_SIZE_WIDTH(crtc_w) |
+                       MDP4_PIPE_DST_SIZE_HEIGHT(crtc_h));
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_DST_XY(pipe),
+                       MDP4_PIPE_SRC_XY_X(crtc_x) |
+                       MDP4_PIPE_SRC_XY_Y(crtc_y));
+
+       mdp4_plane_set_scanout(plane, fb);
+
+       format = to_mdp4_format(msm_framebuffer_format(fb));
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe),
+                       MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) |
+                       MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) |
+                       MDP4_PIPE_SRC_FORMAT_G_BPC(format->bpc_g) |
+                       MDP4_PIPE_SRC_FORMAT_B_BPC(format->bpc_b) |
+                       COND(format->alpha_enable, MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE) |
+                       MDP4_PIPE_SRC_FORMAT_CPP(format->cpp - 1) |
+                       MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) |
+                       COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT));
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe),
+                       MDP4_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) |
+                       MDP4_PIPE_SRC_UNPACK_ELEM1(format->unpack[1]) |
+                       MDP4_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) |
+                       MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3]));
+
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(pipe), op_mode);
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step);
+       mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step);
+
+       plane->crtc = crtc;
+
+       return 0;
+}
+
+static const char *pipe_names[] = {
+               "VG1", "VG2",
+               "RGB1", "RGB2", "RGB3",
+               "VG3", "VG4",
+};
+
+enum mpd4_pipe mdp4_plane_pipe(struct drm_plane *plane)
+{
+       struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane);
+       return mdp4_plane->pipe;
+}
+
+/* initialize plane */
+struct drm_plane *mdp4_plane_init(struct drm_device *dev,
+               enum mpd4_pipe pipe_id, bool private_plane)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct drm_plane *plane = NULL;
+       struct mdp4_plane *mdp4_plane;
+       int ret;
+
+       mdp4_plane = kzalloc(sizeof(*mdp4_plane), GFP_KERNEL);
+       if (!mdp4_plane) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       plane = &mdp4_plane->base;
+
+       mdp4_plane->pipe = pipe_id;
+       mdp4_plane->name = pipe_names[pipe_id];
+
+       drm_plane_init(dev, plane, (1 << priv->num_crtcs) - 1, &mdp4_plane_funcs,
+                       mdp4_plane->formats, mdp4_plane->nformats, private_plane);
+
+       mdp4_plane_install_properties(plane, &plane->base);
+
+       return plane;
+
+fail:
+       if (plane)
+               mdp4_plane_destroy(plane);
+
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/msm_connector.c b/drivers/gpu/drm/msm/msm_connector.c
new file mode 100644 (file)
index 0000000..aeea887
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "msm_drv.h"
+#include "msm_connector.h"
+
+void msm_connector_init(struct msm_connector *connector,
+               const struct msm_connector_funcs *funcs,
+               struct drm_encoder *encoder)
+{
+       connector->funcs = funcs;
+       connector->encoder = encoder;
+}
+
+struct drm_encoder *msm_connector_attached_encoder(
+               struct drm_connector *connector)
+{
+       struct msm_connector *msm_connector = to_msm_connector(connector);
+       return msm_connector->encoder;
+}
diff --git a/drivers/gpu/drm/msm/msm_connector.h b/drivers/gpu/drm/msm/msm_connector.h
new file mode 100644 (file)
index 0000000..0b41866
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MSM_CONNECTOR_H__
+#define __MSM_CONNECTOR_H__
+
+#include "msm_drv.h"
+
+/*
+ * Base class for MSM connectors.  Typically a connector is a bit more
+ * passive.  But with the split between (for example) DTV within MDP4,
+ * and HDMI encoder, we really need two parts to an encoder.  Instead
+ * what we do is have the part external to the display controller block
+ * in the connector, which is called from the encoder to delegate the
+ * appropriate parts of modeset.
+ */
+
+struct msm_connector;
+
+struct msm_connector_funcs {
+       void (*dpms)(struct msm_connector *connector, int mode);
+       void (*mode_set)(struct msm_connector *connector,
+                       struct drm_display_mode *mode);
+};
+
+struct msm_connector {
+       struct drm_connector base;
+       struct drm_encoder *encoder;
+       const struct msm_connector_funcs *funcs;
+};
+#define to_msm_connector(x) container_of(x, struct msm_connector, base)
+
+void msm_connector_init(struct msm_connector *connector,
+               const struct msm_connector_funcs *funcs,
+               struct drm_encoder *encoder);
+
+struct drm_encoder *msm_connector_attached_encoder(
+               struct drm_connector *connector);
+
+static inline struct msm_connector *get_connector(struct drm_encoder *encoder)
+{
+       struct msm_drm_private *priv = encoder->dev->dev_private;
+       int i;
+
+       for (i = 0; i < priv->num_connectors; i++) {
+               struct drm_connector *connector = priv->connectors[i];
+               if (msm_connector_attached_encoder(connector) == encoder)
+                       return to_msm_connector(connector);
+       }
+
+       return NULL;
+}
+
+#endif /* __MSM_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
new file mode 100644 (file)
index 0000000..864c977
--- /dev/null
@@ -0,0 +1,776 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "msm_drv.h"
+#include "msm_gpu.h"
+
+#include <mach/iommu.h>
+
+static void msm_fb_output_poll_changed(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       if (priv->fbdev)
+               drm_fb_helper_hotplug_event(priv->fbdev);
+}
+
+static const struct drm_mode_config_funcs mode_config_funcs = {
+       .fb_create = msm_framebuffer_create,
+       .output_poll_changed = msm_fb_output_poll_changed,
+};
+
+static int msm_fault_handler(struct iommu_domain *iommu, struct device *dev,
+               unsigned long iova, int flags, void *arg)
+{
+       DBG("*** fault: iova=%08lx, flags=%d", iova, flags);
+       return 0;
+}
+
+int msm_register_iommu(struct drm_device *dev, struct iommu_domain *iommu)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       int idx = priv->num_iommus++;
+
+       if (WARN_ON(idx >= ARRAY_SIZE(priv->iommus)))
+               return -EINVAL;
+
+       priv->iommus[idx] = iommu;
+
+       iommu_set_fault_handler(iommu, msm_fault_handler, dev);
+
+       /* need to iommu_attach_device() somewhere??  on resume?? */
+
+       return idx;
+}
+
+int msm_iommu_attach(struct drm_device *dev, struct iommu_domain *iommu,
+               const char **names, int cnt)
+{
+       int i, ret;
+
+       for (i = 0; i < cnt; i++) {
+               struct device *ctx = msm_iommu_get_ctx(names[i]);
+               if (!ctx)
+                       continue;
+               ret = iommu_attach_device(iommu, ctx);
+               if (ret) {
+                       dev_warn(dev->dev, "could not attach iommu to %s", names[i]);
+                       return ret;
+               }
+       }
+       return 0;
+}
+
+#ifdef CONFIG_DRM_MSM_REGISTER_LOGGING
+static bool reglog = false;
+MODULE_PARM_DESC(reglog, "Enable register read/write logging");
+module_param(reglog, bool, 0600);
+#else
+#define reglog 0
+#endif
+
+void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
+               const char *dbgname)
+{
+       struct resource *res;
+       unsigned long size;
+       void __iomem *ptr;
+
+       if (name)
+               res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+       else
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       if (!res) {
+               dev_err(&pdev->dev, "failed to get memory resource: %s\n", name);
+               return ERR_PTR(-EINVAL);
+       }
+
+       size = resource_size(res);
+
+       ptr = devm_ioremap_nocache(&pdev->dev, res->start, size);
+       if (!ptr) {
+               dev_err(&pdev->dev, "failed to ioremap: %s\n", name);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       if (reglog)
+               printk(KERN_DEBUG "IO:region %s %08x %08lx\n", dbgname, (u32)ptr, size);
+
+       return ptr;
+}
+
+void msm_writel(u32 data, void __iomem *addr)
+{
+       if (reglog)
+               printk(KERN_DEBUG "IO:W %08x %08x\n", (u32)addr, data);
+       writel(data, addr);
+}
+
+u32 msm_readl(const void __iomem *addr)
+{
+       u32 val = readl(addr);
+       if (reglog)
+               printk(KERN_ERR "IO:R %08x %08x\n", (u32)addr, val);
+       return val;
+}
+
+/*
+ * DRM operations:
+ */
+
+static int msm_unload(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       struct msm_gpu *gpu = priv->gpu;
+
+       drm_kms_helper_poll_fini(dev);
+       drm_mode_config_cleanup(dev);
+       drm_vblank_cleanup(dev);
+
+       pm_runtime_get_sync(dev->dev);
+       drm_irq_uninstall(dev);
+       pm_runtime_put_sync(dev->dev);
+
+       flush_workqueue(priv->wq);
+       destroy_workqueue(priv->wq);
+
+       if (kms) {
+               pm_runtime_disable(dev->dev);
+               kms->funcs->destroy(kms);
+       }
+
+       if (gpu) {
+               mutex_lock(&dev->struct_mutex);
+               gpu->funcs->pm_suspend(gpu);
+               gpu->funcs->destroy(gpu);
+               mutex_unlock(&dev->struct_mutex);
+       }
+
+       dev->dev_private = NULL;
+
+       kfree(priv);
+
+       return 0;
+}
+
+static int msm_load(struct drm_device *dev, unsigned long flags)
+{
+       struct platform_device *pdev = dev->platformdev;
+       struct msm_drm_private *priv;
+       struct msm_kms *kms;
+       int ret;
+
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(dev->dev, "failed to allocate private data\n");
+               return -ENOMEM;
+       }
+
+       dev->dev_private = priv;
+
+       priv->wq = alloc_ordered_workqueue("msm", 0);
+       init_waitqueue_head(&priv->fence_event);
+
+       INIT_LIST_HEAD(&priv->inactive_list);
+
+       drm_mode_config_init(dev);
+
+       kms = mdp4_kms_init(dev);
+       if (IS_ERR(kms)) {
+               /*
+                * NOTE: once we have GPU support, having no kms should not
+                * be considered fatal.. ideally we would still support gpu
+                * and (for example) use dmabuf/prime to share buffers with
+                * imx drm driver on iMX5
+                */
+               dev_err(dev->dev, "failed to load kms\n");
+               ret = PTR_ERR(priv->kms);
+               goto fail;
+       }
+
+       priv->kms = kms;
+
+       if (kms) {
+               pm_runtime_enable(dev->dev);
+               ret = kms->funcs->hw_init(kms);
+               if (ret) {
+                       dev_err(dev->dev, "kms hw init failed: %d\n", ret);
+                       goto fail;
+               }
+       }
+
+       dev->mode_config.min_width = 0;
+       dev->mode_config.min_height = 0;
+       dev->mode_config.max_width = 2048;
+       dev->mode_config.max_height = 2048;
+       dev->mode_config.funcs = &mode_config_funcs;
+
+       ret = drm_vblank_init(dev, 1);
+       if (ret < 0) {
+               dev_err(dev->dev, "failed to initialize vblank\n");
+               goto fail;
+       }
+
+       pm_runtime_get_sync(dev->dev);
+       ret = drm_irq_install(dev);
+       pm_runtime_put_sync(dev->dev);
+       if (ret < 0) {
+               dev_err(dev->dev, "failed to install IRQ handler\n");
+               goto fail;
+       }
+
+       platform_set_drvdata(pdev, dev);
+
+#ifdef CONFIG_DRM_MSM_FBDEV
+       priv->fbdev = msm_fbdev_init(dev);
+#endif
+
+       drm_kms_helper_poll_init(dev);
+
+       return 0;
+
+fail:
+       msm_unload(dev);
+       return ret;
+}
+
+static void load_gpu(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_gpu *gpu;
+
+       if (priv->gpu)
+               return;
+
+       mutex_lock(&dev->struct_mutex);
+       gpu = a3xx_gpu_init(dev);
+       if (IS_ERR(gpu)) {
+               dev_warn(dev->dev, "failed to load a3xx gpu\n");
+               gpu = NULL;
+               /* not fatal */
+       }
+       mutex_unlock(&dev->struct_mutex);
+
+       if (gpu) {
+               int ret;
+               gpu->funcs->pm_resume(gpu);
+               ret = gpu->funcs->hw_init(gpu);
+               if (ret) {
+                       dev_err(dev->dev, "gpu hw init failed: %d\n", ret);
+                       gpu->funcs->destroy(gpu);
+                       gpu = NULL;
+               }
+       }
+
+       priv->gpu = gpu;
+}
+
+static int msm_open(struct drm_device *dev, struct drm_file *file)
+{
+       struct msm_file_private *ctx;
+
+       /* For now, load gpu on open.. to avoid the requirement of having
+        * firmware in the initrd.
+        */
+       load_gpu(dev);
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+
+       file->driver_priv = ctx;
+
+       return 0;
+}
+
+static void msm_preclose(struct drm_device *dev, struct drm_file *file)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_file_private *ctx = file->driver_priv;
+       struct msm_kms *kms = priv->kms;
+
+       if (kms)
+               kms->funcs->preclose(kms, file);
+
+       mutex_lock(&dev->struct_mutex);
+       if (ctx == priv->lastctx)
+               priv->lastctx = NULL;
+       mutex_unlock(&dev->struct_mutex);
+
+       kfree(ctx);
+}
+
+static void msm_lastclose(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       if (priv->fbdev) {
+               drm_modeset_lock_all(dev);
+               drm_fb_helper_restore_fbdev_mode(priv->fbdev);
+               drm_modeset_unlock_all(dev);
+       }
+}
+
+static irqreturn_t msm_irq(DRM_IRQ_ARGS)
+{
+       struct drm_device *dev = arg;
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       BUG_ON(!kms);
+       return kms->funcs->irq(kms);
+}
+
+static void msm_irq_preinstall(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       BUG_ON(!kms);
+       kms->funcs->irq_preinstall(kms);
+}
+
+static int msm_irq_postinstall(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       BUG_ON(!kms);
+       return kms->funcs->irq_postinstall(kms);
+}
+
+static void msm_irq_uninstall(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       BUG_ON(!kms);
+       kms->funcs->irq_uninstall(kms);
+}
+
+static int msm_enable_vblank(struct drm_device *dev, int crtc_id)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       if (!kms)
+               return -ENXIO;
+       DBG("dev=%p, crtc=%d", dev, crtc_id);
+       return kms->funcs->enable_vblank(kms, priv->crtcs[crtc_id]);
+}
+
+static void msm_disable_vblank(struct drm_device *dev, int crtc_id)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       if (!kms)
+               return;
+       DBG("dev=%p, crtc=%d", dev, crtc_id);
+       kms->funcs->disable_vblank(kms, priv->crtcs[crtc_id]);
+}
+
+/*
+ * DRM debugfs:
+ */
+
+#ifdef CONFIG_DEBUG_FS
+static int msm_gpu_show(struct drm_device *dev, struct seq_file *m)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_gpu *gpu = priv->gpu;
+
+       if (gpu) {
+               seq_printf(m, "%s Status:\n", gpu->name);
+               gpu->funcs->show(gpu, m);
+       }
+
+       return 0;
+}
+
+static int msm_gem_show(struct drm_device *dev, struct seq_file *m)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_gpu *gpu = priv->gpu;
+
+       if (gpu) {
+               seq_printf(m, "Active Objects (%s):\n", gpu->name);
+               msm_gem_describe_objects(&gpu->active_list, m);
+       }
+
+       seq_printf(m, "Inactive Objects:\n");
+       msm_gem_describe_objects(&priv->inactive_list, m);
+
+       return 0;
+}
+
+static int msm_mm_show(struct drm_device *dev, struct seq_file *m)
+{
+       return drm_mm_dump_table(m, dev->mm_private);
+}
+
+static int msm_fb_show(struct drm_device *dev, struct seq_file *m)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct drm_framebuffer *fb, *fbdev_fb = NULL;
+
+       if (priv->fbdev) {
+               seq_printf(m, "fbcon ");
+               fbdev_fb = priv->fbdev->fb;
+               msm_framebuffer_describe(fbdev_fb, m);
+       }
+
+       mutex_lock(&dev->mode_config.fb_lock);
+       list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
+               if (fb == fbdev_fb)
+                       continue;
+
+               seq_printf(m, "user ");
+               msm_framebuffer_describe(fb, m);
+       }
+       mutex_unlock(&dev->mode_config.fb_lock);
+
+       return 0;
+}
+
+static int show_locked(struct seq_file *m, void *arg)
+{
+       struct drm_info_node *node = (struct drm_info_node *) m->private;
+       struct drm_device *dev = node->minor->dev;
+       int (*show)(struct drm_device *dev, struct seq_file *m) =
+                       node->info_ent->data;
+       int ret;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       ret = show(dev, m);
+
+       mutex_unlock(&dev->struct_mutex);
+
+       return ret;
+}
+
+static struct drm_info_list msm_debugfs_list[] = {
+               {"gpu", show_locked, 0, msm_gpu_show},
+               {"gem", show_locked, 0, msm_gem_show},
+               { "mm", show_locked, 0, msm_mm_show },
+               { "fb", show_locked, 0, msm_fb_show },
+};
+
+static int msm_debugfs_init(struct drm_minor *minor)
+{
+       struct drm_device *dev = minor->dev;
+       int ret;
+
+       ret = drm_debugfs_create_files(msm_debugfs_list,
+                       ARRAY_SIZE(msm_debugfs_list),
+                       minor->debugfs_root, minor);
+
+       if (ret) {
+               dev_err(dev->dev, "could not install msm_debugfs_list\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+static void msm_debugfs_cleanup(struct drm_minor *minor)
+{
+       drm_debugfs_remove_files(msm_debugfs_list,
+                       ARRAY_SIZE(msm_debugfs_list), minor);
+}
+#endif
+
+/*
+ * Fences:
+ */
+
+int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
+               struct timespec *timeout)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       unsigned long timeout_jiffies = timespec_to_jiffies(timeout);
+       unsigned long start_jiffies = jiffies;
+       unsigned long remaining_jiffies;
+       int ret;
+
+       if (time_after(start_jiffies, timeout_jiffies))
+               remaining_jiffies = 0;
+       else
+               remaining_jiffies = timeout_jiffies - start_jiffies;
+
+       ret = wait_event_interruptible_timeout(priv->fence_event,
+                       priv->completed_fence >= fence,
+                       remaining_jiffies);
+       if (ret == 0) {
+               DBG("timeout waiting for fence: %u (completed: %u)",
+                               fence, priv->completed_fence);
+               ret = -ETIMEDOUT;
+       } else if (ret != -ERESTARTSYS) {
+               ret = 0;
+       }
+
+       return ret;
+}
+
+/* call under struct_mutex */
+void msm_update_fence(struct drm_device *dev, uint32_t fence)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+
+       if (fence > priv->completed_fence) {
+               priv->completed_fence = fence;
+               wake_up_all(&priv->fence_event);
+       }
+}
+
+/*
+ * DRM ioctls:
+ */
+
+static int msm_ioctl_get_param(struct drm_device *dev, void *data,
+               struct drm_file *file)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct drm_msm_param *args = data;
+       struct msm_gpu *gpu;
+
+       /* for now, we just have 3d pipe.. eventually this would need to
+        * be more clever to dispatch to appropriate gpu module:
+        */
+       if (args->pipe != MSM_PIPE_3D0)
+               return -EINVAL;
+
+       gpu = priv->gpu;
+
+       if (!gpu)
+               return -ENXIO;
+
+       return gpu->funcs->get_param(gpu, args->param, &args->value);
+}
+
+static int msm_ioctl_gem_new(struct drm_device *dev, void *data,
+               struct drm_file *file)
+{
+       struct drm_msm_gem_new *args = data;
+       return msm_gem_new_handle(dev, file, args->size,
+                       args->flags, &args->handle);
+}
+
+#define TS(t) ((struct timespec){ .tv_sec = (t).tv_sec, .tv_nsec = (t).tv_nsec })
+
+static int msm_ioctl_gem_cpu_prep(struct drm_device *dev, void *data,
+               struct drm_file *file)
+{
+       struct drm_msm_gem_cpu_prep *args = data;
+       struct drm_gem_object *obj;
+       int ret;
+
+       obj = drm_gem_object_lookup(dev, file, args->handle);
+       if (!obj)
+               return -ENOENT;
+
+       ret = msm_gem_cpu_prep(obj, args->op, &TS(args->timeout));
+
+       drm_gem_object_unreference_unlocked(obj);
+
+       return ret;
+}
+
+static int msm_ioctl_gem_cpu_fini(struct drm_device *dev, void *data,
+               struct drm_file *file)
+{
+       struct drm_msm_gem_cpu_fini *args = data;
+       struct drm_gem_object *obj;
+       int ret;
+
+       obj = drm_gem_object_lookup(dev, file, args->handle);
+       if (!obj)
+               return -ENOENT;
+
+       ret = msm_gem_cpu_fini(obj);
+
+       drm_gem_object_unreference_unlocked(obj);
+
+       return ret;
+}
+
+static int msm_ioctl_gem_info(struct drm_device *dev, void *data,
+               struct drm_file *file)
+{
+       struct drm_msm_gem_info *args = data;
+       struct drm_gem_object *obj;
+       int ret = 0;
+
+       if (args->pad)
+               return -EINVAL;
+
+       obj = drm_gem_object_lookup(dev, file, args->handle);
+       if (!obj)
+               return -ENOENT;
+
+       args->offset = msm_gem_mmap_offset(obj);
+
+       drm_gem_object_unreference_unlocked(obj);
+
+       return ret;
+}
+
+static int msm_ioctl_wait_fence(struct drm_device *dev, void *data,
+               struct drm_file *file)
+{
+       struct drm_msm_wait_fence *args = data;
+       return msm_wait_fence_interruptable(dev, args->fence, &TS(args->timeout));
+}
+
+static const struct drm_ioctl_desc msm_ioctls[] = {
+       DRM_IOCTL_DEF_DRV(MSM_GET_PARAM,    msm_ioctl_get_param,    DRM_UNLOCKED|DRM_AUTH),
+       DRM_IOCTL_DEF_DRV(MSM_GEM_NEW,      msm_ioctl_gem_new,      DRM_UNLOCKED|DRM_AUTH),
+       DRM_IOCTL_DEF_DRV(MSM_GEM_INFO,     msm_ioctl_gem_info,     DRM_UNLOCKED|DRM_AUTH),
+       DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_PREP, msm_ioctl_gem_cpu_prep, DRM_UNLOCKED|DRM_AUTH),
+       DRM_IOCTL_DEF_DRV(MSM_GEM_CPU_FINI, msm_ioctl_gem_cpu_fini, DRM_UNLOCKED|DRM_AUTH),
+       DRM_IOCTL_DEF_DRV(MSM_GEM_SUBMIT,   msm_ioctl_gem_submit,   DRM_UNLOCKED|DRM_AUTH),
+       DRM_IOCTL_DEF_DRV(MSM_WAIT_FENCE,   msm_ioctl_wait_fence,   DRM_UNLOCKED|DRM_AUTH),
+};
+
+static const struct vm_operations_struct vm_ops = {
+       .fault = msm_gem_fault,
+       .open = drm_gem_vm_open,
+       .close = drm_gem_vm_close,
+};
+
+static const struct file_operations fops = {
+       .owner              = THIS_MODULE,
+       .open               = drm_open,
+       .release            = drm_release,
+       .unlocked_ioctl     = drm_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl       = drm_compat_ioctl,
+#endif
+       .poll               = drm_poll,
+       .read               = drm_read,
+       .llseek             = no_llseek,
+       .mmap               = msm_gem_mmap,
+};
+
+static struct drm_driver msm_driver = {
+       .driver_features    = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET,
+       .load               = msm_load,
+       .unload             = msm_unload,
+       .open               = msm_open,
+       .preclose           = msm_preclose,
+       .lastclose          = msm_lastclose,
+       .irq_handler        = msm_irq,
+       .irq_preinstall     = msm_irq_preinstall,
+       .irq_postinstall    = msm_irq_postinstall,
+       .irq_uninstall      = msm_irq_uninstall,
+       .get_vblank_counter = drm_vblank_count,
+       .enable_vblank      = msm_enable_vblank,
+       .disable_vblank     = msm_disable_vblank,
+       .gem_free_object    = msm_gem_free_object,
+       .gem_vm_ops         = &vm_ops,
+       .dumb_create        = msm_gem_dumb_create,
+       .dumb_map_offset    = msm_gem_dumb_map_offset,
+       .dumb_destroy       = msm_gem_dumb_destroy,
+#ifdef CONFIG_DEBUG_FS
+       .debugfs_init       = msm_debugfs_init,
+       .debugfs_cleanup    = msm_debugfs_cleanup,
+#endif
+       .ioctls             = msm_ioctls,
+       .num_ioctls         = DRM_MSM_NUM_IOCTLS,
+       .fops               = &fops,
+       .name               = "msm",
+       .desc               = "MSM Snapdragon DRM",
+       .date               = "20130625",
+       .major              = 1,
+       .minor              = 0,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static int msm_pm_suspend(struct device *dev)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+
+       drm_kms_helper_poll_disable(ddev);
+
+       return 0;
+}
+
+static int msm_pm_resume(struct device *dev)
+{
+       struct drm_device *ddev = dev_get_drvdata(dev);
+
+       drm_kms_helper_poll_enable(ddev);
+
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops msm_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(msm_pm_suspend, msm_pm_resume)
+};
+
+/*
+ * Platform driver:
+ */
+
+static int msm_pdev_probe(struct platform_device *pdev)
+{
+       return drm_platform_init(&msm_driver, pdev);
+}
+
+static int msm_pdev_remove(struct platform_device *pdev)
+{
+       drm_platform_exit(&msm_driver, pdev);
+
+       return 0;
+}
+
+static const struct platform_device_id msm_id[] = {
+       { "mdp", 0 },
+       { }
+};
+
+static struct platform_driver msm_platform_driver = {
+       .probe      = msm_pdev_probe,
+       .remove     = msm_pdev_remove,
+       .driver     = {
+               .owner  = THIS_MODULE,
+               .name   = "msm",
+               .pm     = &msm_pm_ops,
+       },
+       .id_table   = msm_id,
+};
+
+static int __init msm_drm_register(void)
+{
+       DBG("init");
+       hdmi_register();
+       a3xx_register();
+       return platform_driver_register(&msm_platform_driver);
+}
+
+static void __exit msm_drm_unregister(void)
+{
+       DBG("fini");
+       platform_driver_unregister(&msm_platform_driver);
+       hdmi_unregister();
+       a3xx_unregister();
+}
+
+module_init(msm_drm_register);
+module_exit(msm_drm_unregister);
+
+MODULE_AUTHOR("Rob Clark <robdclark@gmail.com");
+MODULE_DESCRIPTION("MSM DRM Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h
new file mode 100644 (file)
index 0000000..34c36b2
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MSM_DRV_H__
+#define __MSM_DRV_H__
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/cpufreq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/iommu.h>
+#include <linux/types.h>
+#include <asm/sizes.h>
+
+#ifndef CONFIG_OF
+#include <mach/board.h>
+#include <mach/socinfo.h>
+#include <mach/iommu_domains.h>
+#endif
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/msm_drm.h>
+
+struct msm_kms;
+struct msm_gpu;
+
+#define NUM_DOMAINS 2    /* one for KMS, then one per gpu core (?) */
+
+struct msm_file_private {
+       /* currently we don't do anything useful with this.. but when
+        * per-context address spaces are supported we'd keep track of
+        * the context's page-tables here.
+        */
+       int dummy;
+};
+
+struct msm_drm_private {
+
+       struct msm_kms *kms;
+
+       /* when we have more than one 'msm_gpu' these need to be an array: */
+       struct msm_gpu *gpu;
+       struct msm_file_private *lastctx;
+
+       struct drm_fb_helper *fbdev;
+
+       uint32_t next_fence, completed_fence;
+       wait_queue_head_t fence_event;
+
+       /* list of GEM objects: */
+       struct list_head inactive_list;
+
+       struct workqueue_struct *wq;
+
+       /* registered IOMMU domains: */
+       unsigned int num_iommus;
+       struct iommu_domain *iommus[NUM_DOMAINS];
+
+       unsigned int num_crtcs;
+       struct drm_crtc *crtcs[8];
+
+       unsigned int num_encoders;
+       struct drm_encoder *encoders[8];
+
+       unsigned int num_connectors;
+       struct drm_connector *connectors[8];
+};
+
+struct msm_format {
+       uint32_t pixel_format;
+};
+
+/* As there are different display controller blocks depending on the
+ * snapdragon version, the kms support is split out and the appropriate
+ * implementation is loaded at runtime.  The kms module is responsible
+ * for constructing the appropriate planes/crtcs/encoders/connectors.
+ */
+struct msm_kms_funcs {
+       /* hw initialization: */
+       int (*hw_init)(struct msm_kms *kms);
+       /* irq handling: */
+       void (*irq_preinstall)(struct msm_kms *kms);
+       int (*irq_postinstall)(struct msm_kms *kms);
+       void (*irq_uninstall)(struct msm_kms *kms);
+       irqreturn_t (*irq)(struct msm_kms *kms);
+       int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
+       void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc);
+       /* misc: */
+       const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format);
+       long (*round_pixclk)(struct msm_kms *kms, unsigned long rate,
+                       struct drm_encoder *encoder);
+       /* cleanup: */
+       void (*preclose)(struct msm_kms *kms, struct drm_file *file);
+       void (*destroy)(struct msm_kms *kms);
+};
+
+struct msm_kms {
+       const struct msm_kms_funcs *funcs;
+};
+
+struct msm_kms *mdp4_kms_init(struct drm_device *dev);
+
+int msm_register_iommu(struct drm_device *dev, struct iommu_domain *iommu);
+int msm_iommu_attach(struct drm_device *dev, struct iommu_domain *iommu,
+               const char **names, int cnt);
+
+int msm_wait_fence_interruptable(struct drm_device *dev, uint32_t fence,
+               struct timespec *timeout);
+void msm_update_fence(struct drm_device *dev, uint32_t fence);
+
+int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+               struct drm_file *file);
+
+int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
+int msm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
+uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
+int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
+               uint32_t *iova);
+int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova);
+void msm_gem_put_iova(struct drm_gem_object *obj, int id);
+int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+               struct drm_mode_create_dumb *args);
+int msm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+               uint32_t handle);
+int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+               uint32_t handle, uint64_t *offset);
+void *msm_gem_vaddr_locked(struct drm_gem_object *obj);
+void *msm_gem_vaddr(struct drm_gem_object *obj);
+int msm_gem_queue_inactive_work(struct drm_gem_object *obj,
+               struct work_struct *work);
+void msm_gem_move_to_active(struct drm_gem_object *obj,
+               struct msm_gpu *gpu, uint32_t fence);
+void msm_gem_move_to_inactive(struct drm_gem_object *obj);
+int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
+               struct timespec *timeout);
+int msm_gem_cpu_fini(struct drm_gem_object *obj);
+void msm_gem_free_object(struct drm_gem_object *obj);
+int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
+               uint32_t size, uint32_t flags, uint32_t *handle);
+struct drm_gem_object *msm_gem_new(struct drm_device *dev,
+               uint32_t size, uint32_t flags);
+
+struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
+const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
+struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+               struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos);
+struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
+               struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd);
+
+struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
+
+struct drm_connector *hdmi_connector_init(struct drm_device *dev,
+               struct drm_encoder *encoder);
+void __init hdmi_register(void);
+void __exit hdmi_unregister(void);
+
+#ifdef CONFIG_DEBUG_FS
+void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
+void msm_gem_describe_objects(struct list_head *list, struct seq_file *m);
+void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m);
+#endif
+
+void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
+               const char *dbgname);
+void msm_writel(u32 data, void __iomem *addr);
+u32 msm_readl(const void __iomem *addr);
+
+#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+#define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+
+static inline int align_pitch(int width, int bpp)
+{
+       int bytespp = (bpp + 7) / 8;
+       /* adreno needs pitch aligned to 32 pixels: */
+       return bytespp * ALIGN(width, 32);
+}
+
+/* for the generated headers: */
+#define INVALID_IDX(idx) ({BUG(); 0;})
+#define fui(x)                ({BUG(); 0;})
+#define util_float_to_half(x) ({BUG(); 0;})
+
+
+#define FIELD(val, name) (((val) & name ## __MASK) >> name ## __SHIFT)
+
+/* for conditionally setting boolean flag(s): */
+#define COND(bool, val) ((bool) ? (val) : 0)
+
+
+#endif /* __MSM_DRV_H__ */
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c
new file mode 100644 (file)
index 0000000..0286c0e
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "msm_drv.h"
+
+#include "drm_crtc.h"
+#include "drm_crtc_helper.h"
+
+struct msm_framebuffer {
+       struct drm_framebuffer base;
+       const struct msm_format *format;
+       struct drm_gem_object *planes[2];
+};
+#define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base)
+
+
+static int msm_framebuffer_create_handle(struct drm_framebuffer *fb,
+               struct drm_file *file_priv,
+               unsigned int *handle)
+{
+       struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       return drm_gem_handle_create(file_priv,
+                       msm_fb->planes[0], handle);
+}
+
+static void msm_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+       struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       int i, n = drm_format_num_planes(fb->pixel_format);
+
+       DBG("destroy: FB ID: %d (%p)", fb->base.id, fb);
+
+       drm_framebuffer_cleanup(fb);
+
+       for (i = 0; i < n; i++) {
+               struct drm_gem_object *bo = msm_fb->planes[i];
+               if (bo)
+                       drm_gem_object_unreference_unlocked(bo);
+       }
+
+       kfree(msm_fb);
+}
+
+static int msm_framebuffer_dirty(struct drm_framebuffer *fb,
+               struct drm_file *file_priv, unsigned flags, unsigned color,
+               struct drm_clip_rect *clips, unsigned num_clips)
+{
+       return 0;
+}
+
+static const struct drm_framebuffer_funcs msm_framebuffer_funcs = {
+       .create_handle = msm_framebuffer_create_handle,
+       .destroy = msm_framebuffer_destroy,
+       .dirty = msm_framebuffer_dirty,
+};
+
+#ifdef CONFIG_DEBUG_FS
+void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m)
+{
+       struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       int i, n = drm_format_num_planes(fb->pixel_format);
+
+       seq_printf(m, "fb: %dx%d@%4.4s (%2d, ID:%d)\n",
+                       fb->width, fb->height, (char *)&fb->pixel_format,
+                       fb->refcount.refcount.counter, fb->base.id);
+
+       for (i = 0; i < n; i++) {
+               seq_printf(m, "   %d: offset=%d pitch=%d, obj: ",
+                               i, fb->offsets[i], fb->pitches[i]);
+               msm_gem_describe(msm_fb->planes[i], m);
+       }
+}
+#endif
+
+struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane)
+{
+       struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       return msm_fb->planes[plane];
+}
+
+const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb)
+{
+       struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb);
+       return msm_fb->format;
+}
+
+struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
+               struct drm_file *file, struct drm_mode_fb_cmd2 *mode_cmd)
+{
+       struct drm_gem_object *bos[4] = {0};
+       struct drm_framebuffer *fb;
+       int ret, i, n = drm_format_num_planes(mode_cmd->pixel_format);
+
+       for (i = 0; i < n; i++) {
+               bos[i] = drm_gem_object_lookup(dev, file,
+                               mode_cmd->handles[i]);
+               if (!bos[i]) {
+                       ret = -ENXIO;
+                       goto out_unref;
+               }
+       }
+
+       fb = msm_framebuffer_init(dev, mode_cmd, bos);
+       if (IS_ERR(fb)) {
+               ret = PTR_ERR(fb);
+               goto out_unref;
+       }
+
+       return fb;
+
+out_unref:
+       for (i = 0; i < n; i++)
+               drm_gem_object_unreference_unlocked(bos[i]);
+       return ERR_PTR(ret);
+}
+
+struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
+               struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_kms *kms = priv->kms;
+       struct msm_framebuffer *msm_fb;
+       struct drm_framebuffer *fb = NULL;
+       const struct msm_format *format;
+       int ret, i, n;
+       unsigned int hsub, vsub;
+
+       DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
+                       dev, mode_cmd, mode_cmd->width, mode_cmd->height,
+                       (char *)&mode_cmd->pixel_format);
+
+       n = drm_format_num_planes(mode_cmd->pixel_format);
+       hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
+       vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
+
+       format = kms->funcs->get_format(kms, mode_cmd->pixel_format);
+       if (!format) {
+               dev_err(dev->dev, "unsupported pixel format: %4.4s\n",
+                               (char *)&mode_cmd->pixel_format);
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       msm_fb = kzalloc(sizeof(*msm_fb), GFP_KERNEL);
+       if (!msm_fb) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       fb = &msm_fb->base;
+
+       msm_fb->format = format;
+
+       for (i = 0; i < n; i++) {
+               unsigned int width = mode_cmd->width / (i ? hsub : 1);
+               unsigned int height = mode_cmd->height / (i ? vsub : 1);
+               unsigned int min_size;
+
+               min_size = (height - 1) * mode_cmd->pitches[i]
+                        + width * drm_format_plane_cpp(mode_cmd->pixel_format, i)
+                        + mode_cmd->offsets[i];
+
+               if (bos[i]->size < min_size) {
+                       ret = -EINVAL;
+                       goto fail;
+               }
+
+               msm_fb->planes[i] = bos[i];
+       }
+
+       drm_helper_mode_fill_fb_struct(fb, mode_cmd);
+
+       ret = drm_framebuffer_init(dev, fb, &msm_framebuffer_funcs);
+       if (ret) {
+               dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
+               goto fail;
+       }
+
+       DBG("create: FB ID: %d (%p)", fb->base.id, fb);
+
+       return fb;
+
+fail:
+       if (fb)
+               msm_framebuffer_destroy(fb);
+
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
new file mode 100644 (file)
index 0000000..6c6d7d4
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "msm_drv.h"
+
+#include "drm_crtc.h"
+#include "drm_fb_helper.h"
+
+/*
+ * fbdev funcs, to implement legacy fbdev interface on top of drm driver
+ */
+
+#define to_msm_fbdev(x) container_of(x, struct msm_fbdev, base)
+
+struct msm_fbdev {
+       struct drm_fb_helper base;
+       struct drm_framebuffer *fb;
+       struct drm_gem_object *bo;
+};
+
+static struct fb_ops msm_fb_ops = {
+       .owner = THIS_MODULE,
+
+       /* Note: to properly handle manual update displays, we wrap the
+        * basic fbdev ops which write to the framebuffer
+        */
+       .fb_read = fb_sys_read,
+       .fb_write = fb_sys_write,
+       .fb_fillrect = sys_fillrect,
+       .fb_copyarea = sys_copyarea,
+       .fb_imageblit = sys_imageblit,
+
+       .fb_check_var = drm_fb_helper_check_var,
+       .fb_set_par = drm_fb_helper_set_par,
+       .fb_pan_display = drm_fb_helper_pan_display,
+       .fb_blank = drm_fb_helper_blank,
+       .fb_setcmap = drm_fb_helper_setcmap,
+};
+
+static int msm_fbdev_create(struct drm_fb_helper *helper,
+               struct drm_fb_helper_surface_size *sizes)
+{
+       struct msm_fbdev *fbdev = to_msm_fbdev(helper);
+       struct drm_device *dev = helper->dev;
+       struct drm_framebuffer *fb = NULL;
+       struct fb_info *fbi = NULL;
+       struct drm_mode_fb_cmd2 mode_cmd = {0};
+       dma_addr_t paddr;
+       int ret, size;
+
+       /* only doing ARGB32 since this is what is needed to alpha-blend
+        * with video overlays:
+        */
+       sizes->surface_bpp = 32;
+       sizes->surface_depth = 32;
+
+       DBG("create fbdev: %dx%d@%d (%dx%d)", sizes->surface_width,
+                       sizes->surface_height, sizes->surface_bpp,
+                       sizes->fb_width, sizes->fb_height);
+
+       mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
+                       sizes->surface_depth);
+
+       mode_cmd.width = sizes->surface_width;
+       mode_cmd.height = sizes->surface_height;
+
+       mode_cmd.pitches[0] = align_pitch(
+                       mode_cmd.width, sizes->surface_bpp);
+
+       /* allocate backing bo */
+       size = mode_cmd.pitches[0] * mode_cmd.height;
+       DBG("allocating %d bytes for fb %d", size, dev->primary->index);
+       mutex_lock(&dev->struct_mutex);
+       fbdev->bo = msm_gem_new(dev, size, MSM_BO_SCANOUT | MSM_BO_WC);
+       mutex_unlock(&dev->struct_mutex);
+       if (IS_ERR(fbdev->bo)) {
+               ret = PTR_ERR(fbdev->bo);
+               fbdev->bo = NULL;
+               dev_err(dev->dev, "failed to allocate buffer object: %d\n", ret);
+               goto fail;
+       }
+
+       fb = msm_framebuffer_init(dev, &mode_cmd, &fbdev->bo);
+       if (IS_ERR(fb)) {
+               dev_err(dev->dev, "failed to allocate fb\n");
+               /* note: if fb creation failed, we can't rely on fb destroy
+                * to unref the bo:
+                */
+               drm_gem_object_unreference(fbdev->bo);
+               ret = PTR_ERR(fb);
+               goto fail;
+       }
+
+       mutex_lock(&dev->struct_mutex);
+
+       /* TODO implement our own fb_mmap so we don't need this: */
+       msm_gem_get_iova_locked(fbdev->bo, 0, &paddr);
+
+       fbi = framebuffer_alloc(0, dev->dev);
+       if (!fbi) {
+               dev_err(dev->dev, "failed to allocate fb info\n");
+               ret = -ENOMEM;
+               goto fail_unlock;
+       }
+
+       DBG("fbi=%p, dev=%p", fbi, dev);
+
+       fbdev->fb = fb;
+       helper->fb = fb;
+       helper->fbdev = fbi;
+
+       fbi->par = helper;
+       fbi->flags = FBINFO_DEFAULT;
+       fbi->fbops = &msm_fb_ops;
+
+       strcpy(fbi->fix.id, "msm");
+
+       ret = fb_alloc_cmap(&fbi->cmap, 256, 0);
+       if (ret) {
+               ret = -ENOMEM;
+               goto fail_unlock;
+       }
+
+       drm_fb_helper_fill_fix(fbi, fb->pitches[0], fb->depth);
+       drm_fb_helper_fill_var(fbi, helper, sizes->fb_width, sizes->fb_height);
+
+       dev->mode_config.fb_base = paddr;
+
+       fbi->screen_base = msm_gem_vaddr_locked(fbdev->bo);
+       fbi->screen_size = fbdev->bo->size;
+       fbi->fix.smem_start = paddr;
+       fbi->fix.smem_len = fbdev->bo->size;
+
+       DBG("par=%p, %dx%d", fbi->par, fbi->var.xres, fbi->var.yres);
+       DBG("allocated %dx%d fb", fbdev->fb->width, fbdev->fb->height);
+
+       mutex_unlock(&dev->struct_mutex);
+
+       return 0;
+
+fail_unlock:
+       mutex_unlock(&dev->struct_mutex);
+fail:
+
+       if (ret) {
+               if (fbi)
+                       framebuffer_release(fbi);
+               if (fb) {
+                       drm_framebuffer_unregister_private(fb);
+                       drm_framebuffer_remove(fb);
+               }
+       }
+
+       return ret;
+}
+
+static void msm_crtc_fb_gamma_set(struct drm_crtc *crtc,
+               u16 red, u16 green, u16 blue, int regno)
+{
+       DBG("fbdev: set gamma");
+}
+
+static void msm_crtc_fb_gamma_get(struct drm_crtc *crtc,
+               u16 *red, u16 *green, u16 *blue, int regno)
+{
+       DBG("fbdev: get gamma");
+}
+
+static struct drm_fb_helper_funcs msm_fb_helper_funcs = {
+       .gamma_set = msm_crtc_fb_gamma_set,
+       .gamma_get = msm_crtc_fb_gamma_get,
+       .fb_probe = msm_fbdev_create,
+};
+
+/* initialize fbdev helper */
+struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_fbdev *fbdev = NULL;
+       struct drm_fb_helper *helper;
+       int ret = 0;
+
+       fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL);
+       if (!fbdev)
+               goto fail;
+
+       helper = &fbdev->base;
+
+       helper->funcs = &msm_fb_helper_funcs;
+
+       ret = drm_fb_helper_init(dev, helper,
+                       priv->num_crtcs, priv->num_connectors);
+       if (ret) {
+               dev_err(dev->dev, "could not init fbdev: ret=%d\n", ret);
+               goto fail;
+       }
+
+       drm_fb_helper_single_add_all_connectors(helper);
+
+       /* disable all the possible outputs/crtcs before entering KMS mode */
+       drm_helper_disable_unused_functions(dev);
+
+       drm_fb_helper_initial_config(helper, 32);
+
+       priv->fbdev = helper;
+
+       return helper;
+
+fail:
+       kfree(fbdev);
+       return NULL;
+}
+
+void msm_fbdev_free(struct drm_device *dev)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct drm_fb_helper *helper = priv->fbdev;
+       struct msm_fbdev *fbdev;
+       struct fb_info *fbi;
+
+       DBG();
+
+       fbi = helper->fbdev;
+
+       /* only cleanup framebuffer if it is present */
+       if (fbi) {
+               unregister_framebuffer(fbi);
+               framebuffer_release(fbi);
+       }
+
+       drm_fb_helper_fini(helper);
+
+       fbdev = to_msm_fbdev(priv->fbdev);
+
+       /* this will free the backing object */
+       if (fbdev->fb) {
+               drm_framebuffer_unregister_private(fbdev->fb);
+               drm_framebuffer_remove(fbdev->fb);
+       }
+
+       kfree(fbdev);
+
+       priv->fbdev = NULL;
+}
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
new file mode 100644 (file)
index 0000000..6b5a6c8
--- /dev/null
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/shmem_fs.h>
+
+#include "msm_drv.h"
+#include "msm_gem.h"
+#include "msm_gpu.h"
+
+
+/* called with dev->struct_mutex held */
+static struct page **get_pages(struct drm_gem_object *obj)
+{
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+       if (!msm_obj->pages) {
+               struct drm_device *dev = obj->dev;
+               struct page **p = drm_gem_get_pages(obj, 0);
+               int npages = obj->size >> PAGE_SHIFT;
+
+               if (IS_ERR(p)) {
+                       dev_err(dev->dev, "could not get pages: %ld\n",
+                                       PTR_ERR(p));
+                       return p;
+               }
+
+               msm_obj->sgt = drm_prime_pages_to_sg(p, npages);
+               if (!msm_obj->sgt) {
+                       dev_err(dev->dev, "failed to allocate sgt\n");
+                       return ERR_PTR(-ENOMEM);
+               }
+
+               msm_obj->pages = p;
+
+               /* For non-cached buffers, ensure the new pages are clean
+                * because display controller, GPU, etc. are not coherent:
+                */
+               if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
+                       dma_map_sg(dev->dev, msm_obj->sgt->sgl,
+                                       msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+       }
+
+       return msm_obj->pages;
+}
+
+static void put_pages(struct drm_gem_object *obj)
+{
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+       if (msm_obj->pages) {
+               /* For non-cached buffers, ensure the new pages are clean
+                * because display controller, GPU, etc. are not coherent:
+                */
+               if (msm_obj->flags & (MSM_BO_WC|MSM_BO_UNCACHED))
+                       dma_unmap_sg(obj->dev->dev, msm_obj->sgt->sgl,
+                                       msm_obj->sgt->nents, DMA_BIDIRECTIONAL);
+               sg_free_table(msm_obj->sgt);
+               kfree(msm_obj->sgt);
+
+               drm_gem_put_pages(obj, msm_obj->pages, true, false);
+               msm_obj->pages = NULL;
+       }
+}
+
+int msm_gem_mmap_obj(struct drm_gem_object *obj,
+               struct vm_area_struct *vma)
+{
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+       vma->vm_flags &= ~VM_PFNMAP;
+       vma->vm_flags |= VM_MIXEDMAP;
+
+       if (msm_obj->flags & MSM_BO_WC) {
+               vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
+       } else if (msm_obj->flags & MSM_BO_UNCACHED) {
+               vma->vm_page_prot = pgprot_noncached(vm_get_page_prot(vma->vm_flags));
+       } else {
+               /*
+                * Shunt off cached objs to shmem file so they have their own
+                * address_space (so unmap_mapping_range does what we want,
+                * in particular in the case of mmap'd dmabufs)
+                */
+               fput(vma->vm_file);
+               get_file(obj->filp);
+               vma->vm_pgoff = 0;
+               vma->vm_file  = obj->filp;
+
+               vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);
+       }
+
+       return 0;
+}
+
+int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+       int ret;
+
+       ret = drm_gem_mmap(filp, vma);
+       if (ret) {
+               DBG("mmap failed: %d", ret);
+               return ret;
+       }
+
+       return msm_gem_mmap_obj(vma->vm_private_data, vma);
+}
+
+int msm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+       struct drm_gem_object *obj = vma->vm_private_data;
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       struct drm_device *dev = obj->dev;
+       struct page **pages;
+       unsigned long pfn;
+       pgoff_t pgoff;
+       int ret;
+
+       /* Make sure we don't parallel update on a fault, nor move or remove
+        * something from beneath our feet
+        */
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               goto out;
+
+       /* make sure we have pages attached now */
+       pages = get_pages(obj);
+       if (IS_ERR(pages)) {
+               ret = PTR_ERR(pages);
+               goto out_unlock;
+       }
+
+       /* We don't use vmf->pgoff since that has the fake offset: */
+       pgoff = ((unsigned long)vmf->virtual_address -
+                       vma->vm_start) >> PAGE_SHIFT;
+
+       pfn = page_to_pfn(msm_obj->pages[pgoff]);
+
+       VERB("Inserting %p pfn %lx, pa %lx", vmf->virtual_address,
+                       pfn, pfn << PAGE_SHIFT);
+
+       ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn);
+
+out_unlock:
+       mutex_unlock(&dev->struct_mutex);
+out:
+       switch (ret) {
+       case -EAGAIN:
+               set_need_resched();
+       case 0:
+       case -ERESTARTSYS:
+       case -EINTR:
+               return VM_FAULT_NOPAGE;
+       case -ENOMEM:
+               return VM_FAULT_OOM;
+       default:
+               return VM_FAULT_SIGBUS;
+       }
+}
+
+/** get mmap offset */
+static uint64_t mmap_offset(struct drm_gem_object *obj)
+{
+       struct drm_device *dev = obj->dev;
+       int ret;
+
+       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+       /* Make it mmapable */
+       ret = drm_gem_create_mmap_offset(obj);
+
+       if (ret) {
+               dev_err(dev->dev, "could not allocate mmap offset\n");
+               return 0;
+       }
+
+       return drm_vma_node_offset_addr(&obj->vma_node);
+}
+
+uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj)
+{
+       uint64_t offset;
+       mutex_lock(&obj->dev->struct_mutex);
+       offset = mmap_offset(obj);
+       mutex_unlock(&obj->dev->struct_mutex);
+       return offset;
+}
+
+/* helpers for dealing w/ iommu: */
+static int map_range(struct iommu_domain *domain, unsigned int iova,
+               struct sg_table *sgt, unsigned int len, int prot)
+{
+       struct scatterlist *sg;
+       unsigned int da = iova;
+       unsigned int i, j;
+       int ret;
+
+       if (!domain || !sgt)
+               return -EINVAL;
+
+       for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+               u32 pa = sg_phys(sg) - sg->offset;
+               size_t bytes = sg->length + sg->offset;
+
+               VERB("map[%d]: %08x %08x(%x)", i, iova, pa, bytes);
+
+               ret = iommu_map(domain, da, pa, bytes, prot);
+               if (ret)
+                       goto fail;
+
+               da += bytes;
+       }
+
+       return 0;
+
+fail:
+       da = iova;
+
+       for_each_sg(sgt->sgl, sg, i, j) {
+               size_t bytes = sg->length + sg->offset;
+               iommu_unmap(domain, da, bytes);
+               da += bytes;
+       }
+       return ret;
+}
+
+static void unmap_range(struct iommu_domain *domain, unsigned int iova,
+               struct sg_table *sgt, unsigned int len)
+{
+       struct scatterlist *sg;
+       unsigned int da = iova;
+       int i;
+
+       for_each_sg(sgt->sgl, sg, sgt->nents, i) {
+               size_t bytes = sg->length + sg->offset;
+               size_t unmapped;
+
+               unmapped = iommu_unmap(domain, da, bytes);
+               if (unmapped < bytes)
+                       break;
+
+               VERB("unmap[%d]: %08x(%x)", i, iova, bytes);
+
+               BUG_ON(!IS_ALIGNED(bytes, PAGE_SIZE));
+
+               da += bytes;
+       }
+}
+
+/* should be called under struct_mutex.. although it can be called
+ * from atomic context without struct_mutex to acquire an extra
+ * iova ref if you know one is already held.
+ *
+ * That means when I do eventually need to add support for unpinning
+ * the refcnt counter needs to be atomic_t.
+ */
+int msm_gem_get_iova_locked(struct drm_gem_object *obj, int id,
+               uint32_t *iova)
+{
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       int ret = 0;
+
+       if (!msm_obj->domain[id].iova) {
+               struct msm_drm_private *priv = obj->dev->dev_private;
+               uint32_t offset = (uint32_t)mmap_offset(obj);
+               struct page **pages;
+               pages = get_pages(obj);
+               if (IS_ERR(pages))
+                       return PTR_ERR(pages);
+               // XXX ideally we would not map buffers writable when not needed...
+               ret = map_range(priv->iommus[id], offset, msm_obj->sgt,
+                               obj->size, IOMMU_READ | IOMMU_WRITE);
+               msm_obj->domain[id].iova = offset;
+       }
+
+       if (!ret)
+               *iova = msm_obj->domain[id].iova;
+
+       return ret;
+}
+
+int msm_gem_get_iova(struct drm_gem_object *obj, int id, uint32_t *iova)
+{
+       int ret;
+       mutex_lock(&obj->dev->struct_mutex);
+       ret = msm_gem_get_iova_locked(obj, id, iova);
+       mutex_unlock(&obj->dev->struct_mutex);
+       return ret;
+}
+
+void msm_gem_put_iova(struct drm_gem_object *obj, int id)
+{
+       // XXX TODO ..
+       // NOTE: probably don't need a _locked() version.. we wouldn't
+       // normally unmap here, but instead just mark that it could be
+       // unmapped (if the iova refcnt drops to zero), but then later
+       // if another _get_iova_locked() fails we can start unmapping
+       // things that are no longer needed..
+}
+
+int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+               struct drm_mode_create_dumb *args)
+{
+       args->pitch = align_pitch(args->width, args->bpp);
+       args->size  = PAGE_ALIGN(args->pitch * args->height);
+       return msm_gem_new_handle(dev, file, args->size,
+                       MSM_BO_SCANOUT | MSM_BO_WC, &args->handle);
+}
+
+int msm_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+               uint32_t handle)
+{
+       /* No special work needed, drop the reference and see what falls out */
+       return drm_gem_handle_delete(file, handle);
+}
+
+int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
+               uint32_t handle, uint64_t *offset)
+{
+       struct drm_gem_object *obj;
+       int ret = 0;
+
+       /* GEM does all our handle to object mapping */
+       obj = drm_gem_object_lookup(dev, file, handle);
+       if (obj == NULL) {
+               ret = -ENOENT;
+               goto fail;
+       }
+
+       *offset = msm_gem_mmap_offset(obj);
+
+       drm_gem_object_unreference_unlocked(obj);
+
+fail:
+       return ret;
+}
+
+void *msm_gem_vaddr_locked(struct drm_gem_object *obj)
+{
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex));
+       if (!msm_obj->vaddr) {
+               struct page **pages = get_pages(obj);
+               if (IS_ERR(pages))
+                       return ERR_CAST(pages);
+               msm_obj->vaddr = vmap(pages, obj->size >> PAGE_SHIFT,
+                               VM_MAP, pgprot_writecombine(PAGE_KERNEL));
+       }
+       return msm_obj->vaddr;
+}
+
+void *msm_gem_vaddr(struct drm_gem_object *obj)
+{
+       void *ret;
+       mutex_lock(&obj->dev->struct_mutex);
+       ret = msm_gem_vaddr_locked(obj);
+       mutex_unlock(&obj->dev->struct_mutex);
+       return ret;
+}
+
+int msm_gem_queue_inactive_work(struct drm_gem_object *obj,
+               struct work_struct *work)
+{
+       struct drm_device *dev = obj->dev;
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       int ret = 0;
+
+       mutex_lock(&dev->struct_mutex);
+       if (!list_empty(&work->entry)) {
+               ret = -EINVAL;
+       } else if (is_active(msm_obj)) {
+               list_add_tail(&work->entry, &msm_obj->inactive_work);
+       } else {
+               queue_work(priv->wq, work);
+       }
+       mutex_unlock(&dev->struct_mutex);
+
+       return ret;
+}
+
+void msm_gem_move_to_active(struct drm_gem_object *obj,
+               struct msm_gpu *gpu, uint32_t fence)
+{
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       msm_obj->gpu = gpu;
+       msm_obj->fence = fence;
+       list_del_init(&msm_obj->mm_list);
+       list_add_tail(&msm_obj->mm_list, &gpu->active_list);
+}
+
+void msm_gem_move_to_inactive(struct drm_gem_object *obj)
+{
+       struct drm_device *dev = obj->dev;
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+
+       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+       msm_obj->gpu = NULL;
+       msm_obj->fence = 0;
+       list_del_init(&msm_obj->mm_list);
+       list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
+
+       while (!list_empty(&msm_obj->inactive_work)) {
+               struct work_struct *work;
+
+               work = list_first_entry(&msm_obj->inactive_work,
+                               struct work_struct, entry);
+
+               list_del_init(&work->entry);
+               queue_work(priv->wq, work);
+       }
+}
+
+int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op,
+               struct timespec *timeout)
+{
+       struct drm_device *dev = obj->dev;
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       int ret = 0;
+
+       if (is_active(msm_obj) && !(op & MSM_PREP_NOSYNC))
+               ret = msm_wait_fence_interruptable(dev, msm_obj->fence, timeout);
+
+       /* TODO cache maintenance */
+
+       return ret;
+}
+
+int msm_gem_cpu_fini(struct drm_gem_object *obj)
+{
+       /* TODO cache maintenance */
+       return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
+{
+       struct drm_device *dev = obj->dev;
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       uint64_t off = drm_vma_node_start(&obj->vma_node);
+
+       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+       seq_printf(m, "%08x: %c(%d) %2d (%2d) %08llx %p %d\n",
+                       msm_obj->flags, is_active(msm_obj) ? 'A' : 'I',
+                       msm_obj->fence, obj->name, obj->refcount.refcount.counter,
+                       off, msm_obj->vaddr, obj->size);
+}
+
+void msm_gem_describe_objects(struct list_head *list, struct seq_file *m)
+{
+       struct msm_gem_object *msm_obj;
+       int count = 0;
+       size_t size = 0;
+
+       list_for_each_entry(msm_obj, list, mm_list) {
+               struct drm_gem_object *obj = &msm_obj->base;
+               seq_printf(m, "   ");
+               msm_gem_describe(obj, m);
+               count++;
+               size += obj->size;
+       }
+
+       seq_printf(m, "Total %d objects, %zu bytes\n", count, size);
+}
+#endif
+
+void msm_gem_free_object(struct drm_gem_object *obj)
+{
+       struct drm_device *dev = obj->dev;
+       struct msm_gem_object *msm_obj = to_msm_bo(obj);
+       int id;
+
+       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+       /* object should not be on active list: */
+       WARN_ON(is_active(msm_obj));
+
+       list_del(&msm_obj->mm_list);
+
+       for (id = 0; id < ARRAY_SIZE(msm_obj->domain); id++) {
+               if (msm_obj->domain[id].iova) {
+                       struct msm_drm_private *priv = obj->dev->dev_private;
+                       uint32_t offset = (uint32_t)mmap_offset(obj);
+                       unmap_range(priv->iommus[id], offset,
+                                       msm_obj->sgt, obj->size);
+               }
+       }
+
+       drm_gem_free_mmap_offset(obj);
+
+       if (msm_obj->vaddr)
+               vunmap(msm_obj->vaddr);
+
+       put_pages(obj);
+
+       if (msm_obj->resv == &msm_obj->_resv)
+               reservation_object_fini(msm_obj->resv);
+
+       drm_gem_object_release(obj);
+
+       kfree(msm_obj);
+}
+
+/* convenience method to construct a GEM buffer object, and userspace handle */
+int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
+               uint32_t size, uint32_t flags, uint32_t *handle)
+{
+       struct drm_gem_object *obj;
+       int ret;
+
+       ret = mutex_lock_interruptible(&dev->struct_mutex);
+       if (ret)
+               return ret;
+
+       obj = msm_gem_new(dev, size, flags);
+
+       mutex_unlock(&dev->struct_mutex);
+
+       if (IS_ERR(obj))
+               return PTR_ERR(obj);
+
+       ret = drm_gem_handle_create(file, obj, handle);
+
+       /* drop reference from allocate - handle holds it now */
+       drm_gem_object_unreference_unlocked(obj);
+
+       return ret;
+}
+
+struct drm_gem_object *msm_gem_new(struct drm_device *dev,
+               uint32_t size, uint32_t flags)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct msm_gem_object *msm_obj;
+       struct drm_gem_object *obj = NULL;
+       int ret;
+
+       WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
+       size = PAGE_ALIGN(size);
+
+       switch (flags & MSM_BO_CACHE_MASK) {
+       case MSM_BO_UNCACHED:
+       case MSM_BO_CACHED:
+       case MSM_BO_WC:
+               break;
+       default:
+               dev_err(dev->dev, "invalid cache flag: %x\n",
+                               (flags & MSM_BO_CACHE_MASK));
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       msm_obj = kzalloc(sizeof(*msm_obj), GFP_KERNEL);
+       if (!msm_obj) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       obj = &msm_obj->base;
+
+       ret = drm_gem_object_init(dev, obj, size);
+       if (ret)
+               goto fail;
+
+       msm_obj->flags = flags;
+
+       msm_obj->resv = &msm_obj->_resv;
+       reservation_object_init(msm_obj->resv);
+
+       INIT_LIST_HEAD(&msm_obj->submit_entry);
+       INIT_LIST_HEAD(&msm_obj->inactive_work);
+       list_add_tail(&msm_obj->mm_list, &priv->inactive_list);
+
+       return obj;
+
+fail:
+       if (obj)
+               drm_gem_object_unreference_unlocked(obj);
+
+       return ERR_PTR(ret);
+}
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
new file mode 100644 (file)
index 0000000..d746f13
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MSM_GEM_H__
+#define __MSM_GEM_H__
+
+#include <linux/reservation.h>
+#include "msm_drv.h"
+
+struct msm_gem_object {
+       struct drm_gem_object base;
+
+       uint32_t flags;
+
+       /* And object is either:
+        *  inactive - on priv->inactive_list
+        *  active   - on one one of the gpu's active_list..  well, at
+        *     least for now we don't have (I don't think) hw sync between
+        *     2d and 3d one devices which have both, meaning we need to
+        *     block on submit if a bo is already on other ring
+        *
+        */
+       struct list_head mm_list;
+       struct msm_gpu *gpu;     /* non-null if active */
+       uint32_t fence;
+
+       /* Transiently in the process of submit ioctl, objects associated
+        * with the submit are on submit->bo_list.. this only lasts for
+        * the duration of the ioctl, so one bo can never be on multiple
+        * submit lists.
+        */
+       struct list_head submit_entry;
+
+       /* work defered until bo is inactive: */
+       struct list_head inactive_work;
+
+       struct page **pages;
+       struct sg_table *sgt;
+       void *vaddr;
+
+       struct {
+               // XXX
+               uint32_t iova;
+       } domain[NUM_DOMAINS];
+
+       /* normally (resv == &_resv) except for imported bo's */
+       struct reservation_object *resv;
+       struct reservation_object _resv;
+};
+#define to_msm_bo(x) container_of(x, struct msm_gem_object, base)
+
+static inline bool is_active(struct msm_gem_object *msm_obj)
+{
+       return msm_obj->gpu != NULL;
+}
+
+#define MAX_CMDS 4
+
+/* Created per submit-ioctl, to track bo's and cmdstream bufs, etc,
+ * associated with the cmdstream submission for synchronization (and
+ * make it easier to unwind when things go wrong, etc).  This only
+ * lasts for the duration of the submit-ioctl.
+ */
+struct msm_gem_submit {
+       struct drm_device *dev;
+       struct msm_gpu *gpu;
+       struct list_head bo_list;
+       struct ww_acquire_ctx ticket;
+       uint32_t fence;
+       bool valid;
+       unsigned int nr_cmds;
+       unsigned int nr_bos;
+       struct {
+               uint32_t type;
+               uint32_t size;  /* in dwords */
+               uint32_t iova;
+       } cmd[MAX_CMDS];
+       struct {
+               uint32_t flags;
+               struct msm_gem_object *obj;
+               uint32_t iova;
+       } bos[0];
+};
+
+#endif /* __MSM_GEM_H__ */
diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c
new file mode 100644 (file)
index 0000000..3e1ef3a
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "msm_drv.h"
+#include "msm_gpu.h"
+#include "msm_gem.h"
+
+/*
+ * Cmdstream submission:
+ */
+
+#define BO_INVALID_FLAGS ~(MSM_SUBMIT_BO_READ | MSM_SUBMIT_BO_WRITE)
+/* make sure these don't conflict w/ MSM_SUBMIT_BO_x */
+#define BO_VALID    0x8000
+#define BO_LOCKED   0x4000
+#define BO_PINNED   0x2000
+
+static inline void __user *to_user_ptr(u64 address)
+{
+       return (void __user *)(uintptr_t)address;
+}
+
+static struct msm_gem_submit *submit_create(struct drm_device *dev,
+               struct msm_gpu *gpu, int nr)
+{
+       struct msm_gem_submit *submit;
+       int sz = sizeof(*submit) + (nr * sizeof(submit->bos[0]));
+
+       submit = kmalloc(sz, GFP_TEMPORARY | __GFP_NOWARN | __GFP_NORETRY);
+       if (submit) {
+               submit->dev = dev;
+               submit->gpu = gpu;
+
+               /* initially, until copy_from_user() and bo lookup succeeds: */
+               submit->nr_bos = 0;
+               submit->nr_cmds = 0;
+
+               INIT_LIST_HEAD(&submit->bo_list);
+               ww_acquire_init(&submit->ticket, &reservation_ww_class);
+       }
+
+       return submit;
+}
+
+static int submit_lookup_objects(struct msm_gem_submit *submit,
+               struct drm_msm_gem_submit *args, struct drm_file *file)
+{
+       unsigned i;
+       int ret = 0;
+
+       spin_lock(&file->table_lock);
+
+       for (i = 0; i < args->nr_bos; i++) {
+               struct drm_msm_gem_submit_bo submit_bo;
+               struct drm_gem_object *obj;
+               struct msm_gem_object *msm_obj;
+               void __user *userptr =
+                       to_user_ptr(args->bos + (i * sizeof(submit_bo)));
+
+               ret = copy_from_user(&submit_bo, userptr, sizeof(submit_bo));
+               if (ret) {
+                       ret = -EFAULT;
+                       goto out_unlock;
+               }
+
+               if (submit_bo.flags & BO_INVALID_FLAGS) {
+                       DBG("invalid flags: %x", submit_bo.flags);
+                       ret = -EINVAL;
+                       goto out_unlock;
+               }
+
+               submit->bos[i].flags = submit_bo.flags;
+               /* in validate_objects() we figure out if this is true: */
+               submit->bos[i].iova  = submit_bo.presumed;
+
+               /* normally use drm_gem_object_lookup(), but for bulk lookup
+                * all under single table_lock just hit object_idr directly:
+                */
+               obj = idr_find(&file->object_idr, submit_bo.handle);
+               if (!obj) {
+                       DBG("invalid handle %u at index %u", submit_bo.handle, i);
+                       ret = -EINVAL;
+                       goto out_unlock;
+               }
+
+               msm_obj = to_msm_bo(obj);
+
+               if (!list_empty(&msm_obj->submit_entry)) {
+                       DBG("handle %u at index %u already on submit list",
+                                       submit_bo.handle, i);
+                       ret = -EINVAL;
+                       goto out_unlock;
+               }
+
+               drm_gem_object_reference(obj);
+
+               submit->bos[i].obj = msm_obj;
+
+               list_add_tail(&msm_obj->submit_entry, &submit->bo_list);
+       }
+
+out_unlock:
+       submit->nr_bos = i;
+       spin_unlock(&file->table_lock);
+
+       return ret;
+}
+
+static void submit_unlock_unpin_bo(struct msm_gem_submit *submit, int i)
+{
+       struct msm_gem_object *msm_obj = submit->bos[i].obj;
+
+       if (submit->bos[i].flags & BO_PINNED)
+               msm_gem_put_iova(&msm_obj->base, submit->gpu->id);
+
+       if (submit->bos[i].flags & BO_LOCKED)
+               ww_mutex_unlock(&msm_obj->resv->lock);
+
+       if (!(submit->bos[i].flags & BO_VALID))
+               submit->bos[i].iova = 0;
+
+       submit->bos[i].flags &= ~(BO_LOCKED | BO_PINNED);
+}
+
+/* This is where we make sure all the bo's are reserved and pin'd: */
+static int submit_validate_objects(struct msm_gem_submit *submit)
+{
+       int contended, slow_locked = -1, i, ret = 0;
+
+retry:
+       submit->valid = true;
+
+       for (i = 0; i < submit->nr_bos; i++) {
+               struct msm_gem_object *msm_obj = submit->bos[i].obj;
+               uint32_t iova;
+
+               if (slow_locked == i)
+                       slow_locked = -1;
+
+               contended = i;
+
+               if (!(submit->bos[i].flags & BO_LOCKED)) {
+                       ret = ww_mutex_lock_interruptible(&msm_obj->resv->lock,
+                                       &submit->ticket);
+                       if (ret)
+                               goto fail;
+                       submit->bos[i].flags |= BO_LOCKED;
+               }
+
+
+               /* if locking succeeded, pin bo: */
+               ret = msm_gem_get_iova(&msm_obj->base,
+                               submit->gpu->id, &iova);
+
+               /* this would break the logic in the fail path.. there is no
+                * reason for this to happen, but just to be on the safe side
+                * let's notice if this starts happening in the future:
+                */
+               WARN_ON(ret == -EDEADLK);
+
+               if (ret)
+                       goto fail;
+
+               submit->bos[i].flags |= BO_PINNED;
+
+               if (iova == submit->bos[i].iova) {
+                       submit->bos[i].flags |= BO_VALID;
+               } else {
+                       submit->bos[i].iova = iova;
+                       submit->bos[i].flags &= ~BO_VALID;
+                       submit->valid = false;
+               }
+       }
+
+       ww_acquire_done(&submit->ticket);
+
+       return 0;
+
+fail:
+       for (; i >= 0; i--)
+               submit_unlock_unpin_bo(submit, i);
+
+       if (slow_locked > 0)
+               submit_unlock_unpin_bo(submit, slow_locked);
+
+       if (ret == -EDEADLK) {
+               struct msm_gem_object *msm_obj = submit->bos[contended].obj;
+               /* we lost out in a seqno race, lock and retry.. */
+               ret = ww_mutex_lock_slow_interruptible(&msm_obj->resv->lock,
+                               &submit->ticket);
+               if (!ret) {
+                       submit->bos[contended].flags |= BO_LOCKED;
+                       slow_locked = contended;
+                       goto retry;
+               }
+       }
+
+       return ret;
+}
+
+static int submit_bo(struct msm_gem_submit *submit, uint32_t idx,
+               struct msm_gem_object **obj, uint32_t *iova, bool *valid)
+{
+       if (idx >= submit->nr_bos) {
+               DBG("invalid buffer index: %u (out of %u)", idx, submit->nr_bos);
+               return EINVAL;
+       }
+
+       if (obj)
+               *obj = submit->bos[idx].obj;
+       if (iova)
+               *iova = submit->bos[idx].iova;
+       if (valid)
+               *valid = !!(submit->bos[idx].flags & BO_VALID);
+
+       return 0;
+}
+
+/* process the reloc's and patch up the cmdstream as needed: */
+static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *obj,
+               uint32_t offset, uint32_t nr_relocs, uint64_t relocs)
+{
+       uint32_t i, last_offset = 0;
+       uint32_t *ptr;
+       int ret;
+
+       if (offset % 4) {
+               DBG("non-aligned cmdstream buffer: %u", offset);
+               return -EINVAL;
+       }
+
+       /* For now, just map the entire thing.  Eventually we probably
+        * to do it page-by-page, w/ kmap() if not vmap()d..
+        */
+       ptr = msm_gem_vaddr(&obj->base);
+
+       if (IS_ERR(ptr)) {
+               ret = PTR_ERR(ptr);
+               DBG("failed to map: %d", ret);
+               return ret;
+       }
+
+       for (i = 0; i < nr_relocs; i++) {
+               struct drm_msm_gem_submit_reloc submit_reloc;
+               void __user *userptr =
+                       to_user_ptr(relocs + (i * sizeof(submit_reloc)));
+               uint32_t iova, off;
+               bool valid;
+
+               ret = copy_from_user(&submit_reloc, userptr, sizeof(submit_reloc));
+               if (ret)
+                       return -EFAULT;
+
+               if (submit_reloc.submit_offset % 4) {
+                       DBG("non-aligned reloc offset: %u",
+                                       submit_reloc.submit_offset);
+                       return -EINVAL;
+               }
+
+               /* offset in dwords: */
+               off = submit_reloc.submit_offset / 4;
+
+               if ((off >= (obj->base.size / 4)) ||
+                               (off < last_offset)) {
+                       DBG("invalid offset %u at reloc %u", off, i);
+                       return -EINVAL;
+               }
+
+               ret = submit_bo(submit, submit_reloc.reloc_idx, NULL, &iova, &valid);
+               if (ret)
+                       return ret;
+
+               if (valid)
+                       continue;
+
+               iova += submit_reloc.reloc_offset;
+
+               if (submit_reloc.shift < 0)
+                       iova >>= -submit_reloc.shift;
+               else
+                       iova <<= submit_reloc.shift;
+
+               ptr[off] = iova | submit_reloc.or;
+
+               last_offset = off;
+       }
+
+       return 0;
+}
+
+static void submit_cleanup(struct msm_gem_submit *submit, bool fail)
+{
+       unsigned i;
+
+       mutex_lock(&submit->dev->struct_mutex);
+       for (i = 0; i < submit->nr_bos; i++) {
+               struct msm_gem_object *msm_obj = submit->bos[i].obj;
+               submit_unlock_unpin_bo(submit, i);
+               list_del_init(&msm_obj->submit_entry);
+               drm_gem_object_unreference(&msm_obj->base);
+       }
+       mutex_unlock(&submit->dev->struct_mutex);
+
+       ww_acquire_fini(&submit->ticket);
+       kfree(submit);
+}
+
+int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
+               struct drm_file *file)
+{
+       struct msm_drm_private *priv = dev->dev_private;
+       struct drm_msm_gem_submit *args = data;
+       struct msm_file_private *ctx = file->driver_priv;
+       struct msm_gem_submit *submit;
+       struct msm_gpu *gpu;
+       unsigned i;
+       int ret;
+
+       /* for now, we just have 3d pipe.. eventually this would need to
+        * be more clever to dispatch to appropriate gpu module:
+        */
+       if (args->pipe != MSM_PIPE_3D0)
+               return -EINVAL;
+
+       gpu = priv->gpu;
+
+       if (args->nr_cmds > MAX_CMDS)
+               return -EINVAL;
+
+       submit = submit_create(dev, gpu, args->nr_bos);
+       if (!submit) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = submit_lookup_objects(submit, args, file);
+       if (ret)
+               goto out;
+
+       ret = submit_validate_objects(submit);
+       if (ret)
+               goto out;
+
+       for (i = 0; i < args->nr_cmds; i++) {
+               struct drm_msm_gem_submit_cmd submit_cmd;
+               void __user *userptr =
+                       to_user_ptr(args->cmds + (i * sizeof(submit_cmd)));
+               struct msm_gem_object *msm_obj;
+               uint32_t iova;
+
+               ret = copy_from_user(&submit_cmd, userptr, sizeof(submit_cmd));
+               if (ret) {
+                       ret = -EFAULT;
+                       goto out;
+               }
+
+               ret = submit_bo(submit, submit_cmd.submit_idx,
+                               &msm_obj, &iova, NULL);
+               if (ret)
+                       goto out;
+
+               if (submit_cmd.size % 4) {
+                       DBG("non-aligned cmdstream buffer size: %u",
+                                       submit_cmd.size);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               if (submit_cmd.size >= msm_obj->base.size) {
+                       DBG("invalid cmdstream size: %u", submit_cmd.size);
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               submit->cmd[i].type = submit_cmd.type;
+               submit->cmd[i].size = submit_cmd.size / 4;
+               submit->cmd[i].iova = iova + submit_cmd.submit_offset;
+
+               if (submit->valid)
+                       continue;
+
+               ret = submit_reloc(submit, msm_obj, submit_cmd.submit_offset,
+                               submit_cmd.nr_relocs, submit_cmd.relocs);
+               if (ret)
+                       goto out;
+       }
+
+       submit->nr_cmds = i;
+
+       ret = msm_gpu_submit(gpu, submit, ctx);
+
+       args->fence = submit->fence;
+
+out:
+       if (submit)
+               submit_cleanup(submit, !!ret);
+       return ret;
+}
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
new file mode 100644 (file)
index 0000000..e1e1ec9
--- /dev/null
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "msm_gpu.h"
+#include "msm_gem.h"
+
+
+/*
+ * Power Management:
+ */
+
+#ifdef CONFIG_MSM_BUS_SCALING
+#include <mach/board.h>
+#include <mach/kgsl.h>
+static void bs_init(struct msm_gpu *gpu, struct platform_device *pdev)
+{
+       struct drm_device *dev = gpu->dev;
+       struct kgsl_device_platform_data *pdata = pdev->dev.platform_data;
+
+       if (!pdev) {
+               dev_err(dev->dev, "could not find dtv pdata\n");
+               return;
+       }
+
+       if (pdata->bus_scale_table) {
+               gpu->bsc = msm_bus_scale_register_client(pdata->bus_scale_table);
+               DBG("bus scale client: %08x", gpu->bsc);
+       }
+}
+
+static void bs_fini(struct msm_gpu *gpu)
+{
+       if (gpu->bsc) {
+               msm_bus_scale_unregister_client(gpu->bsc);
+               gpu->bsc = 0;
+       }
+}
+
+static void bs_set(struct msm_gpu *gpu, int idx)
+{
+       if (gpu->bsc) {
+               DBG("set bus scaling: %d", idx);
+               msm_bus_scale_client_update_request(gpu->bsc, idx);
+       }
+}
+#else
+static void bs_init(struct msm_gpu *gpu, struct platform_device *pdev) {}
+static void bs_fini(struct msm_gpu *gpu) {}
+static void bs_set(struct msm_gpu *gpu, int idx) {}
+#endif
+
+static int enable_pwrrail(struct msm_gpu *gpu)
+{
+       struct drm_device *dev = gpu->dev;
+       int ret = 0;
+
+       if (gpu->gpu_reg) {
+               ret = regulator_enable(gpu->gpu_reg);
+               if (ret) {
+                       dev_err(dev->dev, "failed to enable 'gpu_reg': %d\n", ret);
+                       return ret;
+               }
+       }
+
+       if (gpu->gpu_cx) {
+               ret = regulator_enable(gpu->gpu_cx);
+               if (ret) {
+                       dev_err(dev->dev, "failed to enable 'gpu_cx': %d\n", ret);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int disable_pwrrail(struct msm_gpu *gpu)
+{
+       if (gpu->gpu_cx)
+               regulator_disable(gpu->gpu_cx);
+       if (gpu->gpu_reg)
+               regulator_disable(gpu->gpu_reg);
+       return 0;
+}
+
+static int enable_clk(struct msm_gpu *gpu)
+{
+       struct clk *rate_clk = NULL;
+       int i;
+
+       /* NOTE: kgsl_pwrctrl_clk() ignores grp_clks[0].. */
+       for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i > 0; i--) {
+               if (gpu->grp_clks[i]) {
+                       clk_prepare(gpu->grp_clks[i]);
+                       rate_clk = gpu->grp_clks[i];
+               }
+       }
+
+       if (rate_clk && gpu->fast_rate)
+               clk_set_rate(rate_clk, gpu->fast_rate);
+
+       for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i > 0; i--)
+               if (gpu->grp_clks[i])
+                       clk_enable(gpu->grp_clks[i]);
+
+       return 0;
+}
+
+static int disable_clk(struct msm_gpu *gpu)
+{
+       struct clk *rate_clk = NULL;
+       int i;
+
+       /* NOTE: kgsl_pwrctrl_clk() ignores grp_clks[0].. */
+       for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i > 0; i--) {
+               if (gpu->grp_clks[i]) {
+                       clk_disable(gpu->grp_clks[i]);
+                       rate_clk = gpu->grp_clks[i];
+               }
+       }
+
+       if (rate_clk && gpu->slow_rate)
+               clk_set_rate(rate_clk, gpu->slow_rate);
+
+       for (i = ARRAY_SIZE(gpu->grp_clks) - 1; i > 0; i--)
+               if (gpu->grp_clks[i])
+                       clk_unprepare(gpu->grp_clks[i]);
+
+       return 0;
+}
+
+static int enable_axi(struct msm_gpu *gpu)
+{
+       if (gpu->ebi1_clk)
+               clk_prepare_enable(gpu->ebi1_clk);
+       if (gpu->bus_freq)
+               bs_set(gpu, gpu->bus_freq);
+       return 0;
+}
+
+static int disable_axi(struct msm_gpu *gpu)
+{
+       if (gpu->ebi1_clk)
+               clk_disable_unprepare(gpu->ebi1_clk);
+       if (gpu->bus_freq)
+               bs_set(gpu, 0);
+       return 0;
+}
+
+int msm_gpu_pm_resume(struct msm_gpu *gpu)
+{
+       int ret;
+
+       DBG("%s", gpu->name);
+
+       ret = enable_pwrrail(gpu);
+       if (ret)
+               return ret;
+
+       ret = enable_clk(gpu);
+       if (ret)
+               return ret;
+
+       ret = enable_axi(gpu);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+int msm_gpu_pm_suspend(struct msm_gpu *gpu)
+{
+       int ret;
+
+       DBG("%s", gpu->name);
+
+       ret = disable_axi(gpu);
+       if (ret)
+               return ret;
+
+       ret = disable_clk(gpu);
+       if (ret)
+               return ret;
+
+       ret = disable_pwrrail(gpu);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+/*
+ * Hangcheck detection for locked gpu:
+ */
+
+static void recover_worker(struct work_struct *work)
+{
+       struct msm_gpu *gpu = container_of(work, struct msm_gpu, recover_work);
+       struct drm_device *dev = gpu->dev;
+
+       dev_err(dev->dev, "%s: hangcheck recover!\n", gpu->name);
+
+       mutex_lock(&dev->struct_mutex);
+       gpu->funcs->recover(gpu);
+       mutex_unlock(&dev->struct_mutex);
+
+       msm_gpu_retire(gpu);
+}
+
+static void hangcheck_timer_reset(struct msm_gpu *gpu)
+{
+       DBG("%s", gpu->name);
+       mod_timer(&gpu->hangcheck_timer,
+                       round_jiffies_up(jiffies + DRM_MSM_HANGCHECK_JIFFIES));
+}
+
+static void hangcheck_handler(unsigned long data)
+{
+       struct msm_gpu *gpu = (struct msm_gpu *)data;
+       uint32_t fence = gpu->funcs->last_fence(gpu);
+
+       if (fence != gpu->hangcheck_fence) {
+               /* some progress has been made.. ya! */
+               gpu->hangcheck_fence = fence;
+       } else if (fence < gpu->submitted_fence) {
+               /* no progress and not done.. hung! */
+               struct msm_drm_private *priv = gpu->dev->dev_private;
+               gpu->hangcheck_fence = fence;
+               queue_work(priv->wq, &gpu->recover_work);
+       }
+
+       /* if still more pending work, reset the hangcheck timer: */
+       if (gpu->submitted_fence > gpu->hangcheck_fence)
+               hangcheck_timer_reset(gpu);
+}
+
+/*
+ * Cmdstream submission/retirement:
+ */
+
+static void retire_worker(struct work_struct *work)
+{
+       struct msm_gpu *gpu = container_of(work, struct msm_gpu, retire_work);
+       struct drm_device *dev = gpu->dev;
+       uint32_t fence = gpu->funcs->last_fence(gpu);
+
+       mutex_lock(&dev->struct_mutex);
+
+       while (!list_empty(&gpu->active_list)) {
+               struct msm_gem_object *obj;
+
+               obj = list_first_entry(&gpu->active_list,
+                               struct msm_gem_object, mm_list);
+
+               if (obj->fence <= fence) {
+                       /* move to inactive: */
+                       msm_gem_move_to_inactive(&obj->base);
+                       msm_gem_put_iova(&obj->base, gpu->id);
+                       drm_gem_object_unreference(&obj->base);
+               } else {
+                       break;
+               }
+       }
+
+       msm_update_fence(gpu->dev, fence);
+
+       mutex_unlock(&dev->struct_mutex);
+}
+
+/* call from irq handler to schedule work to retire bo's */
+void msm_gpu_retire(struct msm_gpu *gpu)
+{
+       struct msm_drm_private *priv = gpu->dev->dev_private;
+       queue_work(priv->wq, &gpu->retire_work);
+}
+
+/* add bo's to gpu's ring, and kick gpu: */
+int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
+               struct msm_file_private *ctx)
+{
+       struct drm_device *dev = gpu->dev;
+       struct msm_drm_private *priv = dev->dev_private;
+       int i, ret;
+
+       mutex_lock(&dev->struct_mutex);
+
+       submit->fence = ++priv->next_fence;
+
+       gpu->submitted_fence = submit->fence;
+
+       ret = gpu->funcs->submit(gpu, submit, ctx);
+       priv->lastctx = ctx;
+
+       for (i = 0; i < submit->nr_bos; i++) {
+               struct msm_gem_object *msm_obj = submit->bos[i].obj;
+
+               /* can't happen yet.. but when we add 2d support we'll have
+                * to deal w/ cross-ring synchronization:
+                */
+               WARN_ON(is_active(msm_obj) && (msm_obj->gpu != gpu));
+
+               if (!is_active(msm_obj)) {
+                       uint32_t iova;
+
+                       /* ring takes a reference to the bo and iova: */
+                       drm_gem_object_reference(&msm_obj->base);
+                       msm_gem_get_iova_locked(&msm_obj->base,
+                                       submit->gpu->id, &iova);
+               }
+
+               msm_gem_move_to_active(&msm_obj->base, gpu, submit->fence);
+       }
+       hangcheck_timer_reset(gpu);
+       mutex_unlock(&dev->struct_mutex);
+
+       return ret;
+}
+
+/*
+ * Init/Cleanup:
+ */
+
+static irqreturn_t irq_handler(int irq, void *data)
+{
+       struct msm_gpu *gpu = data;
+       return gpu->funcs->irq(gpu);
+}
+
+static const char *clk_names[] = {
+               "src_clk", "core_clk", "iface_clk", "mem_clk", "mem_iface_clk",
+};
+
+int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+               struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
+               const char *name, const char *ioname, const char *irqname, int ringsz)
+{
+       int i, ret;
+
+       gpu->dev = drm;
+       gpu->funcs = funcs;
+       gpu->name = name;
+
+       INIT_LIST_HEAD(&gpu->active_list);
+       INIT_WORK(&gpu->retire_work, retire_worker);
+       INIT_WORK(&gpu->recover_work, recover_worker);
+
+       setup_timer(&gpu->hangcheck_timer, hangcheck_handler,
+                       (unsigned long)gpu);
+
+       BUG_ON(ARRAY_SIZE(clk_names) != ARRAY_SIZE(gpu->grp_clks));
+
+       /* Map registers: */
+       gpu->mmio = msm_ioremap(pdev, ioname, name);
+       if (IS_ERR(gpu->mmio)) {
+               ret = PTR_ERR(gpu->mmio);
+               goto fail;
+       }
+
+       /* Get Interrupt: */
+       gpu->irq = platform_get_irq_byname(pdev, irqname);
+       if (gpu->irq < 0) {
+               ret = gpu->irq;
+               dev_err(drm->dev, "failed to get irq: %d\n", ret);
+               goto fail;
+       }
+
+       ret = devm_request_irq(&pdev->dev, gpu->irq, irq_handler,
+                       IRQF_TRIGGER_HIGH, gpu->name, gpu);
+       if (ret) {
+               dev_err(drm->dev, "failed to request IRQ%u: %d\n", gpu->irq, ret);
+               goto fail;
+       }
+
+       /* Acquire clocks: */
+       for (i = 0; i < ARRAY_SIZE(clk_names); i++) {
+               gpu->grp_clks[i] = devm_clk_get(&pdev->dev, clk_names[i]);
+               DBG("grp_clks[%s]: %p", clk_names[i], gpu->grp_clks[i]);
+               if (IS_ERR(gpu->grp_clks[i]))
+                       gpu->grp_clks[i] = NULL;
+       }
+
+       gpu->ebi1_clk = devm_clk_get(&pdev->dev, "bus_clk");
+       DBG("ebi1_clk: %p", gpu->ebi1_clk);
+       if (IS_ERR(gpu->ebi1_clk))
+               gpu->ebi1_clk = NULL;
+
+       /* Acquire regulators: */
+       gpu->gpu_reg = devm_regulator_get(&pdev->dev, "vdd");
+       DBG("gpu_reg: %p", gpu->gpu_reg);
+       if (IS_ERR(gpu->gpu_reg))
+               gpu->gpu_reg = NULL;
+
+       gpu->gpu_cx = devm_regulator_get(&pdev->dev, "vddcx");
+       DBG("gpu_cx: %p", gpu->gpu_cx);
+       if (IS_ERR(gpu->gpu_cx))
+               gpu->gpu_cx = NULL;
+
+       /* Setup IOMMU.. eventually we will (I think) do this once per context
+        * and have separate page tables per context.  For now, to keep things
+        * simple and to get something working, just use a single address space:
+        */
+       gpu->iommu = iommu_domain_alloc(&platform_bus_type);
+       if (!gpu->iommu) {
+               dev_err(drm->dev, "failed to allocate IOMMU\n");
+               ret = -ENOMEM;
+               goto fail;
+       }
+       gpu->id = msm_register_iommu(drm, gpu->iommu);
+
+       /* Create ringbuffer: */
+       gpu->rb = msm_ringbuffer_new(gpu, ringsz);
+       if (IS_ERR(gpu->rb)) {
+               ret = PTR_ERR(gpu->rb);
+               gpu->rb = NULL;
+               dev_err(drm->dev, "could not create ringbuffer: %d\n", ret);
+               goto fail;
+       }
+
+       ret = msm_gem_get_iova_locked(gpu->rb->bo, gpu->id, &gpu->rb_iova);
+       if (ret) {
+               gpu->rb_iova = 0;
+               dev_err(drm->dev, "could not map ringbuffer: %d\n", ret);
+               goto fail;
+       }
+
+       bs_init(gpu, pdev);
+
+       return 0;
+
+fail:
+       return ret;
+}
+
+void msm_gpu_cleanup(struct msm_gpu *gpu)
+{
+       DBG("%s", gpu->name);
+
+       WARN_ON(!list_empty(&gpu->active_list));
+
+       bs_fini(gpu);
+
+       if (gpu->rb) {
+               if (gpu->rb_iova)
+                       msm_gem_put_iova(gpu->rb->bo, gpu->id);
+               msm_ringbuffer_destroy(gpu->rb);
+       }
+
+       if (gpu->iommu)
+               iommu_domain_free(gpu->iommu);
+}
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
new file mode 100644 (file)
index 0000000..8cd829e
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MSM_GPU_H__
+#define __MSM_GPU_H__
+
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+
+#include "msm_drv.h"
+#include "msm_ringbuffer.h"
+
+struct msm_gem_submit;
+
+/* So far, with hardware that I've seen to date, we can have:
+ *  + zero, one, or two z180 2d cores
+ *  + a3xx or a2xx 3d core, which share a common CP (the firmware
+ *    for the CP seems to implement some different PM4 packet types
+ *    but the basics of cmdstream submission are the same)
+ *
+ * Which means that the eventual complete "class" hierarchy, once
+ * support for all past and present hw is in place, becomes:
+ *  + msm_gpu
+ *    + adreno_gpu
+ *      + a3xx_gpu
+ *      + a2xx_gpu
+ *    + z180_gpu
+ */
+struct msm_gpu_funcs {
+       int (*get_param)(struct msm_gpu *gpu, uint32_t param, uint64_t *value);
+       int (*hw_init)(struct msm_gpu *gpu);
+       int (*pm_suspend)(struct msm_gpu *gpu);
+       int (*pm_resume)(struct msm_gpu *gpu);
+       int (*submit)(struct msm_gpu *gpu, struct msm_gem_submit *submit,
+                       struct msm_file_private *ctx);
+       void (*flush)(struct msm_gpu *gpu);
+       void (*idle)(struct msm_gpu *gpu);
+       irqreturn_t (*irq)(struct msm_gpu *irq);
+       uint32_t (*last_fence)(struct msm_gpu *gpu);
+       void (*recover)(struct msm_gpu *gpu);
+       void (*destroy)(struct msm_gpu *gpu);
+#ifdef CONFIG_DEBUG_FS
+       /* show GPU status in debugfs: */
+       void (*show)(struct msm_gpu *gpu, struct seq_file *m);
+#endif
+};
+
+struct msm_gpu {
+       const char *name;
+       struct drm_device *dev;
+       const struct msm_gpu_funcs *funcs;
+
+       struct msm_ringbuffer *rb;
+       uint32_t rb_iova;
+
+       /* list of GEM active objects: */
+       struct list_head active_list;
+
+       uint32_t submitted_fence;
+
+       /* worker for handling active-list retiring: */
+       struct work_struct retire_work;
+
+       void __iomem *mmio;
+       int irq;
+
+       struct iommu_domain *iommu;
+       int id;
+
+       /* Power Control: */
+       struct regulator *gpu_reg, *gpu_cx;
+       struct clk *ebi1_clk, *grp_clks[5];
+       uint32_t fast_rate, slow_rate, bus_freq;
+       uint32_t bsc;
+
+       /* Hang Detction: */
+#define DRM_MSM_HANGCHECK_PERIOD 500 /* in ms */
+#define DRM_MSM_HANGCHECK_JIFFIES msecs_to_jiffies(DRM_MSM_HANGCHECK_PERIOD)
+       struct timer_list hangcheck_timer;
+       uint32_t hangcheck_fence;
+       struct work_struct recover_work;
+};
+
+static inline void gpu_write(struct msm_gpu *gpu, u32 reg, u32 data)
+{
+       msm_writel(data, gpu->mmio + (reg << 2));
+}
+
+static inline u32 gpu_read(struct msm_gpu *gpu, u32 reg)
+{
+       return msm_readl(gpu->mmio + (reg << 2));
+}
+
+int msm_gpu_pm_suspend(struct msm_gpu *gpu);
+int msm_gpu_pm_resume(struct msm_gpu *gpu);
+
+void msm_gpu_retire(struct msm_gpu *gpu);
+int msm_gpu_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit,
+               struct msm_file_private *ctx);
+
+int msm_gpu_init(struct drm_device *drm, struct platform_device *pdev,
+               struct msm_gpu *gpu, const struct msm_gpu_funcs *funcs,
+               const char *name, const char *ioname, const char *irqname, int ringsz);
+void msm_gpu_cleanup(struct msm_gpu *gpu);
+
+struct msm_gpu *a3xx_gpu_init(struct drm_device *dev);
+void __init a3xx_register(void);
+void __exit a3xx_unregister(void);
+
+#endif /* __MSM_GPU_H__ */
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c
new file mode 100644 (file)
index 0000000..8171537
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "msm_ringbuffer.h"
+#include "msm_gpu.h"
+
+struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size)
+{
+       struct msm_ringbuffer *ring;
+       int ret;
+
+       size = ALIGN(size, 4);   /* size should be dword aligned */
+
+       ring = kzalloc(sizeof(*ring), GFP_KERNEL);
+       if (!ring) {
+               ret = -ENOMEM;
+               goto fail;
+       }
+
+       ring->gpu = gpu;
+       ring->bo = msm_gem_new(gpu->dev, size, MSM_BO_WC);
+       if (IS_ERR(ring->bo)) {
+               ret = PTR_ERR(ring->bo);
+               ring->bo = NULL;
+               goto fail;
+       }
+
+       ring->start = msm_gem_vaddr_locked(ring->bo);
+       ring->end   = ring->start + (size / 4);
+       ring->cur   = ring->start;
+
+       ring->size = size;
+
+       return ring;
+
+fail:
+       if (ring)
+               msm_ringbuffer_destroy(ring);
+       return ERR_PTR(ret);
+}
+
+void msm_ringbuffer_destroy(struct msm_ringbuffer *ring)
+{
+       if (ring->bo)
+               drm_gem_object_unreference(ring->bo);
+       kfree(ring);
+}
diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.h b/drivers/gpu/drm/msm/msm_ringbuffer.h
new file mode 100644 (file)
index 0000000..6e0e104
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MSM_RINGBUFFER_H__
+#define __MSM_RINGBUFFER_H__
+
+#include "msm_drv.h"
+
+struct msm_ringbuffer {
+       struct msm_gpu *gpu;
+       int size;
+       struct drm_gem_object *bo;
+       uint32_t *start, *end, *cur;
+};
+
+struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int size);
+void msm_ringbuffer_destroy(struct msm_ringbuffer *ring);
+
+/* ringbuffer helpers (the parts that are same for a3xx/a2xx/z180..) */
+
+static inline void
+OUT_RING(struct msm_ringbuffer *ring, uint32_t data)
+{
+       if (ring->cur == ring->end)
+               ring->cur = ring->start;
+       *(ring->cur++) = data;
+}
+
+#endif /* __MSM_RINGBUFFER_H__ */
index 119487e05e65aa8bdf653c6dc8b94eb25155daed..2d9a25daab0542a4275f6be5343c031daa1144f1 100644 (file)
@@ -16,3 +16,4 @@ header-y += sis_drm.h
 header-y += tegra_drm.h
 header-y += via_drm.h
 header-y += vmwgfx_drm.h
+header-y += msm_drm.h
diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h
new file mode 100644 (file)
index 0000000..d3c6207
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ * Author: Rob Clark <robdclark@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MSM_DRM_H__
+#define __MSM_DRM_H__
+
+#include <stddef.h>
+#include <drm/drm.h>
+
+/* Please note that modifications to all structs defined here are
+ * subject to backwards-compatibility constraints:
+ *  1) Do not use pointers, use uint64_t instead for 32 bit / 64 bit
+ *     user/kernel compatibility
+ *  2) Keep fields aligned to their size
+ *  3) Because of how drm_ioctl() works, we can add new fields at
+ *     the end of an ioctl if some care is taken: drm_ioctl() will
+ *     zero out the new fields at the tail of the ioctl, so a zero
+ *     value should have a backwards compatible meaning.  And for
+ *     output params, userspace won't see the newly added output
+ *     fields.. so that has to be somehow ok.
+ */
+
+#define MSM_PIPE_NONE        0x00
+#define MSM_PIPE_2D0         0x01
+#define MSM_PIPE_2D1         0x02
+#define MSM_PIPE_3D0         0x10
+
+/* timeouts are specified in clock-monotonic absolute times (to simplify
+ * restarting interrupted ioctls).  The following struct is logically the
+ * same as 'struct timespec' but 32/64b ABI safe.
+ */
+struct drm_msm_timespec {
+       int64_t tv_sec;          /* seconds */
+       int64_t tv_nsec;         /* nanoseconds */
+};
+
+#define MSM_PARAM_GPU_ID     0x01
+#define MSM_PARAM_GMEM_SIZE  0x02
+
+struct drm_msm_param {
+       uint32_t pipe;           /* in, MSM_PIPE_x */
+       uint32_t param;          /* in, MSM_PARAM_x */
+       uint64_t value;          /* out (get_param) or in (set_param) */
+};
+
+/*
+ * GEM buffers:
+ */
+
+#define MSM_BO_SCANOUT       0x00000001     /* scanout capable */
+#define MSM_BO_GPU_READONLY  0x00000002
+#define MSM_BO_CACHE_MASK    0x000f0000
+/* cache modes */
+#define MSM_BO_CACHED        0x00010000
+#define MSM_BO_WC            0x00020000
+#define MSM_BO_UNCACHED      0x00040000
+
+struct drm_msm_gem_new {
+       uint64_t size;           /* in */
+       uint32_t flags;          /* in, mask of MSM_BO_x */
+       uint32_t handle;         /* out */
+};
+
+struct drm_msm_gem_info {
+       uint32_t handle;         /* in */
+       uint32_t pad;
+       uint64_t offset;         /* out, offset to pass to mmap() */
+};
+
+#define MSM_PREP_READ        0x01
+#define MSM_PREP_WRITE       0x02
+#define MSM_PREP_NOSYNC      0x04
+
+struct drm_msm_gem_cpu_prep {
+       uint32_t handle;         /* in */
+       uint32_t op;             /* in, mask of MSM_PREP_x */
+       struct drm_msm_timespec timeout;   /* in */
+};
+
+struct drm_msm_gem_cpu_fini {
+       uint32_t handle;         /* in */
+};
+
+/*
+ * Cmdstream Submission:
+ */
+
+/* The value written into the cmdstream is logically:
+ *
+ *   ((relocbuf->gpuaddr + reloc_offset) << shift) | or
+ *
+ * When we have GPU's w/ >32bit ptrs, it should be possible to deal
+ * with this by emit'ing two reloc entries with appropriate shift
+ * values.  Or a new MSM_SUBMIT_CMD_x type would also be an option.
+ *
+ * NOTE that reloc's must be sorted by order of increasing submit_offset,
+ * otherwise EINVAL.
+ */
+struct drm_msm_gem_submit_reloc {
+       uint32_t submit_offset;  /* in, offset from submit_bo */
+       uint32_t or;             /* in, value OR'd with result */
+       int32_t  shift;          /* in, amount of left shift (can be negative) */
+       uint32_t reloc_idx;      /* in, index of reloc_bo buffer */
+       uint64_t reloc_offset;   /* in, offset from start of reloc_bo */
+};
+
+/* submit-types:
+ *   BUF - this cmd buffer is executed normally.
+ *   IB_TARGET_BUF - this cmd buffer is an IB target.  Reloc's are
+ *      processed normally, but the kernel does not setup an IB to
+ *      this buffer in the first-level ringbuffer
+ *   CTX_RESTORE_BUF - only executed if there has been a GPU context
+ *      switch since the last SUBMIT ioctl
+ */
+#define MSM_SUBMIT_CMD_BUF             0x0001
+#define MSM_SUBMIT_CMD_IB_TARGET_BUF   0x0002
+#define MSM_SUBMIT_CMD_CTX_RESTORE_BUF 0x0003
+struct drm_msm_gem_submit_cmd {
+       uint32_t type;           /* in, one of MSM_SUBMIT_CMD_x */
+       uint32_t submit_idx;     /* in, index of submit_bo cmdstream buffer */
+       uint32_t submit_offset;  /* in, offset into submit_bo */
+       uint32_t size;           /* in, cmdstream size */
+       uint32_t pad;
+       uint32_t nr_relocs;      /* in, number of submit_reloc's */
+       uint64_t __user relocs;  /* in, ptr to array of submit_reloc's */
+};
+
+/* Each buffer referenced elsewhere in the cmdstream submit (ie. the
+ * cmdstream buffer(s) themselves or reloc entries) has one (and only
+ * one) entry in the submit->bos[] table.
+ *
+ * As a optimization, the current buffer (gpu virtual address) can be
+ * passed back through the 'presumed' field.  If on a subsequent reloc,
+ * userspace passes back a 'presumed' address that is still valid,
+ * then patching the cmdstream for this entry is skipped.  This can
+ * avoid kernel needing to map/access the cmdstream bo in the common
+ * case.
+ */
+#define MSM_SUBMIT_BO_READ             0x0001
+#define MSM_SUBMIT_BO_WRITE            0x0002
+struct drm_msm_gem_submit_bo {
+       uint32_t flags;          /* in, mask of MSM_SUBMIT_BO_x */
+       uint32_t handle;         /* in, GEM handle */
+       uint64_t presumed;       /* in/out, presumed buffer address */
+};
+
+/* Each cmdstream submit consists of a table of buffers involved, and
+ * one or more cmdstream buffers.  This allows for conditional execution
+ * (context-restore), and IB buffers needed for per tile/bin draw cmds.
+ */
+struct drm_msm_gem_submit {
+       uint32_t pipe;           /* in, MSM_PIPE_x */
+       uint32_t fence;          /* out */
+       uint32_t nr_bos;         /* in, number of submit_bo's */
+       uint32_t nr_cmds;        /* in, number of submit_cmd's */
+       uint64_t __user bos;     /* in, ptr to array of submit_bo's */
+       uint64_t __user cmds;    /* in, ptr to array of submit_cmd's */
+};
+
+/* The normal way to synchronize with the GPU is just to CPU_PREP on
+ * a buffer if you need to access it from the CPU (other cmdstream
+ * submission from same or other contexts, PAGE_FLIP ioctl, etc, all
+ * handle the required synchronization under the hood).  This ioctl
+ * mainly just exists as a way to implement the gallium pipe_fence
+ * APIs without requiring a dummy bo to synchronize on.
+ */
+struct drm_msm_wait_fence {
+       uint32_t fence;          /* in */
+       uint32_t pad;
+       struct drm_msm_timespec timeout;   /* in */
+};
+
+#define DRM_MSM_GET_PARAM              0x00
+/* placeholder:
+#define DRM_MSM_SET_PARAM              0x01
+ */
+#define DRM_MSM_GEM_NEW                0x02
+#define DRM_MSM_GEM_INFO               0x03
+#define DRM_MSM_GEM_CPU_PREP           0x04
+#define DRM_MSM_GEM_CPU_FINI           0x05
+#define DRM_MSM_GEM_SUBMIT             0x06
+#define DRM_MSM_WAIT_FENCE             0x07
+#define DRM_MSM_NUM_IOCTLS             0x08
+
+#define DRM_IOCTL_MSM_GET_PARAM        DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GET_PARAM, struct drm_msm_param)
+#define DRM_IOCTL_MSM_GEM_NEW          DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_NEW, struct drm_msm_gem_new)
+#define DRM_IOCTL_MSM_GEM_INFO         DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_INFO, struct drm_msm_gem_info)
+#define DRM_IOCTL_MSM_GEM_CPU_PREP     DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_GEM_CPU_PREP, struct drm_msm_gem_cpu_prep)
+#define DRM_IOCTL_MSM_GEM_CPU_FINI     DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_GEM_CPU_FINI, struct drm_msm_gem_cpu_fini)
+#define DRM_IOCTL_MSM_GEM_SUBMIT       DRM_IOWR(DRM_COMMAND_BASE + DRM_MSM_GEM_SUBMIT, struct drm_msm_gem_submit)
+#define DRM_IOCTL_MSM_WAIT_FENCE       DRM_IOW (DRM_COMMAND_BASE + DRM_MSM_WAIT_FENCE, struct drm_msm_wait_fence)
+
+#endif /* __MSM_DRM_H__ */