drm/radeon: Sync to Linux 3.11
authorMichael Neumann <mneumann@ntecs.de>
Wed, 27 May 2015 07:35:36 +0000 (10:35 +0300)
committerFrançois Tigeot <ftigeot@wolfpond.org>
Thu, 28 May 2015 18:01:37 +0000 (20:01 +0200)
144 files changed:
sys/dev/drm/include/asm/io.h
sys/dev/drm/include/drm/drm_fixed.h
sys/dev/drm/include/linux/io.h
sys/dev/drm/include/linux/math64.h
sys/dev/drm/include/uapi_drm/radeon_drm.h
sys/dev/drm/radeon/Makefile
sys/dev/drm/radeon/ObjectID.h
sys/dev/drm/radeon/atom-bits.h
sys/dev/drm/radeon/atom-names.h
sys/dev/drm/radeon/atom-types.h
sys/dev/drm/radeon/atom.c
sys/dev/drm/radeon/atom.h
sys/dev/drm/radeon/atombios.h
sys/dev/drm/radeon/atombios_crtc.c
sys/dev/drm/radeon/atombios_dp.c
sys/dev/drm/radeon/atombios_encoders.c
sys/dev/drm/radeon/avivod.h
sys/dev/drm/radeon/btc_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/btc_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/btcd.h [new file with mode: 0644]
sys/dev/drm/radeon/cayman_blit_shaders.c
sys/dev/drm/radeon/cayman_blit_shaders.h
sys/dev/drm/radeon/cik.c [new file with mode: 0644]
sys/dev/drm/radeon/cik_blit_shaders.c [copied from sys/dev/drm/radeon/si_blit_shaders.c with 93% similarity]
sys/dev/drm/radeon/cik_blit_shaders.h [copied from sys/dev/drm/radeon/si_blit_shaders.h with 81% similarity]
sys/dev/drm/radeon/cik_reg.h [new file with mode: 0644]
sys/dev/drm/radeon/cikd.h [copied from sys/dev/drm/radeon/sid.h with 57% similarity]
sys/dev/drm/radeon/clearstate_cayman.h [new file with mode: 0644]
sys/dev/drm/radeon/clearstate_defs.h [copied from sys/dev/drm/radeon/atom-types.h with 72% similarity]
sys/dev/drm/radeon/clearstate_evergreen.h [new file with mode: 0644]
sys/dev/drm/radeon/clearstate_si.h [new file with mode: 0644]
sys/dev/drm/radeon/cypress_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/cypress_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/evergreen.c
sys/dev/drm/radeon/evergreen_blit_kms.c
sys/dev/drm/radeon/evergreen_blit_shaders.c
sys/dev/drm/radeon/evergreen_blit_shaders.h
sys/dev/drm/radeon/evergreen_hdmi.c
sys/dev/drm/radeon/evergreen_reg.h
sys/dev/drm/radeon/evergreen_smc.h [new file with mode: 0644]
sys/dev/drm/radeon/evergreend.h
sys/dev/drm/radeon/ni.c
sys/dev/drm/radeon/ni_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/ni_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/ni_reg.h
sys/dev/drm/radeon/nid.h
sys/dev/drm/radeon/nislands_smc.h [new file with mode: 0644]
sys/dev/drm/radeon/ppsmc.h [new file with mode: 0644]
sys/dev/drm/radeon/r100.c
sys/dev/drm/radeon/r100_track.h
sys/dev/drm/radeon/r100d.h
sys/dev/drm/radeon/r200.c
sys/dev/drm/radeon/r300_reg.h
sys/dev/drm/radeon/r300d.h
sys/dev/drm/radeon/r420d.h
sys/dev/drm/radeon/r500_reg.h
sys/dev/drm/radeon/r520.c
sys/dev/drm/radeon/r520d.h
sys/dev/drm/radeon/r600.c
sys/dev/drm/radeon/r600_blit_shaders.c
sys/dev/drm/radeon/r600_blit_shaders.h
sys/dev/drm/radeon/r600_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/r600_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/r600_hdmi.c
sys/dev/drm/radeon/r600_reg.h
sys/dev/drm/radeon/r600d.h
sys/dev/drm/radeon/radeon.h
sys/dev/drm/radeon/radeon_acpi.c
sys/dev/drm/radeon/radeon_asic.c
sys/dev/drm/radeon/radeon_asic.h
sys/dev/drm/radeon/radeon_atombios.c
sys/dev/drm/radeon/radeon_benchmark.c
sys/dev/drm/radeon/radeon_blit_common.h
sys/dev/drm/radeon/radeon_combios.c
sys/dev/drm/radeon/radeon_cs.c
sys/dev/drm/radeon/radeon_cursor.c
sys/dev/drm/radeon/radeon_device.c
sys/dev/drm/radeon/radeon_display.c
sys/dev/drm/radeon/radeon_drv.c
sys/dev/drm/radeon/radeon_drv.h
sys/dev/drm/radeon/radeon_encoders.c
sys/dev/drm/radeon/radeon_family.h
sys/dev/drm/radeon/radeon_fb.c
sys/dev/drm/radeon/radeon_gart.c
sys/dev/drm/radeon/radeon_irq.c
sys/dev/drm/radeon/radeon_irq_kms.c
sys/dev/drm/radeon/radeon_kms.c
sys/dev/drm/radeon/radeon_legacy_crtc.c
sys/dev/drm/radeon/radeon_legacy_tv.c
sys/dev/drm/radeon/radeon_mode.h
sys/dev/drm/radeon/radeon_object.c
sys/dev/drm/radeon/radeon_object.h
sys/dev/drm/radeon/radeon_pm.c
sys/dev/drm/radeon/radeon_prime.c
sys/dev/drm/radeon/radeon_reg.h
sys/dev/drm/radeon/radeon_ring.c
sys/dev/drm/radeon/radeon_sa.c
sys/dev/drm/radeon/radeon_trace.h
sys/dev/drm/radeon/radeon_trace_points.c
sys/dev/drm/radeon/radeon_ucode.h [new file with mode: 0644]
sys/dev/drm/radeon/radeon_uvd.c
sys/dev/drm/radeon/rs100d.h
sys/dev/drm/radeon/rs400d.h
sys/dev/drm/radeon/rs600d.h
sys/dev/drm/radeon/rs690.c
sys/dev/drm/radeon/rs690d.h
sys/dev/drm/radeon/rs780_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/rs780_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/rs780d.h [new file with mode: 0644]
sys/dev/drm/radeon/rv200d.h
sys/dev/drm/radeon/rv250d.h
sys/dev/drm/radeon/rv350d.h
sys/dev/drm/radeon/rv515.c
sys/dev/drm/radeon/rv515d.h
sys/dev/drm/radeon/rv6xx_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/rv6xx_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/rv6xxd.h [new file with mode: 0644]
sys/dev/drm/radeon/rv730_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/rv730d.h [new file with mode: 0644]
sys/dev/drm/radeon/rv740_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/rv740d.h [new file with mode: 0644]
sys/dev/drm/radeon/rv770.c
sys/dev/drm/radeon/rv770_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/rv770_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/rv770_smc.c [new file with mode: 0644]
sys/dev/drm/radeon/rv770_smc.h [new file with mode: 0644]
sys/dev/drm/radeon/rv770d.h
sys/dev/drm/radeon/si.c
sys/dev/drm/radeon/si_blit_shaders.c
sys/dev/drm/radeon/si_blit_shaders.h
sys/dev/drm/radeon/si_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/si_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/si_reg.h
sys/dev/drm/radeon/si_smc.c [new file with mode: 0644]
sys/dev/drm/radeon/sid.h
sys/dev/drm/radeon/sislands_smc.h [new file with mode: 0644]
sys/dev/drm/radeon/sumo_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/sumo_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/sumo_smc.c [new file with mode: 0644]
sys/dev/drm/radeon/sumod.h [new file with mode: 0644]
sys/dev/drm/radeon/trinity_dpm.c [new file with mode: 0644]
sys/dev/drm/radeon/trinity_dpm.h [new file with mode: 0644]
sys/dev/drm/radeon/trinity_smc.c [new file with mode: 0644]
sys/dev/drm/radeon/trinityd.h [new file with mode: 0644]

index a28bf02..191df3a 100644 (file)
@@ -51,6 +51,11 @@ static inline void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long
        return pmap_mapdev_attr(phys_addr, size, VM_MEMATTR_WRITE_COMBINING);
 }
 
+static inline void iounmap(void __iomem *ptr, unsigned long size)
+{
+       pmap_unmapdev((vm_offset_t) ptr, size);
+}
+
 #define mmiowb cpu_sfence
 
 #endif /* _ASM_IO_H_ */
index 0ead502..d639049 100644 (file)
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Authors: Dave Airlie
+ *          Christian König
  */
 #ifndef DRM_FIXED_H
 #define DRM_FIXED_H
 
+#include <linux/math64.h>
+
 typedef union dfixed {
        u32 full;
 } fixed20_12;
@@ -65,4 +68,95 @@ static inline u32 dfixed_div(fixed20_12 A, fixed20_12 B)
        tmp /= 2;
        return lower_32_bits(tmp);
 }
+
+#define DRM_FIXED_POINT                32
+#define DRM_FIXED_ONE          (1ULL << DRM_FIXED_POINT)
+#define DRM_FIXED_DECIMAL_MASK (DRM_FIXED_ONE - 1)
+#define DRM_FIXED_DIGITS_MASK  (~DRM_FIXED_DECIMAL_MASK)
+
+static inline s64 drm_int2fixp(int a)
+{
+       return ((s64)a) << DRM_FIXED_POINT;
+}
+
+static inline int drm_fixp2int(int64_t a)
+{
+       return ((s64)a) >> DRM_FIXED_POINT;
+}
+
+static inline unsigned drm_fixp_msbset(int64_t a)
+{
+       unsigned shift, sign = (a >> 63) & 1;
+
+       for (shift = 62; shift > 0; --shift)
+               if (((a >> shift) & 1) != sign)
+                       return shift;
+
+       return 0;
+}
+
+static inline s64 drm_fixp_mul(s64 a, s64 b)
+{
+       unsigned shift = drm_fixp_msbset(a) + drm_fixp_msbset(b);
+       s64 result;
+
+       if (shift > 61) {
+               shift = shift - 61;
+               a >>= (shift >> 1) + (shift & 1);
+               b >>= shift >> 1;
+       } else
+               shift = 0;
+
+       result = a * b;
+
+       if (shift > DRM_FIXED_POINT)
+               return result << (shift - DRM_FIXED_POINT);
+
+       if (shift < DRM_FIXED_POINT)
+               return result >> (DRM_FIXED_POINT - shift);
+
+       return result;
+}
+
+static inline s64 drm_fixp_div(s64 a, s64 b)
+{
+       unsigned shift = 62 - drm_fixp_msbset(a);
+       s64 result;
+
+       a <<= shift;
+
+       if (shift < DRM_FIXED_POINT)
+               b >>= (DRM_FIXED_POINT - shift);
+
+       result = div64_s64(a, b);
+
+       if (shift > DRM_FIXED_POINT)
+               return result >> (shift - DRM_FIXED_POINT);
+
+       return result;
+}
+
+static inline s64 drm_fixp_exp(s64 x)
+{
+       s64 tolerance = div64_s64(DRM_FIXED_ONE, 1000000);
+       s64 sum = DRM_FIXED_ONE, term, y = x;
+       u64 count = 1;
+
+       if (x < 0)
+               y = -1 * x;
+
+       term = y;
+
+       while (term >= tolerance) {
+               sum = sum + term;
+               count = count + 1;
+               term = drm_fixp_mul(term, div64_s64(y, count));
+       }
+
+       if (x < 0)
+               sum = drm_fixp_div(DRM_FIXED_ONE, sum);
+
+       return sum;
+}
+
 #endif
index f8b99e9..02c00eb 100644 (file)
@@ -36,7 +36,7 @@
 #endif
 
 static inline void
-writel(uint32_t value, void *addr)
+writel(uint32_t value, volatile void *addr)
 {
        *(volatile uint32_t *)addr = value;
 }
index 94650ca..73764e2 100644 (file)
 */
 static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
 {
-        *remainder = dividend % divisor;
-        return dividend / divisor;
+       *remainder = dividend % divisor;
+       return dividend / divisor;
 }
 
+/**
+ * div64_u64 - unsigned 64bit divide with 64bit divisor
+ */
+static inline u64 div64_u64(u64 dividend, u64 divisor)
+{
+       return dividend / divisor;
+}
+
+/**
+ * div64_s64 - signed 64bit divide with 64bit divisor
+ */
+static inline s64 div64_s64(s64 dividend, s64 divisor)
+{
+       return dividend / divisor;
+}
 
 #elif BITS_PER_LONG == 32
 
index 6f88421..ca82852 100644 (file)
@@ -974,9 +974,9 @@ struct drm_radeon_cs {
 /* max SH per SE */
 #define RADEON_INFO_MAX_SH_PER_SE      0x13
 /* fast fb access is enabled */
-#define RADEON_INFO_FASTFB_WORKING     0x14
+#define RADEON_INFO_FASTFB_WORKING     0x14
 /* query if a RADEON_CS_RING_* submission is supported */
-#define RADEON_INFO_RING_WORKING       0x15
+#define RADEON_INFO_RING_WORKING       0x15
 /* SI tile mode array */
 #define RADEON_INFO_SI_TILE_MODE_ARRAY 0x16
 
@@ -990,19 +990,19 @@ struct drm_radeon_info {
 /* Those correspond to the tile index to use, this is to explicitly state
  * the API that is implicitly defined by the tile mode array.
  */
-#define SI_TILE_MODE_COLOR_LINEAR_ALIGNED      8
-#define SI_TILE_MODE_COLOR_1D                  13
-#define SI_TILE_MODE_COLOR_1D_SCANOUT          9
-#define SI_TILE_MODE_COLOR_2D_8BPP             14
-#define SI_TILE_MODE_COLOR_2D_16BPP            15
-#define SI_TILE_MODE_COLOR_2D_32BPP            16
-#define SI_TILE_MODE_COLOR_2D_64BPP            17
-#define SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP    11
-#define SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP    12
-#define SI_TILE_MODE_DEPTH_STENCIL_1D          4
-#define SI_TILE_MODE_DEPTH_STENCIL_2D          0
-#define SI_TILE_MODE_DEPTH_STENCIL_2D_2AA      3
-#define SI_TILE_MODE_DEPTH_STENCIL_2D_4AA      3
-#define SI_TILE_MODE_DEPTH_STENCIL_2D_8AA      2
+#define SI_TILE_MODE_COLOR_LINEAR_ALIGNED      8
+#define SI_TILE_MODE_COLOR_1D                  13
+#define SI_TILE_MODE_COLOR_1D_SCANOUT          9
+#define SI_TILE_MODE_COLOR_2D_8BPP             14
+#define SI_TILE_MODE_COLOR_2D_16BPP            15
+#define SI_TILE_MODE_COLOR_2D_32BPP            16
+#define SI_TILE_MODE_COLOR_2D_64BPP            17
+#define SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP    11
+#define SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP    12
+#define SI_TILE_MODE_DEPTH_STENCIL_1D          4
+#define SI_TILE_MODE_DEPTH_STENCIL_2D          0
+#define SI_TILE_MODE_DEPTH_STENCIL_2D_2AA      3
+#define SI_TILE_MODE_DEPTH_STENCIL_2D_4AA      3
+#define SI_TILE_MODE_DEPTH_STENCIL_2D_8AA      2
 
 #endif
index 504e117..77acde2 100644 (file)
@@ -75,7 +75,25 @@ SRCS +=                                                              \
        ni.c                                                            \
        si.c                                                            \
        si_blit_shaders.c                                               \
-       radeon_uvd.c
+       radeon_uvd.c                                                    \
+       cik.c                                                           \
+       cik_blit_shaders.c                                              \
+       r600_dpm.c                                                      \
+       rs780_dpm.c                                                     \
+       rv6xx_dpm.c                                                     \
+       rv770_dpm.c                                                     \
+       rv730_dpm.c                                                     \
+       rv740_dpm.c                                                     \
+       rv770_smc.c                                                     \
+       cypress_dpm.c                                                   \
+       btc_dpm.c                                                       \
+       sumo_dpm.c                                                      \
+       sumo_smc.c                                                      \
+       trinity_dpm.c                                                   \
+       trinity_smc.c                                                   \
+       ni_dpm.c                                                        \
+       si_smc.c                                                        \
+       si_dpm.c
 
 
 # UMS driver
index 37abd7e..73a9155 100644 (file)
@@ -71,6 +71,8 @@
 #define ENCODER_OBJECT_ID_ALMOND                  0x22
 #define ENCODER_OBJECT_ID_TRAVIS                  0x23
 #define ENCODER_OBJECT_ID_NUTMEG                  0x22
+#define ENCODER_OBJECT_ID_HDMI_ANX9805            0x26
+
 /* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */
 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1   0x13
 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1    0x14
@@ -88,6 +90,8 @@
 #define ENCODER_OBJECT_ID_INTERNAL_UNIPHY1        0x20
 #define ENCODER_OBJECT_ID_INTERNAL_UNIPHY2        0x21
 #define ENCODER_OBJECT_ID_INTERNAL_VCE            0x24
+#define ENCODER_OBJECT_ID_INTERNAL_UNIPHY3        0x25
+#define ENCODER_OBJECT_ID_INTERNAL_AMCLK          0x27
 
 #define ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO    0xFF
 
                                                  GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
                                                  ENCODER_OBJECT_ID_INTERNAL_UNIPHY2 << OBJECT_ID_SHIFT)
 
+#define ENCODER_INTERNAL_UNIPHY3_ENUM_ID1         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 << OBJECT_ID_SHIFT)
+
+#define ENCODER_INTERNAL_UNIPHY3_ENUM_ID2         ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\
+                                                 ENCODER_OBJECT_ID_INTERNAL_UNIPHY3 << OBJECT_ID_SHIFT)
+
 #define ENCODER_GENERAL_EXTERNAL_DVO_ENUM_ID1    ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                   ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT)
                                                   GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                   ENCODER_OBJECT_ID_INTERNAL_VCE << OBJECT_ID_SHIFT)
 
+#define ENCODER_HDMI_ANX9805_ENUM_ID1            ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\
+                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
+                                                  ENCODER_OBJECT_ID_HDMI_ANX9805 << OBJECT_ID_SHIFT)
+
 /****************************************************/
 /* Connector Object ID definition - Shared with BIOS */
 /****************************************************/
                                                  GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
 
+#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID5   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID6   ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT)
+
 #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
                                                  GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
 
+#define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID4     ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT)
+
 #define CONNECTOR_VGA_ENUM_ID1                 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_VGA << OBJECT_ID_SHIFT)
                                                  GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
 
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID4         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID5         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID5 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+
+#define CONNECTOR_HDMI_TYPE_A_ENUM_ID6         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
+                                                 GRAPH_OBJECT_ENUM_ID6 << ENUM_ID_SHIFT |\
+                                                 CONNECTOR_OBJECT_ID_HDMI_TYPE_A << OBJECT_ID_SHIFT)
+
 #define CONNECTOR_HDMI_TYPE_B_ENUM_ID1         ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\
                                                  GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\
                                                  CONNECTOR_OBJECT_ID_HDMI_TYPE_B << OBJECT_ID_SHIFT)
index b106ada..e8fae5c 100644 (file)
@@ -20,8 +20,6 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Author: Stanislaw Skowronek
- *
- * $FreeBSD: head/sys/dev/drm2/radeon/atom-bits.h 254885 2013-08-25 19:37:15Z dumbbell $
  */
 
 #ifndef ATOM_BITS_H
index 22d17dc..6f907a5 100644 (file)
@@ -20,8 +20,6 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Author: Stanislaw Skowronek
- *
- * $FreeBSD: head/sys/dev/drm2/radeon/atom-names.h 254885 2013-08-25 19:37:15Z dumbbell $
  */
 
 #ifndef ATOM_NAMES_H
index 2a8ae9c..1125b86 100644 (file)
@@ -20,8 +20,6 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Author: Dave Airlie
- *
- * $FreeBSD: head/sys/dev/drm2/radeon/atom-types.h 254885 2013-08-25 19:37:15Z dumbbell $
  */
 
 #ifndef ATOM_TYPES_H
index 28bd0b0..1b0aaf9 100644 (file)
@@ -1219,12 +1219,17 @@ int atom_execute_table(struct atom_context *ctx, int index, uint32_t * params)
        int r;
 
        lockmgr(&ctx->mutex, LK_EXCLUSIVE);
+       /* reset data block */
+       ctx->data_block = 0;
        /* reset reg block */
        ctx->reg_block = 0;
        /* reset fb window */
        ctx->fb_base = 0;
        /* reset io mode */
        ctx->io_mode = ATOM_IO_MM;
+       /* reset divmul */
+       ctx->divmul[0] = 0;
+       ctx->divmul[1] = 0;
        r = atom_execute_table_locked(ctx, index, params);
        lockmgr(&ctx->mutex, LK_RELEASE);
        return r;
index 2553c0c..11cb5e2 100644 (file)
@@ -20,8 +20,6 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  *
  * Author: Stanislaw Skowronek
- *
- * $FreeBSD: head/sys/dev/drm2/radeon/atom.h 254885 2013-08-25 19:37:15Z dumbbell $
  */
 
 #ifndef ATOM_H
@@ -126,7 +124,7 @@ struct card_info {
 struct atom_context {
        struct card_info *card;
        struct lock mutex;
-       void *bios;
+       uint8_t *bios;
        uint32_t cmd_table, data_table;
        uint16_t *iio;
 
index 2d52d03..9105d2c 100644 (file)
@@ -18,8 +18,6 @@
  * 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.
- *
- * $FreeBSD: head/sys/dev/drm2/radeon/atombios.h 254885 2013-08-25 19:37:15Z dumbbell $
  */
 
 
@@ -76,6 +74,8 @@
 #define ATOM_PPLL2            1
 #define ATOM_DCPLL            2
 #define ATOM_PPLL0            2
+#define ATOM_PPLL3            3
+
 #define ATOM_EXT_PLL1         8
 #define ATOM_EXT_PLL2         9
 #define ATOM_EXT_CLOCK        10
@@ -261,7 +261,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
   USHORT AdjustDisplayPll;                                                                                      //Atomic Table,  used by various SW componentes. 
   USHORT AdjustMemoryController;                 //Atomic Table,  indirectly used by various SW components,called from SetMemoryClock                
   USHORT EnableASIC_StaticPwrMgt;                //Atomic Table,  only used by Bios
-  USHORT ASIC_StaticPwrMgtStatusChange;          //Obsolete ,     only used by Bios   
+  USHORT SetUniphyInstance;                      //Atomic Table,  only used by Bios
   USHORT DAC_LoadDetection;                      //Atomic Table,  directly used by various SW components,latest version 1.2  
   USHORT LVTMAEncoderControl;                    //Atomic Table,directly used by various SW components,latest version 1.3
   USHORT HW_Misc_Operation;                      //Atomic Table,  directly used by various SW components,latest version 1.1 
@@ -273,7 +273,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
   USHORT TVEncoderControl;                       //Function Table,directly used by various SW components,latest version 1.1
   USHORT PatchMCSetting;                         //only used by BIOS
   USHORT MC_SEQ_Control;                         //only used by BIOS
-  USHORT TV1OutputControl;                       //Atomic Table,  Obsolete from Ry6xx, use DAC2 Output instead
+  USHORT Gfx_Harvesting;                         //Atomic Table,  Obsolete from Ry6xx, Now only used by BIOS for GFX harvesting
   USHORT EnableScaler;                           //Atomic Table,  used only by Bios
   USHORT BlankCRTC;                              //Atomic Table,  directly used by various SW components,latest version 1.1 
   USHORT EnableCRTC;                             //Atomic Table,  directly used by various SW components,latest version 1.1 
@@ -330,7 +330,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
 #define UNIPHYTransmitterControl                            DIG1TransmitterControl
 #define LVTMATransmitterControl                                     DIG2TransmitterControl
 #define SetCRTC_DPM_State                        GetConditionalGoldenSetting
-#define SetUniphyInstance                        ASIC_StaticPwrMgtStatusChange
+#define ASIC_StaticPwrMgtStatusChange            SetUniphyInstance
 #define HPDInterruptService                      ReadHWAssistedI2CStatus
 #define EnableVGA_Access                         GetSCLKOverMCLKRatio
 #define EnableYUV                                GetDispObjectInfo                         
@@ -340,7 +340,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{
 #define TMDSAEncoderControl                      PatchMCSetting
 #define LVDSEncoderControl                       MC_SEQ_Control
 #define LCD1OutputControl                        HW_Misc_Operation
-
+#define TV1OutputControl                         Gfx_Harvesting
 
 typedef struct _ATOM_MASTER_COMMAND_TABLE
 {
@@ -480,11 +480,11 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V3
 typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4
 {
 #if ATOM_BIG_ENDIAN
-  ULONG  ucPostDiv;          //return parameter: post divider which is used to program to register directly
+  ULONG  ucPostDiv:8;        //return parameter: post divider which is used to program to register directly
   ULONG  ulClock:24;         //Input= target clock, output = actual clock 
 #else
   ULONG  ulClock:24;         //Input= target clock, output = actual clock 
-  ULONG  ucPostDiv;          //return parameter: post divider which is used to program to register directly
+  ULONG  ucPostDiv:8;        //return parameter: post divider which is used to program to register directly
 #endif
 }COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4;
 
@@ -506,6 +506,32 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5
   UCHAR   ucReserved;                       
 }COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5;
 
+
+typedef struct _COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6
+{
+  ATOM_COMPUTE_CLOCK_FREQ  ulClock;         //Input Parameter
+  ULONG   ulReserved[2];
+}COMPUTE_GPU_CLOCK_INPUT_PARAMETERS_V1_6;
+
+//ATOM_COMPUTE_CLOCK_FREQ.ulComputeClockFlag
+#define COMPUTE_GPUCLK_INPUT_FLAG_CLK_TYPE_MASK            0x0f
+#define COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK           0x00
+#define COMPUTE_GPUCLK_INPUT_FLAG_SCLK                     0x01
+
+typedef struct _COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6
+{
+  COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4  ulClock;         //Output Parameter: ucPostDiv=DFS divider
+  ATOM_S_MPLL_FB_DIVIDER   ulFbDiv;         //Output Parameter: PLL FB divider
+  UCHAR   ucPllRefDiv;                      //Output Parameter: PLL ref divider
+  UCHAR   ucPllPostDiv;                     //Output Parameter: PLL post divider
+  UCHAR   ucPllCntlFlag;                    //Output Flags: control flag
+  UCHAR   ucReserved;
+}COMPUTE_GPU_CLOCK_OUTPUT_PARAMETERS_V1_6;
+
+//ucPllCntlFlag
+#define SPLL_CNTL_FLAG_VCO_MODE_MASK            0x03
+
+
 // ucInputFlag
 #define ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN  1   // 1-StrobeMode, 0-PerformanceMode
 
@@ -1688,6 +1714,7 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V6
 #define PIXEL_CLOCK_V6_MISC_HDMI_30BPP              0x08
 #define PIXEL_CLOCK_V6_MISC_HDMI_48BPP              0x0c
 #define PIXEL_CLOCK_V6_MISC_REF_DIV_SRC             0x10
+#define PIXEL_CLOCK_V6_MISC_GEN_DPREFCLK            0x40
 
 typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2
 {
@@ -2104,6 +2131,17 @@ typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3
 }DVO_ENCODER_CONTROL_PARAMETERS_V3;
 #define DVO_ENCODER_CONTROL_PS_ALLOCATION_V3   DVO_ENCODER_CONTROL_PARAMETERS_V3
 
+typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V1_4
+{
+  USHORT usPixelClock;
+  UCHAR  ucDVOConfig;
+  UCHAR  ucAction;                                                                                                             //ATOM_ENABLE/ATOM_DISABLE/ATOM_HPD_INIT
+  UCHAR  ucBitPerColor;                       //please refer to definition of PANEL_xBIT_PER_COLOR
+  UCHAR  ucReseved[3];
+}DVO_ENCODER_CONTROL_PARAMETERS_V1_4;
+#define DVO_ENCODER_CONTROL_PS_ALLOCATION_V1_4 DVO_ENCODER_CONTROL_PARAMETERS_V1_4
+
+
 //ucTableFormatRevision=1
 //ucTableContentRevision=3 structure is not changed but usMisc add bit 1 as another input for 
 // bit1=0: non-coherent mode
@@ -2167,7 +2205,7 @@ typedef struct _DVO_ENCODER_CONTROL_PARAMETERS_V3
 #define SET_ASIC_VOLTAGE_MODE_SOURCE_B         0x4
 
 #define        SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE      0x0
-#define        SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL      0x1      
+#define        SET_ASIC_VOLTAGE_MODE_GET_GPIOVAL      0x1
 #define        SET_ASIC_VOLTAGE_MODE_GET_GPIOMASK     0x2
 
 typedef struct _SET_VOLTAGE_PARAMETERS
@@ -2202,15 +2240,20 @@ typedef struct  _SET_VOLTAGE_PARAMETERS_V1_3
 //SET_VOLTAGE_PARAMETERS_V3.ucVoltageMode
 #define ATOM_SET_VOLTAGE                     0        //Set voltage Level
 #define ATOM_INIT_VOLTAGE_REGULATOR          3        //Init Regulator
-#define ATOM_SET_VOLTAGE_PHASE               4        //Set Vregulator Phase
-#define ATOM_GET_MAX_VOLTAGE                 6        //Get Max Voltage, not used in SetVoltageTable v1.3
-#define ATOM_GET_VOLTAGE_LEVEL               6        //Get Voltage level from vitual voltage ID
+#define ATOM_SET_VOLTAGE_PHASE               4        //Set Vregulator Phase, only for SVID/PVID regulator
+#define ATOM_GET_MAX_VOLTAGE                 6        //Get Max Voltage, not used from SetVoltageTable v1.3
+#define ATOM_GET_VOLTAGE_LEVEL               6        //Get Voltage level from vitual voltage ID, not used for SetVoltage v1.4
+#define ATOM_GET_LEAKAGE_ID                  8        //Get Leakage Voltage Id ( starting from SMU7x IP ), SetVoltage v1.4
 
 // define vitual voltage id in usVoltageLevel
 #define ATOM_VIRTUAL_VOLTAGE_ID0             0xff01
 #define ATOM_VIRTUAL_VOLTAGE_ID1             0xff02
 #define ATOM_VIRTUAL_VOLTAGE_ID2             0xff03
 #define ATOM_VIRTUAL_VOLTAGE_ID3             0xff04
+#define ATOM_VIRTUAL_VOLTAGE_ID4             0xff05
+#define ATOM_VIRTUAL_VOLTAGE_ID5             0xff06
+#define ATOM_VIRTUAL_VOLTAGE_ID6             0xff07
+#define ATOM_VIRTUAL_VOLTAGE_ID7             0xff08
 
 typedef struct _SET_VOLTAGE_PS_ALLOCATION
 {
@@ -2630,7 +2673,8 @@ typedef struct _ATOM_FIRMWARE_INFO_V2_2
   ULONG                           ulFirmwareRevision;
   ULONG                           ulDefaultEngineClock;       //In 10Khz unit
   ULONG                           ulDefaultMemoryClock;       //In 10Khz unit
-  ULONG                           ulReserved[2];
+  ULONG                           ulSPLL_OutputFreq;          //In 10Khz unit
+  ULONG                           ulGPUPLL_OutputFreq;        //In 10Khz unit
   ULONG                           ulReserved1;                //Was ulMaxEngineClockPLL_Output; //In 10Khz unit*
   ULONG                           ulReserved2;                //Was ulMaxMemoryClockPLL_Output; //In 10Khz unit*
   ULONG                           ulMaxPixelClockPLL_Output;  //In 10Khz unit
@@ -3815,6 +3859,12 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT
   UCHAR                    ucGPIO_ID;
 }ATOM_GPIO_PIN_ASSIGNMENT;
 
+//ucGPIO_ID pre-define id for multiple usage
+//from SMU7.x, if ucGPIO_ID=PP_AC_DC_SWITCH_GPIO_PINID in GPIO_LUTTable, AC/DC swithing feature is enable
+#define PP_AC_DC_SWITCH_GPIO_PINID          60
+//from SMU7.x, if ucGPIO_ID=VDDC_REGULATOR_VRHOT_GPIO_PINID in GPIO_LUTable, VRHot feature is enable
+#define VDDC_VRHOT_GPIO_PINID               61
+
 typedef struct _ATOM_GPIO_PIN_LUT
 {
   ATOM_COMMON_TABLE_HEADER  sHeader;
@@ -4076,17 +4126,19 @@ typedef struct _EXT_DISPLAY_PATH
 
 //usCaps
 #define  EXT_DISPLAY_PATH_CAPS__HBR2_DISABLE          0x01
+#define  EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN        0x02
 
 typedef  struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO
 {
   ATOM_COMMON_TABLE_HEADER sHeader;
   UCHAR                    ucGuid [NUMBER_OF_UCHAR_FOR_GUID];     // a GUID is a 16 byte long string
   EXT_DISPLAY_PATH         sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries.
-  UCHAR                    ucChecksum;                            // a  simple Checksum of the sum of whole structure equal to 0x0. 
+  UCHAR                    ucChecksum;                            // a simple Checksum of the sum of whole structure equal to 0x0.
   UCHAR                    uc3DStereoPinId;                       // use for eDP panel
   UCHAR                    ucRemoteDisplayConfig;
   UCHAR                    uceDPToLVDSRxId;
-  UCHAR                    Reserved[4];                           // for potential expansion
+  UCHAR                    ucFixDPVoltageSwing;                   // usCaps[1]=1, this indicate DP_LANE_SET value
+  UCHAR                    Reserved[3];                           // for potential expansion
 }ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO;
 
 //Related definitions, all records are different but they have a commond header
@@ -4418,6 +4470,13 @@ typedef struct _ATOM_VOLTAGE_CONTROL
 #define        VOLTAGE_CONTROL_ID_CHL822x                                              0x08                                                                    
 #define        VOLTAGE_CONTROL_ID_VT1586M                                              0x09
 #define VOLTAGE_CONTROL_ID_UP1637                                              0x0A
+#define        VOLTAGE_CONTROL_ID_CHL8214            0x0B
+#define        VOLTAGE_CONTROL_ID_UP1801             0x0C
+#define        VOLTAGE_CONTROL_ID_ST6788A            0x0D
+#define VOLTAGE_CONTROL_ID_CHLIR3564SVI2      0x0E
+#define VOLTAGE_CONTROL_ID_AD527x                    0x0F
+#define VOLTAGE_CONTROL_ID_NCP81022                  0x10
+#define VOLTAGE_CONTROL_ID_LTC2635                       0x11
 
 typedef struct  _ATOM_VOLTAGE_OBJECT
 {
@@ -4460,6 +4519,15 @@ typedef struct _ATOM_VOLTAGE_OBJECT_HEADER_V3{
         USHORT         usSize;                                                                                                 //Size of Object        
 }ATOM_VOLTAGE_OBJECT_HEADER_V3;
 
+// ATOM_VOLTAGE_OBJECT_HEADER_V3.ucVoltageMode
+#define VOLTAGE_OBJ_GPIO_LUT                 0        //VOLTAGE and GPIO Lookup table ->ATOM_GPIO_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_VR_I2C_INIT_SEQ          3        //VOLTAGE REGULATOR INIT sequece through I2C -> ATOM_I2C_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_PHASE_LUT                4        //Set Vregulator Phase lookup table ->ATOM_GPIO_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_SVID2                    7        //Indicate voltage control by SVID2 ->ATOM_SVID2_VOLTAGE_OBJECT_V3
+#define        VOLTAGE_OBJ_PWRBOOST_LEAKAGE_LUT     0x10     //Powerboost Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
+#define        VOLTAGE_OBJ_HIGH_STATE_LEAKAGE_LUT   0x11     //High voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
+#define VOLTAGE_OBJ_HIGH1_STATE_LEAKAGE_LUT  0x12     //High1 voltage state Voltage and LeakageId lookup table->ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
+
 typedef struct  _VOLTAGE_LUT_ENTRY_V2
 {
         ULONG          ulVoltageId;                                                                      // The Voltage ID which is used to program GPIO register
@@ -4475,7 +4543,7 @@ typedef struct  _LEAKAGE_VOLTAGE_LUT_ENTRY_V2
 
 typedef struct  _ATOM_I2C_VOLTAGE_OBJECT_V3
 {
-   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;
+   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;    // voltage mode = VOLTAGE_OBJ_VR_I2C_INIT_SEQ
    UCHAR       ucVoltageRegulatorId;                                     //Indicate Voltage Regulator Id
    UCHAR    ucVoltageControlI2cLine;
    UCHAR    ucVoltageControlAddress;
@@ -4486,7 +4554,7 @@ typedef struct  _ATOM_I2C_VOLTAGE_OBJECT_V3
 
 typedef struct  _ATOM_GPIO_VOLTAGE_OBJECT_V3
 {
-   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;   
+   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;   // voltage mode = VOLTAGE_OBJ_GPIO_LUT or VOLTAGE_OBJ_PHASE_LUT
    UCHAR    ucVoltageGpioCntlId;         // default is 0 which indicate control through CG VID mode 
    UCHAR    ucGpioEntryNum;              // indiate the entry numbers of Votlage/Gpio value Look up table
    UCHAR    ucPhaseDelay;                // phase delay in unit of micro second
@@ -4497,7 +4565,7 @@ typedef struct  _ATOM_GPIO_VOLTAGE_OBJECT_V3
 
 typedef struct  _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
 {
-   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;
+   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;    // voltage mode = 0x10/0x11/0x12
    UCHAR    ucLeakageCntlId;             // default is 0
    UCHAR    ucLeakageEntryNum;           // indicate the entry number of LeakageId/Voltage Lut table
    UCHAR    ucReserved[2];               
@@ -4505,10 +4573,26 @@ typedef struct  _ATOM_LEAKAGE_VOLTAGE_OBJECT_V3
    LEAKAGE_VOLTAGE_LUT_ENTRY_V2 asLeakageIdLut[1];   
 }ATOM_LEAKAGE_VOLTAGE_OBJECT_V3;
 
+
+typedef struct  _ATOM_SVID2_VOLTAGE_OBJECT_V3
+{
+   ATOM_VOLTAGE_OBJECT_HEADER_V3 sHeader;    // voltage mode = VOLTAGE_OBJ_SVID2
+// 14:7 \96 PSI0_VID
+// 6 \96 PSI0_EN
+// 5 \96 PSI1
+// 4:2 \96 load line slope trim.
+// 1:0 \96 offset trim,
+   USHORT   usLoadLine_PSI;
+// GPU GPIO pin Id to SVID2 regulator VRHot pin. possible value 0~31. 0 means GPIO0, 31 means GPIO31
+   UCHAR    ucReserved[2];
+   ULONG    ulReserved;
+}ATOM_SVID2_VOLTAGE_OBJECT_V3;
+
 typedef union _ATOM_VOLTAGE_OBJECT_V3{
   ATOM_GPIO_VOLTAGE_OBJECT_V3 asGpioVoltageObj;
   ATOM_I2C_VOLTAGE_OBJECT_V3 asI2cVoltageObj;
   ATOM_LEAKAGE_VOLTAGE_OBJECT_V3 asLeakageObj;
+  ATOM_SVID2_VOLTAGE_OBJECT_V3 asSVID2Obj;
 }ATOM_VOLTAGE_OBJECT_V3;
 
 typedef struct  _ATOM_VOLTAGE_OBJECT_INFO_V3_1
@@ -4538,6 +4622,21 @@ typedef struct  _ATOM_ASIC_PROFILING_INFO
        ATOM_ASIC_PROFILE_VOLTAGE                       asVoltage;
 }ATOM_ASIC_PROFILING_INFO;
 
+typedef struct  _ATOM_ASIC_PROFILING_INFO_V2_1
+{
+  ATOM_COMMON_TABLE_HEADER                     asHeader;
+  UCHAR  ucLeakageBinNum;                // indicate the entry number of LeakageId/Voltage Lut table
+  USHORT usLeakageBinArrayOffset;        // offset of USHORT Leakage Bin list array ( from lower LeakageId to higher)
+
+  UCHAR  ucElbVDDC_Num;
+  USHORT usElbVDDC_IdArrayOffset;        // offset of USHORT virtual VDDC voltage id ( 0xff01~0xff08 )
+  USHORT usElbVDDC_LevelArrayOffset;     // offset of 2 dimension voltage level USHORT array
+
+  UCHAR  ucElbVDDCI_Num;
+  USHORT usElbVDDCI_IdArrayOffset;       // offset of USHORT virtual VDDCI voltage id ( 0xff01~0xff08 )
+  USHORT usElbVDDCI_LevelArrayOffset;    // offset of 2 dimension voltage level USHORT array
+}ATOM_ASIC_PROFILING_INFO_V2_1;
+
 typedef struct _ATOM_POWER_SOURCE_OBJECT
 {
        UCHAR   ucPwrSrcId;                                                                                                     // Power source
@@ -4654,6 +4753,8 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6
 #define SYS_INFO_LVDSMISC__888_BPC                                                   0x04
 #define SYS_INFO_LVDSMISC__OVERRIDE_EN                                               0x08
 #define SYS_INFO_LVDSMISC__BLON_ACTIVE_LOW                                           0x10
+// new since Trinity
+#define SYS_INFO_LVDSMISC__TRAVIS_LVDS_VOL_OVERRIDE_EN                               0x20
 
 // not used any more
 #define SYS_INFO_LVDSMISC__VSYNC_ACTIVE_LOW                                          0x04
@@ -4754,6 +4855,29 @@ typedef struct _ATOM_FUSION_SYSTEM_INFO_V1
   ATOM_INTEGRATED_SYSTEM_INFO_V6    sIntegratedSysInfo;   
   ULONG  ulPowerplayTable[128];  
 }ATOM_FUSION_SYSTEM_INFO_V1; 
+
+
+typedef struct _ATOM_TDP_CONFIG_BITS
+{
+#if ATOM_BIG_ENDIAN
+  ULONG   uReserved:2;
+  ULONG   uTDP_Value:14;  // Original TDP value in tens of milli watts
+  ULONG   uCTDP_Value:14; // Override value in tens of milli watts
+  ULONG   uCTDP_Enable:2; // = (uCTDP_Value > uTDP_Value? 2: (uCTDP_Value < uTDP_Value))
+#else
+  ULONG   uCTDP_Enable:2; // = (uCTDP_Value > uTDP_Value? 2: (uCTDP_Value < uTDP_Value))
+  ULONG   uCTDP_Value:14; // Override value in tens of milli watts
+  ULONG   uTDP_Value:14;  // Original TDP value in tens of milli watts
+  ULONG   uReserved:2;
+#endif
+}ATOM_TDP_CONFIG_BITS;
+
+typedef union _ATOM_TDP_CONFIG
+{
+  ATOM_TDP_CONFIG_BITS TDP_config;
+  ULONG            TDP_config_all;
+}ATOM_TDP_CONFIG;
+
 /**********************************************************************************************************************
   ATOM_FUSION_SYSTEM_INFO_V1 Description
 sIntegratedSysInfo:               refer to ATOM_INTEGRATED_SYSTEM_INFO_V6 definition.
@@ -4786,7 +4910,8 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7
   UCHAR  ucMemoryType;  
   UCHAR  ucUMAChannelNumber;
   UCHAR  strVBIOSMsg[40];
-  ULONG  ulReserved[20];
+  ATOM_TDP_CONFIG  asTdpConfig;
+  ULONG  ulReserved[19];
   ATOM_AVAILABLE_SCLK_LIST   sAvail_SCLK[5];
   ULONG  ulGMCRestoreResetTime;
   ULONG  ulMinimumNClk;
@@ -4811,7 +4936,7 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7
   USHORT GnbTdpLimit;
   USHORT usMaxLVDSPclkFreqInSingleLink;
   UCHAR  ucLvdsMisc;
-  UCHAR  ucLVDSReserved;
+  UCHAR  ucTravisLVDSVolAdjust;
   UCHAR  ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
   UCHAR  ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
   UCHAR  ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
@@ -4819,7 +4944,7 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7
   UCHAR  ucLVDSOffToOnDelay_in4Ms;
   UCHAR  ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
   UCHAR  ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
-  UCHAR  ucLVDSReserved1;
+  UCHAR  ucMinAllowedBL_Level;
   ULONG  ulLCDBitDepthControlVal;
   ULONG  ulNbpStateMemclkFreq[4];
   USHORT usNBP2Voltage;               
@@ -4848,6 +4973,7 @@ typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7
 #define SYS_INFO_GPUCAPS__TMDSHDMI_COHERENT_SINGLEPLL_MODE                0x01
 #define SYS_INFO_GPUCAPS__DP_SINGLEPLL_MODE                               0x02
 #define SYS_INFO_GPUCAPS__DISABLE_AUX_MODE_DETECT                         0x08
+#define SYS_INFO_GPUCAPS__ENABEL_DFS_BYPASS                               0x10
 
 /**********************************************************************************************************************
   ATOM_INTEGRATED_SYSTEM_INFO_V1_7 Description
@@ -4947,6 +5073,9 @@ ucLVDSMisc:                       [bit0] LVDS 888bit panel mode =0: LVDS 888 pan
                                   [bit2] LVDS 888bit per color mode  =0: 666 bit per color =1:888 bit per color
                                   [bit3] LVDS parameter override enable  =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used
                                   [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low )
+                                  [bit5] Travid LVDS output voltage override enable, when =1, use ucTravisLVDSVolAdjust value to overwrite Traivs register LVDS_CTRL_4
+ucTravisLVDSVolAdjust             When ucLVDSMisc[5]=1,it means platform SBIOS want to overwrite TravisLVDSVoltage. Then VBIOS will use ucTravisLVDSVolAdjust
+                                  value to program Travis register LVDS_CTRL_4
 ucLVDSPwrOnSeqDIGONtoDE_in4Ms:    LVDS power up sequence time in unit of 4ms, time delay from DIGON signal active to data enable signal active( DE ).
                                   =0 mean use VBIOS default which is 8 ( 32ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON. 
                                   This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
@@ -4966,18 +5095,241 @@ ucLVDSOffToOnDelay_in4Ms:         LVDS power down sequence time in unit of 4ms.
                                   =0 means to use VBIOS default delay which is 125 ( 500ms ).
                                   This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
 
-ucLVDSPwrOnVARY_BLtoBLON_in4Ms:   LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active. 
+ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms:
+                                  LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active.
                                   =0 means to use VBIOS default delay which is 0 ( 0ms ).
                                   This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
 
-ucLVDSPwrOffBLONtoVARY_BL_in4Ms:  LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off. 
+ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms:
+                                  LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off.
                                   =0 means to use VBIOS default delay which is 0 ( 0ms ).
                                   This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
 
+ucMinAllowedBL_Level:             Lowest LCD backlight PWM level. This is customer platform specific parameters. By default it is 0.
+
 ulNbpStateMemclkFreq[4]:          system memory clock frequncey in unit of 10Khz in different NB pstate. 
 
 **********************************************************************************************************************/
 
+// this IntegrateSystemInfoTable is used for Kaveri & Kabini APU
+typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_8
+{
+  ATOM_COMMON_TABLE_HEADER   sHeader;
+  ULONG  ulBootUpEngineClock;
+  ULONG  ulDentistVCOFreq;
+  ULONG  ulBootUpUMAClock;
+  ATOM_CLK_VOLT_CAPABILITY   sDISPCLK_Voltage[4];
+  ULONG  ulBootUpReqDisplayVector;
+  ULONG  ulVBIOSMisc;
+  ULONG  ulGPUCapInfo;
+  ULONG  ulDISP_CLK2Freq;
+  USHORT usRequestedPWMFreqInHz;
+  UCHAR  ucHtcTmpLmt;
+  UCHAR  ucHtcHystLmt;
+  ULONG  ulReserved2;
+  ULONG  ulSystemConfig;
+  ULONG  ulCPUCapInfo;
+  ULONG  ulReserved3;
+  USHORT usGPUReservedSysMemSize;
+  USHORT usExtDispConnInfoOffset;
+  USHORT usPanelRefreshRateRange;
+  UCHAR  ucMemoryType;
+  UCHAR  ucUMAChannelNumber;
+  UCHAR  strVBIOSMsg[40];
+  ATOM_TDP_CONFIG  asTdpConfig;
+  ULONG  ulReserved[19];
+  ATOM_AVAILABLE_SCLK_LIST   sAvail_SCLK[5];
+  ULONG  ulGMCRestoreResetTime;
+  ULONG  ulReserved4;
+  ULONG  ulIdleNClk;
+  ULONG  ulDDR_DLL_PowerUpTime;
+  ULONG  ulDDR_PLL_PowerUpTime;
+  USHORT usPCIEClkSSPercentage;
+  USHORT usPCIEClkSSType;
+  USHORT usLvdsSSPercentage;
+  USHORT usLvdsSSpreadRateIn10Hz;
+  USHORT usHDMISSPercentage;
+  USHORT usHDMISSpreadRateIn10Hz;
+  USHORT usDVISSPercentage;
+  USHORT usDVISSpreadRateIn10Hz;
+  ULONG  ulGPUReservedSysMemBaseAddrLo;
+  ULONG  ulGPUReservedSysMemBaseAddrHi;
+  ULONG  ulReserved5[3];
+  USHORT usMaxLVDSPclkFreqInSingleLink;
+  UCHAR  ucLvdsMisc;
+  UCHAR  ucTravisLVDSVolAdjust;
+  UCHAR  ucLVDSPwrOnSeqDIGONtoDE_in4Ms;
+  UCHAR  ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms;
+  UCHAR  ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms;
+  UCHAR  ucLVDSPwrOffSeqDEtoDIGON_in4Ms;
+  UCHAR  ucLVDSOffToOnDelay_in4Ms;
+  UCHAR  ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms;
+  UCHAR  ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms;
+  UCHAR  ucMinAllowedBL_Level;
+  ULONG  ulLCDBitDepthControlVal;
+  ULONG  ulNbpStateMemclkFreq[4];
+  ULONG  ulReserved6;
+  ULONG  ulNbpStateNClkFreq[4];
+  USHORT usNBPStateVoltage[4];
+  USHORT usBootUpNBVoltage;
+  USHORT usReserved2;
+  ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo;
+}ATOM_INTEGRATED_SYSTEM_INFO_V1_8;
+
+/**********************************************************************************************************************
+  ATOM_INTEGRATED_SYSTEM_INFO_V1_8 Description
+ulBootUpEngineClock:              VBIOS bootup Engine clock frequency, in 10kHz unit. if it is equal 0, then VBIOS use pre-defined bootup engine clock
+ulDentistVCOFreq:                 Dentist VCO clock in 10kHz unit.
+ulBootUpUMAClock:                 System memory boot up clock frequency in 10Khz unit.
+sDISPCLK_Voltage:                 Report Display clock frequency requirement on GNB voltage(up to 4 voltage levels).
+
+ulBootUpReqDisplayVector:         VBIOS boot up display IDs, following are supported devices in Trinity projects:
+                                  ATOM_DEVICE_CRT1_SUPPORT                  0x0001
+                                  ATOM_DEVICE_DFP1_SUPPORT                  0x0008
+                                  ATOM_DEVICE_DFP6_SUPPORT                  0x0040
+                                  ATOM_DEVICE_DFP2_SUPPORT                  0x0080
+                                  ATOM_DEVICE_DFP3_SUPPORT                  0x0200
+                                  ATOM_DEVICE_DFP4_SUPPORT                  0x0400
+                                  ATOM_DEVICE_DFP5_SUPPORT                  0x0800
+                                  ATOM_DEVICE_LCD1_SUPPORT                  0x0002
+
+ulVBIOSMisc:                         Miscellenous flags for VBIOS requirement and interface
+                                  bit[0]=0: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is not supported by SBIOS.
+                                        =1: INT15 callback function Get LCD EDID ( ax=4e08, bl=1b ) is supported by SBIOS.
+                                  bit[1]=0: INT15 callback function Get boot display( ax=4e08, bl=01h) is not supported by SBIOS
+                                        =1: INT15 callback function Get boot display( ax=4e08, bl=01h) is supported by SBIOS
+                                  bit[2]=0: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is not supported by SBIOS
+                                        =1: INT15 callback function Get panel Expansion ( ax=4e08, bl=02h) is supported by SBIOS
+                                  bit[3]=0: VBIOS fast boot is disable
+                                        =1: VBIOS fast boot is enable. ( VBIOS skip display device detection in every set mode if LCD panel is connect and LID is open)
+
+ulGPUCapInfo:                     bit[0~2]= Reserved
+                                  bit[3]=0: Enable AUX HW mode detection logic
+                                        =1: Disable AUX HW mode detection logic
+                                  bit[4]=0: Disable DFS bypass feature
+                                        =1: Enable DFS bypass feature
+
+usRequestedPWMFreqInHz:           When it's set to 0x0 by SBIOS: the LCD BackLight is not controlled by GPU(SW).
+                                  Any attempt to change BL using VBIOS function or enable VariBri from PP table is not effective since ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==0;
+
+                                  When it's set to a non-zero frequency, the BackLight is controlled by GPU (SW) in one of two ways below:
+                                  1. SW uses the GPU BL PWM output to control the BL, in chis case, this non-zero frequency determines what freq GPU should use;
+                                  VBIOS will set up proper PWM frequency and ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1,as the result,
+                                  Changing BL using VBIOS function is functional in both driver and non-driver present environment;
+                                  and enabling VariBri under the driver environment from PP table is optional.
+
+                                  2. SW uses other means to control BL (like DPCD),this non-zero frequency serves as a flag only indicating
+                                  that BL control from GPU is expected.
+                                  VBIOS will NOT set up PWM frequency but make ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1
+                                  Changing BL using VBIOS function could be functional in both driver and non-driver present environment,but
+                                  it's per platform
+                                  and enabling VariBri under the driver environment from PP table is optional.
+
+ucHtcTmpLmt:                      Refer to D18F3x64 bit[22:16], HtcTmpLmt. Threshold on value to enter HTC_active state.
+ucHtcHystLmt:                     Refer to D18F3x64 bit[27:24], HtcHystLmt.
+                                  To calculate threshold off value to exit HTC_active state, which is Threshold on vlaue minus ucHtcHystLmt.
+
+ulSystemConfig:                   Bit[0]=0: PCIE Power Gating Disabled
+                                        =1: PCIE Power Gating Enabled
+                                  Bit[1]=0: DDR-DLL shut-down feature disabled.
+                                         1: DDR-DLL shut-down feature enabled.
+                                  Bit[2]=0: DDR-PLL Power down feature disabled.
+                                         1: DDR-PLL Power down feature enabled.
+                                  Bit[3]=0: GNB DPM is disabled
+                                        =1: GNB DPM is enabled
+ulCPUCapInfo:                     TBD
+
+usExtDispConnInfoOffset:          Offset to sExtDispConnInfo inside the structure
+usPanelRefreshRateRange:          Bit vector for LCD supported refresh rate range. If DRR is requestd by the platform, at least two bits need to be set
+                                  to indicate a range.
+                                  SUPPORTED_LCD_REFRESHRATE_30Hz          0x0004
+                                  SUPPORTED_LCD_REFRESHRATE_40Hz          0x0008
+                                  SUPPORTED_LCD_REFRESHRATE_50Hz          0x0010
+                                  SUPPORTED_LCD_REFRESHRATE_60Hz          0x0020
+
+ucMemoryType:                     [3:0]=1:DDR1;=2:DDR2;=3:DDR3;=5:GDDR5; [7:4] is reserved.
+ucUMAChannelNumber:                    System memory channel numbers.
+
+strVBIOSMsg[40]:                  VBIOS boot up customized message string
+
+sAvail_SCLK[5]:                   Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high
+
+ulGMCRestoreResetTime:            GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns.
+ulIdleNClk:                       NCLK speed while memory runs in self-refresh state, used to calculate self-refresh latency. Unit in 10kHz.
+ulDDR_DLL_PowerUpTime:            DDR PHY DLL power up time. Unit in ns.
+ulDDR_PLL_PowerUpTime:            DDR PHY PLL power up time. Unit in ns.
+
+usPCIEClkSSPercentage:            PCIE Clock Spread Spectrum Percentage in unit 0.01%; 100 mean 1%.
+usPCIEClkSSType:                  PCIE Clock Spread Spectrum Type. 0 for Down spread(default); 1 for Center spread.
+usLvdsSSPercentage:               LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting.
+usLvdsSSpreadRateIn10Hz:          LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting.
+usHDMISSPercentage:               HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%,  =0, use VBIOS default setting.
+usHDMISSpreadRateIn10Hz:          HDMI Spread Spectrum frequency in unit of 10Hz,  =0, use VBIOS default setting.
+usDVISSPercentage:                DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%,  =0, use VBIOS default setting.
+usDVISSpreadRateIn10Hz:           DVI Spread Spectrum frequency in unit of 10Hz,  =0, use VBIOS default setting.
+
+usGPUReservedSysMemSize:          Reserved system memory size for ACP engine in APU GNB, units in MB. 0/2/4MB based on CMOS options, current default could be 0MB. KV only, not on KB.
+ulGPUReservedSysMemBaseAddrLo:    Low 32 bits base address to the reserved system memory.
+ulGPUReservedSysMemBaseAddrHi:    High 32 bits base address to the reserved system memory.
+
+usMaxLVDSPclkFreqInSingleLink:    Max pixel clock LVDS panel single link, if=0 means VBIOS use default threhold, right now it is 85Mhz
+ucLVDSMisc:                       [bit0] LVDS 888bit panel mode =0: LVDS 888 panel in LDI mode, =1: LVDS 888 panel in FPDI mode
+                                  [bit1] LVDS panel lower and upper link mapping =0: lower link and upper link not swap, =1: lower link and upper link are swapped
+                                  [bit2] LVDS 888bit per color mode  =0: 666 bit per color =1:888 bit per color
+                                  [bit3] LVDS parameter override enable  =0: ucLvdsMisc parameter are not used =1: ucLvdsMisc parameter should be used
+                                  [bit4] Polarity of signal sent to digital BLON output pin. =0: not inverted(active high) =1: inverted ( active low )
+                                  [bit5] Travid LVDS output voltage override enable, when =1, use ucTravisLVDSVolAdjust value to overwrite Traivs register LVDS_CTRL_4
+ucTravisLVDSVolAdjust             When ucLVDSMisc[5]=1,it means platform SBIOS want to overwrite TravisLVDSVoltage. Then VBIOS will use ucTravisLVDSVolAdjust
+                                  value to program Travis register LVDS_CTRL_4
+ucLVDSPwrOnSeqDIGONtoDE_in4Ms:
+                                  LVDS power up sequence time in unit of 4ms, time delay from DIGON signal active to data enable signal active( DE ).
+                                  =0 mean use VBIOS default which is 8 ( 32ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON.
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSPwrOnDEtoVARY_BL_in4Ms:
+                                  LVDS power up sequence time in unit of 4ms., time delay from DE( data enable ) active to Vary Brightness enable signal active( VARY_BL ).
+                                  =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power up sequence is as following: DIGON->DE->VARY_BL->BLON.
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSPwrOffVARY_BLtoDE_in4Ms:
+                                  LVDS power down sequence time in unit of 4ms, time delay from data enable ( DE ) signal off to LCDVCC (DIGON) off.
+                                  =0 mean use VBIOS default delay which is 8 ( 32ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSPwrOffDEtoDIGON_in4Ms:
+                                   LVDS power down sequence time in unit of 4ms, time delay from vary brightness enable signal( VARY_BL) off to data enable ( DE ) signal off.
+                                  =0 mean use VBIOS default which is 90 ( 360ms ). The LVDS power down sequence is as following: BLON->VARY_BL->DE->DIGON
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSOffToOnDelay_in4Ms:
+                                  LVDS power down sequence time in unit of 4ms. Time delay from DIGON signal off to DIGON signal active.
+                                  =0 means to use VBIOS default delay which is 125 ( 500ms ).
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms:
+                                  LVDS power up sequence time in unit of 4ms. Time delay from VARY_BL signal on to DLON signal active.
+                                  =0 means to use VBIOS default delay which is 0 ( 0ms ).
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+
+ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms:
+                                  LVDS power down sequence time in unit of 4ms. Time delay from BLON signal off to VARY_BL signal off.
+                                  =0 means to use VBIOS default delay which is 0 ( 0ms ).
+                                  This parameter is used by VBIOS only. VBIOS will patch LVDS_InfoTable.
+ucMinAllowedBL_Level:             Lowest LCD backlight PWM level. This is customer platform specific parameters. By default it is 0.
+
+ulLCDBitDepthControlVal:          GPU display control encoder bit dither control setting, used to program register mmFMT_BIT_DEPTH_CONTROL
+
+ulNbpStateMemclkFreq[4]:          system memory clock frequncey in unit of 10Khz in different NB P-State(P0, P1, P2 & P3).
+ulNbpStateNClkFreq[4]:            NB P-State NClk frequency in different NB P-State
+usNBPStateVoltage[4]:             NB P-State (P0/P1 & P2/P3) voltage; NBP3 refers to lowes voltage
+usBootUpNBVoltage:                NB P-State voltage during boot up before driver loaded
+sExtDispConnInfo:                 Display connector information table provided to VBIOS
+
+**********************************************************************************************************************/
+
+// this Table is used for Kaveri/Kabini APU
+typedef struct _ATOM_FUSION_SYSTEM_INFO_V2
+{
+  ATOM_INTEGRATED_SYSTEM_INFO_V1_8    sIntegratedSysInfo;       // refer to ATOM_INTEGRATED_SYSTEM_INFO_V1_8 definition
+  ULONG                               ulPowerplayTable[128];    // Update comments here to link new powerplay table definition structure
+}ATOM_FUSION_SYSTEM_INFO_V2;
+
+
 /**************************************************************************/
 // This portion is only used when ext thermal chip or engine/memory clock SS chip is populated on a design
 //Memory SS Info Table
@@ -5028,22 +5380,24 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT
 
 //Define ucClockIndication, SW uses the IDs below to search if the SS is required/enabled on a clock branch/signal type.
 //SS is not required or enabled if a match is not found.
-#define ASIC_INTERNAL_MEMORY_SS                        1
-#define ASIC_INTERNAL_ENGINE_SS                        2
-#define ASIC_INTERNAL_UVD_SS        3
-#define ASIC_INTERNAL_SS_ON_TMDS    4
-#define ASIC_INTERNAL_SS_ON_HDMI    5
-#define ASIC_INTERNAL_SS_ON_LVDS    6
-#define ASIC_INTERNAL_SS_ON_DP      7
-#define ASIC_INTERNAL_SS_ON_DCPLL   8
-#define ASIC_EXTERNAL_SS_ON_DP_CLOCK 9
-#define ASIC_INTERNAL_VCE_SS        10
+#define ASIC_INTERNAL_MEMORY_SS                 1
+#define ASIC_INTERNAL_ENGINE_SS                 2
+#define ASIC_INTERNAL_UVD_SS             3
+#define ASIC_INTERNAL_SS_ON_TMDS         4
+#define ASIC_INTERNAL_SS_ON_HDMI         5
+#define ASIC_INTERNAL_SS_ON_LVDS         6
+#define ASIC_INTERNAL_SS_ON_DP           7
+#define ASIC_INTERNAL_SS_ON_DCPLL        8
+#define ASIC_EXTERNAL_SS_ON_DP_CLOCK     9
+#define ASIC_INTERNAL_VCE_SS             10
+#define ASIC_INTERNAL_GPUPLL_SS          11
+
 
 typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2
 {
        ULONG                                                           ulTargetClockRange;                                             //For mem/engine/uvd, Clock Out frequence (VCO ), in unit of 10Khz
                                                     //For TMDS/HDMI/LVDS, it is pixel clock , for DP, it is link clock ( 27000 or 16200 )
-  USHORT              usSpreadSpectrumPercentage;              //in unit of 0.01%
+  USHORT              usSpreadSpectrumPercentage;              //in unit of 0.01% or 0.001%, decided by ucSpreadSpectrumMode bit4
        USHORT                                                  usSpreadRateIn10Hz;                                             //in unit of 10Hz, modulation freq
   UCHAR               ucClockIndication;                                         //Indicate which clock source needs SS
        UCHAR                                                           ucSpreadSpectrumMode;                                   //Bit0=0 Down Spread,=1 Center Spread, bit1=0: internal SS bit1=1: external SS
@@ -5081,6 +5435,11 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V3
        UCHAR                                                           ucReserved[2];
 }ATOM_ASIC_SS_ASSIGNMENT_V3;
 
+//ATOM_ASIC_SS_ASSIGNMENT_V3.ucSpreadSpectrumMode
+#define SS_MODE_V3_CENTRE_SPREAD_MASK             0x01
+#define SS_MODE_V3_EXTERNAL_SS_MASK               0x02
+#define SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK    0x10
+
 typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3
 {
   ATOM_COMMON_TABLE_HEADER           sHeader; 
@@ -5721,6 +6080,7 @@ typedef struct _INDIRECT_IO_ACCESS
 #define INDIRECT_IO_PCIE           3
 #define INDIRECT_IO_PCIEP          4
 #define INDIRECT_IO_NBMISC         5
+#define INDIRECT_IO_SMU            5
 
 #define INDIRECT_IO_PLL_READ       INDIRECT_IO_PLL   | INDIRECT_READ
 #define INDIRECT_IO_PLL_WRITE      INDIRECT_IO_PLL   | INDIRECT_WRITE
@@ -5732,6 +6092,8 @@ typedef struct _INDIRECT_IO_ACCESS
 #define INDIRECT_IO_PCIEP_WRITE    INDIRECT_IO_PCIEP | INDIRECT_WRITE
 #define INDIRECT_IO_NBMISC_READ    INDIRECT_IO_NBMISC | INDIRECT_READ
 #define INDIRECT_IO_NBMISC_WRITE   INDIRECT_IO_NBMISC | INDIRECT_WRITE
+#define INDIRECT_IO_SMU_READ       INDIRECT_IO_SMU | INDIRECT_READ
+#define INDIRECT_IO_SMU_WRITE      INDIRECT_IO_SMU | INDIRECT_WRITE
 
 typedef struct _ATOM_OEM_INFO
 { 
@@ -5877,6 +6239,7 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE
 #define _64Mx32             0x43
 #define _128Mx8             0x51
 #define _128Mx16            0x52
+#define _128Mx32            0x53
 #define _256Mx8             0x61
 #define _256Mx16            0x62
 
@@ -5895,6 +6258,8 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE
 #define PROMOS              MOSEL
 #define KRETON              INFINEON
 #define ELIXIR              NANYA
+#define MEZZA               ELPIDA
+
 
 /////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM/////////////
 
@@ -6627,6 +6992,10 @@ typedef struct _ATOM_DISP_OUT_INFO_V3
        ASIC_TRANSMITTER_INFO_V2  asTransmitterInfo[1];     // for alligment only
 }ATOM_DISP_OUT_INFO_V3;
 
+//ucDispCaps
+#define DISPLAY_CAPS__DP_PCLK_FROM_PPLL        0x01
+#define DISPLAY_CAPS__FORCE_DISPDEV_CONNECTED  0x02
+
 typedef enum CORE_REF_CLK_SOURCE{
   CLOCK_SRC_XTALIN=0,
   CLOCK_SRC_XO_IN=1,
@@ -6831,6 +7200,17 @@ typedef struct _DIG_TRANSMITTER_INFO_HEADER_V3_1{
   USHORT usPhyPllSettingOffset;          // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy Pll Settings
 }DIG_TRANSMITTER_INFO_HEADER_V3_1;
 
+typedef struct _DIG_TRANSMITTER_INFO_HEADER_V3_2{
+  ATOM_COMMON_TABLE_HEADER sHeader;
+  USHORT usDPVsPreEmphSettingOffset;     // offset of PHY_ANALOG_SETTING_INFO * with DP Voltage Swing and Pre-Emphasis for each Link clock
+  USHORT usPhyAnalogRegListOffset;       // offset of CLOCK_CONDITION_REGESTER_INFO* with None-DP mode Analog Setting's register Info
+  USHORT usPhyAnalogSettingOffset;       // offset of CLOCK_CONDITION_SETTING_ENTRY* with None-DP mode Analog Setting for each link clock range
+  USHORT usPhyPllRegListOffset;          // offset of CLOCK_CONDITION_REGESTER_INFO* with Phy Pll register Info
+  USHORT usPhyPllSettingOffset;          // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy Pll Settings
+  USHORT usDPSSRegListOffset;            // offset of CLOCK_CONDITION_REGESTER_INFO* with Phy SS Pll register Info
+  USHORT usDPSSSettingOffset;            // offset of CLOCK_CONDITION_SETTING_ENTRY* with Phy SS Pll Settings
+}DIG_TRANSMITTER_INFO_HEADER_V3_2;
+
 typedef struct _CLOCK_CONDITION_REGESTER_INFO{
   USHORT usRegisterIndex;
   UCHAR  ucStartBit;
@@ -6854,12 +7234,24 @@ typedef struct _PHY_CONDITION_REG_VAL{
   ULONG  ulRegVal;
 }PHY_CONDITION_REG_VAL;
 
+typedef struct _PHY_CONDITION_REG_VAL_V2{
+  ULONG  ulCondition;
+  UCHAR  ucCondition2;
+  ULONG  ulRegVal;
+}PHY_CONDITION_REG_VAL_V2;
+
 typedef struct _PHY_CONDITION_REG_INFO{
   USHORT usRegIndex;
   USHORT usSize;
   PHY_CONDITION_REG_VAL asRegVal[1];
 }PHY_CONDITION_REG_INFO;
 
+typedef struct _PHY_CONDITION_REG_INFO_V2{
+  USHORT usRegIndex;
+  USHORT usSize;
+  PHY_CONDITION_REG_VAL_V2 asRegVal[1];
+}PHY_CONDITION_REG_INFO_V2;
+
 typedef struct _PHY_ANALOG_SETTING_INFO{
   UCHAR  ucEncodeMode;
   UCHAR  ucPhySel;
@@ -6867,6 +7259,25 @@ typedef struct _PHY_ANALOG_SETTING_INFO{
   PHY_CONDITION_REG_INFO  asAnalogSetting[1];
 }PHY_ANALOG_SETTING_INFO;
 
+typedef struct _PHY_ANALOG_SETTING_INFO_V2{
+  UCHAR  ucEncodeMode;
+  UCHAR  ucPhySel;
+  USHORT usSize;
+  PHY_CONDITION_REG_INFO_V2  asAnalogSetting[1];
+}PHY_ANALOG_SETTING_INFO_V2;
+
+typedef struct _GFX_HAVESTING_PARAMETERS {
+  UCHAR ucGfxBlkId;                        //GFX blk id to be harvested, like CU, RB or PRIM
+  UCHAR ucReserved;                        //reserved
+  UCHAR ucActiveUnitNumPerSH;              //requested active CU/RB/PRIM number per shader array
+  UCHAR ucMaxUnitNumPerSH;                 //max CU/RB/PRIM number per shader array
+} GFX_HAVESTING_PARAMETERS;
+
+//ucGfxBlkId
+#define GFX_HARVESTING_CU_ID               0
+#define GFX_HARVESTING_RB_ID               1
+#define GFX_HARVESTING_PRIM_ID             2
+
 /****************************************************************************/ 
 //Portion VI: Definitinos for vbios MC scratch registers that driver used
 /****************************************************************************/
@@ -6877,8 +7288,17 @@ typedef struct _PHY_ANALOG_SETTING_INFO{
 #define MC_MISC0__MEMORY_TYPE__GDDR3  0x30000000
 #define MC_MISC0__MEMORY_TYPE__GDDR4  0x40000000
 #define MC_MISC0__MEMORY_TYPE__GDDR5  0x50000000
+#define MC_MISC0__MEMORY_TYPE__HBM    0x60000000
 #define MC_MISC0__MEMORY_TYPE__DDR3   0xB0000000
 
+#define ATOM_MEM_TYPE_DDR_STRING      "DDR"
+#define ATOM_MEM_TYPE_DDR2_STRING     "DDR2"
+#define ATOM_MEM_TYPE_GDDR3_STRING    "GDDR3"
+#define ATOM_MEM_TYPE_GDDR4_STRING    "GDDR4"
+#define ATOM_MEM_TYPE_GDDR5_STRING    "GDDR5"
+#define ATOM_MEM_TYPE_HBM_STRING      "HBM"
+#define ATOM_MEM_TYPE_DDR3_STRING     "DDR3"
+
 /****************************************************************************/ 
 //Portion VI: Definitinos being oboselete
 /****************************************************************************/
@@ -7276,6 +7696,7 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER
 #define ATOM_PP_THERMALCONTROLLER_NISLANDS  15
 #define ATOM_PP_THERMALCONTROLLER_SISLANDS  16
 #define ATOM_PP_THERMALCONTROLLER_LM96163   17
+#define ATOM_PP_THERMALCONTROLLER_CISLANDS  18
 
 // Thermal controller 'combo type' to use an external controller for Fan control and an internal controller for thermal.
 // We probably should reserve the bit 0x80 for this use.
@@ -7318,6 +7739,8 @@ typedef struct _ATOM_PPLIB_EXTENDEDHEADER
     // Add extra system parameters here, always adjust size to include all fields.
     USHORT  usVCETableOffset; //points to ATOM_PPLIB_VCE_Table
     USHORT  usUVDTableOffset;   //points to ATOM_PPLIB_UVD_Table
+    USHORT  usSAMUTableOffset;  //points to ATOM_PPLIB_SAMU_Table
+    USHORT  usPPMTableOffset;   //points to ATOM_PPLIB_PPM_Table
 } ATOM_PPLIB_EXTENDEDHEADER;
 
 //// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps
@@ -7339,7 +7762,10 @@ typedef struct _ATOM_PPLIB_EXTENDEDHEADER
 #define ATOM_PP_PLATFORM_CAP_VDDCI_CONTROL 0x8000                   // Does the driver control VDDCI independently from VDDC.
 #define ATOM_PP_PLATFORM_CAP_REGULATOR_HOT 0x00010000               // Enable the 'regulator hot' feature.
 #define ATOM_PP_PLATFORM_CAP_BACO          0x00020000               // Does the driver supports BACO state.
-
+#define ATOM_PP_PLATFORM_CAP_NEW_CAC_VOLTAGE   0x00040000           // Does the driver supports new CAC voltage table.
+#define ATOM_PP_PLATFORM_CAP_REVERT_GPIO5_POLARITY   0x00080000     // Does the driver supports revert GPIO5 polarity.
+#define ATOM_PP_PLATFORM_CAP_OUTPUT_THERMAL2GPIO17   0x00100000     // Does the driver supports thermal2GPIO17.
+#define ATOM_PP_PLATFORM_CAP_VRHOT_GPIO_CONFIGURABLE   0x00200000   // Does the driver supports VR HOT GPIO Configurable.
 
 typedef struct _ATOM_PPLIB_POWERPLAYTABLE
 {
@@ -7400,7 +7826,7 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE4
     USHORT                     usVddcDependencyOnMCLKOffset;
     USHORT                     usMaxClockVoltageOnDCOffset;
     USHORT                     usVddcPhaseShedLimitsTableOffset;    // Points to ATOM_PPLIB_PhaseSheddingLimits_Table
-    USHORT                     usReserved;  
+    USHORT                     usMvddDependencyOnMCLKOffset;
 } ATOM_PPLIB_POWERPLAYTABLE4, *LPATOM_PPLIB_POWERPLAYTABLE4;
 
 typedef struct _ATOM_PPLIB_POWERPLAYTABLE5
@@ -7565,6 +7991,17 @@ typedef struct _ATOM_PPLIB_SI_CLOCK_INFO
 
 } ATOM_PPLIB_SI_CLOCK_INFO;
 
+typedef struct _ATOM_PPLIB_CI_CLOCK_INFO
+{
+      USHORT usEngineClockLow;
+      UCHAR  ucEngineClockHigh;
+
+      USHORT usMemoryClockLow;
+      UCHAR  ucMemoryClockHigh;
+
+      UCHAR  ucPCIEGen;
+      USHORT usPCIELane;
+} ATOM_PPLIB_CI_CLOCK_INFO;
 
 typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO
 
@@ -7682,8 +8119,8 @@ typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table
 
 typedef struct _ATOM_PPLIB_CAC_Leakage_Record
 {
-    USHORT usVddc;  // We use this field for the "fake" standardized VDDC for power calculations                                                  
-    ULONG  ulLeakageValue;
+    USHORT usVddc;  // We use this field for the "fake" standardized VDDC for power calculations; For CI and newer, we use this as the real VDDC value.
+    ULONG  ulLeakageValue;  // For CI and newer we use this as the "fake" standar VDDC value.
 }ATOM_PPLIB_CAC_Leakage_Record;
 
 typedef struct _ATOM_PPLIB_CAC_Leakage_Table
@@ -7798,6 +8235,42 @@ typedef struct _ATOM_PPLIB_UVD_Table
 //    ATOM_PPLIB_UVD_State_Table states;
 }ATOM_PPLIB_UVD_Table;
 
+
+typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Record
+{
+      USHORT usVoltage;
+      USHORT usSAMClockLow;
+      UCHAR  ucSAMClockHigh;
+}ATOM_PPLIB_SAMClk_Voltage_Limit_Record;
+
+typedef struct _ATOM_PPLIB_SAMClk_Voltage_Limit_Table{
+    UCHAR numEntries;
+    ATOM_PPLIB_SAMClk_Voltage_Limit_Record entries[1];
+}ATOM_PPLIB_SAMClk_Voltage_Limit_Table;
+
+typedef struct _ATOM_PPLIB_SAMU_Table
+{
+      UCHAR revid;
+      ATOM_PPLIB_SAMClk_Voltage_Limit_Table limits;
+}ATOM_PPLIB_SAMU_Table;
+
+#define ATOM_PPM_A_A    1
+#define ATOM_PPM_A_I    2
+typedef struct _ATOM_PPLIB_PPM_Table
+{
+      UCHAR  ucRevId;
+      UCHAR  ucPpmDesign;          //A+I or A+A
+      USHORT usCpuCoreNumber;
+      ULONG  ulPlatformTDP;
+      ULONG  ulSmallACPlatformTDP;
+      ULONG  ulPlatformTDC;
+      ULONG  ulSmallACPlatformTDC;
+      ULONG  ulApuTDP;
+      ULONG  ulDGpuTDP;
+      ULONG  ulDGpuUlvPower;
+      ULONG  ulTjmax;
+} ATOM_PPLIB_PPM_Table;
+
 /**************************************************************************/
 
 
index b0b1b62..0e8e408 100644 (file)
  *
  * Authors: Dave Airlie
  *          Alex Deucher
- *
- * $FreeBSD: head/sys/dev/drm2/radeon/atombios_crtc.c 254885 2013-08-25 19:37:15Z dumbbell $
  */
-
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
 #include <uapi_drm/radeon_drm.h>
@@ -558,7 +555,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc,
                if (rdev->family < CHIP_RV770)
                        radeon_crtc->pll_flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP;
                /* use frac fb div on APUs */
-               if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev))
+               if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
                        radeon_crtc->pll_flags |= RADEON_PLL_USE_FRAC_FB_DIV;
                /* use frac fb div on RS780/RS880 */
                if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
@@ -746,7 +743,7 @@ static void atombios_crtc_set_disp_eng_pll(struct radeon_device *rdev,
                         * SetPixelClock provides the dividers
                         */
                        args.v6.ulDispEngClkFreq = cpu_to_le32(dispclk);
-                       if (ASIC_IS_DCE61(rdev))
+                       if (ASIC_IS_DCE61(rdev) || ASIC_IS_DCE8(rdev))
                                args.v6.ucPpll = ATOM_EXT_PLL1;
                        else if (ASIC_IS_DCE6(rdev))
                                args.v6.ucPpll = ATOM_PPLL0;
@@ -1146,7 +1143,9 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        }
 
        if (tiling_flags & RADEON_TILING_MACRO) {
-               if (rdev->family >= CHIP_TAHITI)
+               if (rdev->family >= CHIP_BONAIRE)
+                       tmp = rdev->config.cik.tile_config;
+               else if (rdev->family >= CHIP_TAHITI)
                        tmp = rdev->config.si.tile_config;
                else if (rdev->family >= CHIP_CAYMAN)
                        tmp = rdev->config.cayman.tile_config;
@@ -1173,11 +1172,29 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
                fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw);
                fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh);
                fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect);
+               if (rdev->family >= CHIP_BONAIRE) {
+                       /* XXX need to know more about the surface tiling mode */
+                       fb_format |= CIK_GRPH_MICRO_TILE_MODE(CIK_DISPLAY_MICRO_TILING);
+               }
        } else if (tiling_flags & RADEON_TILING_MICRO)
                fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1);
 
-       if ((rdev->family == CHIP_TAHITI) ||
-           (rdev->family == CHIP_PITCAIRN))
+       if (rdev->family >= CHIP_BONAIRE) {
+               u32 num_pipe_configs = rdev->config.cik.max_tile_pipes;
+               u32 num_rb = rdev->config.cik.max_backends_per_se;
+               if (num_pipe_configs > 8)
+                       num_pipe_configs = 8;
+               if (num_pipe_configs == 8)
+                       fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P8_32x32_16x16);
+               else if (num_pipe_configs == 4) {
+                       if (num_rb == 4)
+                               fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_16x16);
+                       else if (num_rb < 4)
+                               fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P4_8x16);
+               } else if (num_pipe_configs == 2)
+                       fb_format |= CIK_GRPH_PIPE_CONFIG(CIK_ADDR_SURF_P2);
+       } else if ((rdev->family == CHIP_TAHITI) ||
+                  (rdev->family == CHIP_PITCAIRN))
                fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P8_32x32_8x16);
        else if (rdev->family == CHIP_VERDE)
                fb_format |= SI_GRPH_PIPE_CONFIG(SI_ADDR_SURF_P4_8x16);
@@ -1227,8 +1244,12 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
        WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, fb_pitch_pixels);
        WREG32(EVERGREEN_GRPH_ENABLE + radeon_crtc->crtc_offset, 1);
 
-       WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
-              target_fb->height);
+       if (rdev->family >= CHIP_BONAIRE)
+               WREG32(CIK_LB_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
+                      target_fb->height);
+       else
+               WREG32(EVERGREEN_DESKTOP_HEIGHT + radeon_crtc->crtc_offset,
+                      target_fb->height);
        x &= ~3;
        y &= ~1;
        WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
@@ -1600,6 +1621,12 @@ static int radeon_get_shared_nondp_ppll(struct drm_crtc *crtc)
  *
  * Asic specific PLL information
  *
+ * DCE 8.x
+ * KB/KV
+ * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP)
+ * CI
+ * - PPLL0, PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC
+ *
  * DCE 6.1
  * - PPLL2 is only available to UNIPHYA (both DP and non-DP)
  * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP)
@@ -1626,7 +1653,47 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
        u32 pll_in_use;
        int pll;
 
-       if (ASIC_IS_DCE61(rdev)) {
+       if (ASIC_IS_DCE8(rdev)) {
+               if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(radeon_crtc->encoder))) {
+                       if (rdev->clock.dp_extclk)
+                               /* skip PPLL programming if using ext clock */
+                               return ATOM_PPLL_INVALID;
+                       else {
+                               /* use the same PPLL for all DP monitors */
+                               pll = radeon_get_shared_dp_ppll(crtc);
+                               if (pll != ATOM_PPLL_INVALID)
+                                       return pll;
+                       }
+               } else {
+                       /* use the same PPLL for all monitors with the same clock */
+                       pll = radeon_get_shared_nondp_ppll(crtc);
+                       if (pll != ATOM_PPLL_INVALID)
+                               return pll;
+               }
+               /* otherwise, pick one of the plls */
+               if ((rdev->family == CHIP_KAVERI) ||
+                   (rdev->family == CHIP_KABINI)) {
+                       /* KB/KV has PPLL1 and PPLL2 */
+                       pll_in_use = radeon_get_pll_use_mask(crtc);
+                       if (!(pll_in_use & (1 << ATOM_PPLL2)))
+                               return ATOM_PPLL2;
+                       if (!(pll_in_use & (1 << ATOM_PPLL1)))
+                               return ATOM_PPLL1;
+                       DRM_ERROR("unable to allocate a PPLL\n");
+                       return ATOM_PPLL_INVALID;
+               } else {
+                       /* CI has PPLL0, PPLL1, and PPLL2 */
+                       pll_in_use = radeon_get_pll_use_mask(crtc);
+                       if (!(pll_in_use & (1 << ATOM_PPLL2)))
+                               return ATOM_PPLL2;
+                       if (!(pll_in_use & (1 << ATOM_PPLL1)))
+                               return ATOM_PPLL1;
+                       if (!(pll_in_use & (1 << ATOM_PPLL0)))
+                               return ATOM_PPLL0;
+                       DRM_ERROR("unable to allocate a PPLL\n");
+                       return ATOM_PPLL_INVALID;
+               }
+       } else if (ASIC_IS_DCE61(rdev)) {
                struct radeon_encoder_atom_dig *dig =
                        radeon_encoder->enc_priv;
 
@@ -1774,6 +1841,9 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
        atombios_crtc_set_base(crtc, x, y, old_fb);
        atombios_overscan_setup(crtc, mode, adjusted_mode);
        atombios_scaler_setup(crtc);
+       /* update the hw version fpr dpm */
+       radeon_crtc->hw_mode = *adjusted_mode;
+
        return 0;
 }
 
@@ -1864,7 +1934,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
                break;
        case ATOM_PPLL0:
                /* disable the ppll */
-               if (ASIC_IS_DCE61(rdev))
+               if ((rdev->family == CHIP_ARUBA) || (rdev->family == CHIP_BONAIRE))
                        atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
                                                  0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
                break;
index be8c84a..51a7428 100644 (file)
@@ -47,6 +47,41 @@ static char *pre_emph_names[] = {
 };
 
 /***** radeon AUX functions *****/
+
+/* Atom needs data in little endian format
+ * so swap as appropriate when copying data to
+ * or from atom. Note that atom operates on
+ * dw units.
+ */
+static void radeon_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
+{
+#ifdef __BIG_ENDIAN
+       u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */
+       u32 *dst32, *src32;
+       int i;
+
+       memcpy(src_tmp, src, num_bytes);
+       src32 = (u32 *)src_tmp;
+       dst32 = (u32 *)dst_tmp;
+       if (to_le) {
+               for (i = 0; i < ((num_bytes + 3) / 4); i++)
+                       dst32[i] = cpu_to_le32(src32[i]);
+               memcpy(dst, dst_tmp, num_bytes);
+       } else {
+               u8 dws = num_bytes & ~3;
+               for (i = 0; i < ((num_bytes + 3) / 4); i++)
+                       dst32[i] = le32_to_cpu(src32[i]);
+               memcpy(dst, dst_tmp, dws);
+               if (num_bytes % 4) {
+                       for (i = 0; i < (num_bytes % 4); i++)
+                               dst[dws+i] = dst_tmp[dws+i];
+               }
+       }
+#else
+       memcpy(dst, src, num_bytes);
+#endif
+}
+
 union aux_channel_transaction {
        PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
        PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
@@ -68,10 +103,10 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
 
        base = (unsigned char *)(rdev->mode_info.atom_context->scratch + 1);
 
-       memcpy(base, send, send_bytes);
+       radeon_copy_swap(base, send, send_bytes, true);
 
-       args.v1.lpAuxRequest = 0 + 4;
-       args.v1.lpDataOut = 16 + 4;
+       args.v1.lpAuxRequest = cpu_to_le16((u16)(0 + 4));
+       args.v1.lpDataOut = cpu_to_le16((u16)(16 + 4));
        args.v1.ucDataOutLen = 0;
        args.v1.ucChannelID = chan->rec.i2c_id;
        args.v1.ucDelay = delay / 10;
@@ -105,7 +140,7 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
                recv_bytes = recv_size;
 
        if (recv && recv_size)
-               memcpy(recv, base + 16, recv_bytes);
+               radeon_copy_swap(recv, base + 16, recv_bytes, false);
 
        return recv_bytes;
 }
index 134ec68..91df95f 100644 (file)
@@ -187,6 +187,13 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder,
        u8 backlight_level;
        char bl_name[16];
 
+       /* Mac laptops with multiple GPUs use the gmux driver for backlight
+        * so don't register a backlight device
+        */
+       if ((rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
+           (rdev->ddev->pci_device == 0x6741))
+               return;
+
        if (!radeon_encoder->enc_priv)
                return;
 
@@ -295,6 +302,7 @@ static inline bool radeon_encoder_is_digital(struct drm_encoder *encoder)
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
                return true;
        default:
                return false;
@@ -478,11 +486,11 @@ static u8 radeon_atom_get_bpc(struct drm_encoder *encoder)
        }
 }
 
-
 union dvo_encoder_control {
        ENABLE_EXTERNAL_TMDS_ENCODER_PS_ALLOCATION ext_tmds;
        DVO_ENCODER_CONTROL_PS_ALLOCATION dvo;
        DVO_ENCODER_CONTROL_PS_ALLOCATION_V3 dvo_v3;
+       DVO_ENCODER_CONTROL_PS_ALLOCATION_V1_4 dvo_v4;
 };
 
 void
@@ -532,6 +540,13 @@ atombios_dvo_setup(struct drm_encoder *encoder, int action)
                        args.dvo_v3.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
                        args.dvo_v3.ucDVOConfig = 0; /* XXX */
                        break;
+               case 4:
+                       /* DCE8 */
+                       args.dvo_v4.ucAction = action;
+                       args.dvo_v4.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
+                       args.dvo_v4.ucDVOConfig = 0; /* XXX */
+                       args.dvo_v4.ucBitPerColor = radeon_atom_get_bpc(encoder);
+                       break;
                default:
                        DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
                        break;
@@ -914,10 +929,14 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mo
                                args.v4.ucLaneNum = 4;
 
                        if (ENCODER_MODE_IS_DP(args.v4.ucEncoderMode)) {
-                               if (dp_clock == 270000)
-                                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
-                               else if (dp_clock == 540000)
+                               if (dp_clock == 540000)
                                        args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
+                               else if (dp_clock == 324000)
+                                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_3_24GHZ;
+                               else if (dp_clock == 270000)
+                                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ;
+                               else
+                                       args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ;
                        }
                        args.v4.acConfig.ucDigSel = dig->dig_encoder;
                        args.v4.ucBitPerColor = radeon_atom_get_bpc(encoder);
@@ -1011,6 +1030,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
                index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl);
                break;
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
@@ -1270,6 +1290,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t
                                else
                                        args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYE;
                                break;
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
+                               args.v5.ucPhyId = ATOM_PHY_ID_UNIPHYG;
+                               break;
                        }
                        if (is_dp)
                                args.v5.ucLaneNum = dp_lane_count;
@@ -1734,6 +1757,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode)
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
                radeon_atom_encoder_dpms_dig(encoder, mode);
                break;
@@ -1871,6 +1895,7 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
                        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+                       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
                        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
                                dig = radeon_encoder->enc_priv;
                                switch (dig->dig_encoder) {
@@ -1892,6 +1917,9 @@ atombios_set_encoder_crtc_source(struct drm_encoder *encoder)
                                case 5:
                                        args.v2.ucEncoderID = ASIC_INT_DIG6_ENCODER_ID;
                                        break;
+                               case 6:
+                                       args.v2.ucEncoderID = ASIC_INT_DIG7_ENCODER_ID;
+                                       break;
                                }
                                break;
                        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
@@ -1954,7 +1982,13 @@ atombios_apply_encoder_quirks(struct drm_encoder *encoder,
        /* set scaler clears this on some chips */
        if (ASIC_IS_AVIVO(rdev) &&
            (!(radeon_encoder->active_device & (ATOM_DEVICE_TV_SUPPORT)))) {
-               if (ASIC_IS_DCE4(rdev)) {
+               if (ASIC_IS_DCE8(rdev)) {
+                       if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+                               WREG32(CIK_LB_DATA_FORMAT + radeon_crtc->crtc_offset,
+                                      CIK_INTERLEAVE_EN);
+                       else
+                               WREG32(CIK_LB_DATA_FORMAT + radeon_crtc->crtc_offset, 0);
+               } else if (ASIC_IS_DCE4(rdev)) {
                        if (mode->flags & DRM_MODE_FLAG_INTERLACE)
                                WREG32(EVERGREEN_DATA_FORMAT + radeon_crtc->crtc_offset,
                                       EVERGREEN_INTERLEAVE_EN);
@@ -2001,6 +2035,9 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder)
                        else
                                return 4;
                        break;
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
+                       return 6;
+                       break;
                }
        } else if (ASIC_IS_DCE4(rdev)) {
                /* DCE4/5 */
@@ -2085,6 +2122,7 @@ radeon_atom_encoder_init(struct radeon_device *rdev)
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
                case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+               case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
                case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
                        atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
                        break;
@@ -2129,6 +2167,7 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
                /* handled in dpms */
                break;
@@ -2394,6 +2433,7 @@ static void radeon_atom_encoder_disable(struct drm_encoder *encoder)
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
                /* handled in dpms */
                break;
@@ -2630,6 +2670,7 @@ radeon_add_atom_encoder(struct drm_device *dev,
        case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:
        case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:
+       case ENCODER_OBJECT_ID_INTERNAL_UNIPHY3:
                if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {
                        radeon_encoder->rmx_type = RMX_FULL;
                        drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_LVDS);
index c46db9a..3c391e7 100644 (file)
@@ -23,8 +23,6 @@
  * Authors: Dave Airlie
  *          Alex Deucher
  *          Jerome Glisse
- *
- * $FreeBSD: head/sys/dev/drm2/radeon/avivod.h 254885 2013-08-25 19:37:15Z dumbbell $
  */
 #ifndef AVIVOD_H
 #define AVIVOD_H
diff --git a/sys/dev/drm/radeon/btc_dpm.c b/sys/dev/drm/radeon/btc_dpm.c
new file mode 100644 (file)
index 0000000..ee58a8b
--- /dev/null
@@ -0,0 +1,2740 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+
+#include <drm/drmP.h>
+#include "radeon.h"
+#include "btcd.h"
+#include "r600_dpm.h"
+#include "cypress_dpm.h"
+#include "btc_dpm.h"
+#include "atom.h"
+#include "radeon_asic.h"
+
+#define MC_CG_ARB_FREQ_F0           0x0a
+#define MC_CG_ARB_FREQ_F1           0x0b
+#define MC_CG_ARB_FREQ_F2           0x0c
+#define MC_CG_ARB_FREQ_F3           0x0d
+
+#define MC_CG_SEQ_DRAMCONF_S0       0x05
+#define MC_CG_SEQ_DRAMCONF_S1       0x06
+#define MC_CG_SEQ_YCLK_SUSPEND      0x04
+#define MC_CG_SEQ_YCLK_RESUME       0x0a
+
+#define SMC_RAM_END 0x8000
+
+#ifndef BTC_MGCG_SEQUENCE
+#define BTC_MGCG_SEQUENCE  300
+
+struct rv7xx_ps *rv770_get_ps(struct radeon_ps *rps);
+struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
+struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
+void btc_dpm_reset_asic(struct radeon_device *rdev);
+
+
+//********* BARTS **************//
+static const u32 barts_cgcg_cgls_default[] =
+{
+       /* Register,   Value,     Mask bits */
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff
+};
+#define BARTS_CGCG_CGLS_DEFAULT_LENGTH sizeof(barts_cgcg_cgls_default) / (3 * sizeof(u32))
+
+static const u32 barts_cgcg_cgls_disable[] =
+{
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x00000644, 0x000f7912, 0x001f4180,
+       0x00000644, 0x000f3812, 0x001f4180
+};
+#define BARTS_CGCG_CGLS_DISABLE_LENGTH sizeof(barts_cgcg_cgls_disable) / (3 * sizeof(u32))
+
+static const u32 barts_cgcg_cgls_enable[] =
+{
+       /* 0x0000c124, 0x84180000, 0x00180000, */
+       0x00000644, 0x000f7892, 0x001f4080,
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff
+};
+#define BARTS_CGCG_CGLS_ENABLE_LENGTH sizeof(barts_cgcg_cgls_enable) / (3 * sizeof(u32))
+
+static const u32 barts_mgcg_default[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x00005448, 0x00000100, 0xffffffff,
+       0x000055e4, 0x00600100, 0xffffffff,
+       0x0000160c, 0x00000100, 0xffffffff,
+       0x0000c164, 0x00000100, 0xffffffff,
+       0x00008a18, 0x00000100, 0xffffffff,
+       0x0000897c, 0x06000100, 0xffffffff,
+       0x00008b28, 0x00000100, 0xffffffff,
+       0x00009144, 0x00000100, 0xffffffff,
+       0x00009a60, 0x00000100, 0xffffffff,
+       0x00009868, 0x00000100, 0xffffffff,
+       0x00008d58, 0x00000100, 0xffffffff,
+       0x00009510, 0x00000100, 0xffffffff,
+       0x0000949c, 0x00000100, 0xffffffff,
+       0x00009654, 0x00000100, 0xffffffff,
+       0x00009030, 0x00000100, 0xffffffff,
+       0x00009034, 0x00000100, 0xffffffff,
+       0x00009038, 0x00000100, 0xffffffff,
+       0x0000903c, 0x00000100, 0xffffffff,
+       0x00009040, 0x00000100, 0xffffffff,
+       0x0000a200, 0x00000100, 0xffffffff,
+       0x0000a204, 0x00000100, 0xffffffff,
+       0x0000a208, 0x00000100, 0xffffffff,
+       0x0000a20c, 0x00000100, 0xffffffff,
+       0x0000977c, 0x00000100, 0xffffffff,
+       0x00003f80, 0x00000100, 0xffffffff,
+       0x0000a210, 0x00000100, 0xffffffff,
+       0x0000a214, 0x00000100, 0xffffffff,
+       0x000004d8, 0x00000100, 0xffffffff,
+       0x00009784, 0x00000100, 0xffffffff,
+       0x00009698, 0x00000100, 0xffffffff,
+       0x000004d4, 0x00000200, 0xffffffff,
+       0x000004d0, 0x00000000, 0xffffffff,
+       0x000030cc, 0x00000100, 0xffffffff,
+       0x0000d0c0, 0xff000100, 0xffffffff,
+       0x0000802c, 0x40000000, 0xffffffff,
+       0x0000915c, 0x00010000, 0xffffffff,
+       0x00009160, 0x00030002, 0xffffffff,
+       0x00009164, 0x00050004, 0xffffffff,
+       0x00009168, 0x00070006, 0xffffffff,
+       0x00009178, 0x00070000, 0xffffffff,
+       0x0000917c, 0x00030002, 0xffffffff,
+       0x00009180, 0x00050004, 0xffffffff,
+       0x0000918c, 0x00010006, 0xffffffff,
+       0x00009190, 0x00090008, 0xffffffff,
+       0x00009194, 0x00070000, 0xffffffff,
+       0x00009198, 0x00030002, 0xffffffff,
+       0x0000919c, 0x00050004, 0xffffffff,
+       0x000091a8, 0x00010006, 0xffffffff,
+       0x000091ac, 0x00090008, 0xffffffff,
+       0x000091b0, 0x00070000, 0xffffffff,
+       0x000091b4, 0x00030002, 0xffffffff,
+       0x000091b8, 0x00050004, 0xffffffff,
+       0x000091c4, 0x00010006, 0xffffffff,
+       0x000091c8, 0x00090008, 0xffffffff,
+       0x000091cc, 0x00070000, 0xffffffff,
+       0x000091d0, 0x00030002, 0xffffffff,
+       0x000091d4, 0x00050004, 0xffffffff,
+       0x000091e0, 0x00010006, 0xffffffff,
+       0x000091e4, 0x00090008, 0xffffffff,
+       0x000091e8, 0x00000000, 0xffffffff,
+       0x000091ec, 0x00070000, 0xffffffff,
+       0x000091f0, 0x00030002, 0xffffffff,
+       0x000091f4, 0x00050004, 0xffffffff,
+       0x00009200, 0x00010006, 0xffffffff,
+       0x00009204, 0x00090008, 0xffffffff,
+       0x00009208, 0x00070000, 0xffffffff,
+       0x0000920c, 0x00030002, 0xffffffff,
+       0x00009210, 0x00050004, 0xffffffff,
+       0x0000921c, 0x00010006, 0xffffffff,
+       0x00009220, 0x00090008, 0xffffffff,
+       0x00009224, 0x00070000, 0xffffffff,
+       0x00009228, 0x00030002, 0xffffffff,
+       0x0000922c, 0x00050004, 0xffffffff,
+       0x00009238, 0x00010006, 0xffffffff,
+       0x0000923c, 0x00090008, 0xffffffff,
+       0x00009294, 0x00000000, 0xffffffff,
+       0x0000802c, 0x40010000, 0xffffffff,
+       0x0000915c, 0x00010000, 0xffffffff,
+       0x00009160, 0x00030002, 0xffffffff,
+       0x00009164, 0x00050004, 0xffffffff,
+       0x00009168, 0x00070006, 0xffffffff,
+       0x00009178, 0x00070000, 0xffffffff,
+       0x0000917c, 0x00030002, 0xffffffff,
+       0x00009180, 0x00050004, 0xffffffff,
+       0x0000918c, 0x00010006, 0xffffffff,
+       0x00009190, 0x00090008, 0xffffffff,
+       0x00009194, 0x00070000, 0xffffffff,
+       0x00009198, 0x00030002, 0xffffffff,
+       0x0000919c, 0x00050004, 0xffffffff,
+       0x000091a8, 0x00010006, 0xffffffff,
+       0x000091ac, 0x00090008, 0xffffffff,
+       0x000091b0, 0x00070000, 0xffffffff,
+       0x000091b4, 0x00030002, 0xffffffff,
+       0x000091b8, 0x00050004, 0xffffffff,
+       0x000091c4, 0x00010006, 0xffffffff,
+       0x000091c8, 0x00090008, 0xffffffff,
+       0x000091cc, 0x00070000, 0xffffffff,
+       0x000091d0, 0x00030002, 0xffffffff,
+       0x000091d4, 0x00050004, 0xffffffff,
+       0x000091e0, 0x00010006, 0xffffffff,
+       0x000091e4, 0x00090008, 0xffffffff,
+       0x000091e8, 0x00000000, 0xffffffff,
+       0x000091ec, 0x00070000, 0xffffffff,
+       0x000091f0, 0x00030002, 0xffffffff,
+       0x000091f4, 0x00050004, 0xffffffff,
+       0x00009200, 0x00010006, 0xffffffff,
+       0x00009204, 0x00090008, 0xffffffff,
+       0x00009208, 0x00070000, 0xffffffff,
+       0x0000920c, 0x00030002, 0xffffffff,
+       0x00009210, 0x00050004, 0xffffffff,
+       0x0000921c, 0x00010006, 0xffffffff,
+       0x00009220, 0x00090008, 0xffffffff,
+       0x00009224, 0x00070000, 0xffffffff,
+       0x00009228, 0x00030002, 0xffffffff,
+       0x0000922c, 0x00050004, 0xffffffff,
+       0x00009238, 0x00010006, 0xffffffff,
+       0x0000923c, 0x00090008, 0xffffffff,
+       0x00009294, 0x00000000, 0xffffffff,
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff
+};
+#define BARTS_MGCG_DEFAULT_LENGTH sizeof(barts_mgcg_default) / (3 * sizeof(u32))
+
+static const u32 barts_mgcg_disable[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x000008f8, 0x00000000, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000001, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000002, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000003, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x00009150, 0x00600000, 0xffffffff
+};
+#define BARTS_MGCG_DISABLE_LENGTH sizeof(barts_mgcg_disable) / (3 * sizeof(u32))
+
+static const u32 barts_mgcg_enable[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x000008f8, 0x00000000, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000001, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000002, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000003, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x00009150, 0x81944000, 0xffffffff
+};
+#define BARTS_MGCG_ENABLE_LENGTH sizeof(barts_mgcg_enable) / (3 * sizeof(u32))
+
+//********* CAICOS **************//
+static const u32 caicos_cgcg_cgls_default[] =
+{
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff
+};
+#define CAICOS_CGCG_CGLS_DEFAULT_LENGTH sizeof(caicos_cgcg_cgls_default) / (3 * sizeof(u32))
+
+static const u32 caicos_cgcg_cgls_disable[] =
+{
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x00000644, 0x000f7912, 0x001f4180,
+       0x00000644, 0x000f3812, 0x001f4180
+};
+#define CAICOS_CGCG_CGLS_DISABLE_LENGTH sizeof(caicos_cgcg_cgls_disable) / (3 * sizeof(u32))
+
+static const u32 caicos_cgcg_cgls_enable[] =
+{
+       /* 0x0000c124, 0x84180000, 0x00180000, */
+       0x00000644, 0x000f7892, 0x001f4080,
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff
+};
+#define CAICOS_CGCG_CGLS_ENABLE_LENGTH sizeof(caicos_cgcg_cgls_enable) / (3 * sizeof(u32))
+
+static const u32 caicos_mgcg_default[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x00005448, 0x00000100, 0xffffffff,
+       0x000055e4, 0x00600100, 0xffffffff,
+       0x0000160c, 0x00000100, 0xffffffff,
+       0x0000c164, 0x00000100, 0xffffffff,
+       0x00008a18, 0x00000100, 0xffffffff,
+       0x0000897c, 0x06000100, 0xffffffff,
+       0x00008b28, 0x00000100, 0xffffffff,
+       0x00009144, 0x00000100, 0xffffffff,
+       0x00009a60, 0x00000100, 0xffffffff,
+       0x00009868, 0x00000100, 0xffffffff,
+       0x00008d58, 0x00000100, 0xffffffff,
+       0x00009510, 0x00000100, 0xffffffff,
+       0x0000949c, 0x00000100, 0xffffffff,
+       0x00009654, 0x00000100, 0xffffffff,
+       0x00009030, 0x00000100, 0xffffffff,
+       0x00009034, 0x00000100, 0xffffffff,
+       0x00009038, 0x00000100, 0xffffffff,
+       0x0000903c, 0x00000100, 0xffffffff,
+       0x00009040, 0x00000100, 0xffffffff,
+       0x0000a200, 0x00000100, 0xffffffff,
+       0x0000a204, 0x00000100, 0xffffffff,
+       0x0000a208, 0x00000100, 0xffffffff,
+       0x0000a20c, 0x00000100, 0xffffffff,
+       0x0000977c, 0x00000100, 0xffffffff,
+       0x00003f80, 0x00000100, 0xffffffff,
+       0x0000a210, 0x00000100, 0xffffffff,
+       0x0000a214, 0x00000100, 0xffffffff,
+       0x000004d8, 0x00000100, 0xffffffff,
+       0x00009784, 0x00000100, 0xffffffff,
+       0x00009698, 0x00000100, 0xffffffff,
+       0x000004d4, 0x00000200, 0xffffffff,
+       0x000004d0, 0x00000000, 0xffffffff,
+       0x000030cc, 0x00000100, 0xffffffff,
+       0x0000d0c0, 0xff000100, 0xffffffff,
+       0x0000915c, 0x00010000, 0xffffffff,
+       0x00009160, 0x00030002, 0xffffffff,
+       0x00009164, 0x00050004, 0xffffffff,
+       0x00009168, 0x00070006, 0xffffffff,
+       0x00009178, 0x00070000, 0xffffffff,
+       0x0000917c, 0x00030002, 0xffffffff,
+       0x00009180, 0x00050004, 0xffffffff,
+       0x0000918c, 0x00010006, 0xffffffff,
+       0x00009190, 0x00090008, 0xffffffff,
+       0x00009194, 0x00070000, 0xffffffff,
+       0x00009198, 0x00030002, 0xffffffff,
+       0x0000919c, 0x00050004, 0xffffffff,
+       0x000091a8, 0x00010006, 0xffffffff,
+       0x000091ac, 0x00090008, 0xffffffff,
+       0x000091e8, 0x00000000, 0xffffffff,
+       0x00009294, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff
+};
+#define CAICOS_MGCG_DEFAULT_LENGTH sizeof(caicos_mgcg_default) / (3 * sizeof(u32))
+
+static const u32 caicos_mgcg_disable[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x000008f8, 0x00000000, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000001, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000002, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000003, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x00009150, 0x00600000, 0xffffffff
+};
+#define CAICOS_MGCG_DISABLE_LENGTH sizeof(caicos_mgcg_disable) / (3 * sizeof(u32))
+
+static const u32 caicos_mgcg_enable[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x000008f8, 0x00000000, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000001, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000002, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000003, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x00009150, 0x46944040, 0xffffffff
+};
+#define CAICOS_MGCG_ENABLE_LENGTH sizeof(caicos_mgcg_enable) / (3 * sizeof(u32))
+
+//********* TURKS **************//
+static const u32 turks_cgcg_cgls_default[] =
+{
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff
+};
+#define TURKS_CGCG_CGLS_DEFAULT_LENGTH  sizeof(turks_cgcg_cgls_default) / (3 * sizeof(u32))
+
+static const u32 turks_cgcg_cgls_disable[] =
+{
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x00000644, 0x000f7912, 0x001f4180,
+       0x00000644, 0x000f3812, 0x001f4180
+};
+#define TURKS_CGCG_CGLS_DISABLE_LENGTH sizeof(turks_cgcg_cgls_disable) / (3 * sizeof(u32))
+
+static const u32 turks_cgcg_cgls_enable[] =
+{
+       /* 0x0000c124, 0x84180000, 0x00180000, */
+       0x00000644, 0x000f7892, 0x001f4080,
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000020, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000021, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000022, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000023, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000024, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000025, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000026, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000027, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000028, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000029, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000002a, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x0000002b, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff
+};
+#define TURKS_CGCG_CGLS_ENABLE_LENGTH sizeof(turks_cgcg_cgls_enable) / (3 * sizeof(u32))
+
+// These are the sequences for turks_mgcg_shls
+static const u32 turks_mgcg_default[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x00005448, 0x00000100, 0xffffffff,
+       0x000055e4, 0x00600100, 0xffffffff,
+       0x0000160c, 0x00000100, 0xffffffff,
+       0x0000c164, 0x00000100, 0xffffffff,
+       0x00008a18, 0x00000100, 0xffffffff,
+       0x0000897c, 0x06000100, 0xffffffff,
+       0x00008b28, 0x00000100, 0xffffffff,
+       0x00009144, 0x00000100, 0xffffffff,
+       0x00009a60, 0x00000100, 0xffffffff,
+       0x00009868, 0x00000100, 0xffffffff,
+       0x00008d58, 0x00000100, 0xffffffff,
+       0x00009510, 0x00000100, 0xffffffff,
+       0x0000949c, 0x00000100, 0xffffffff,
+       0x00009654, 0x00000100, 0xffffffff,
+       0x00009030, 0x00000100, 0xffffffff,
+       0x00009034, 0x00000100, 0xffffffff,
+       0x00009038, 0x00000100, 0xffffffff,
+       0x0000903c, 0x00000100, 0xffffffff,
+       0x00009040, 0x00000100, 0xffffffff,
+       0x0000a200, 0x00000100, 0xffffffff,
+       0x0000a204, 0x00000100, 0xffffffff,
+       0x0000a208, 0x00000100, 0xffffffff,
+       0x0000a20c, 0x00000100, 0xffffffff,
+       0x0000977c, 0x00000100, 0xffffffff,
+       0x00003f80, 0x00000100, 0xffffffff,
+       0x0000a210, 0x00000100, 0xffffffff,
+       0x0000a214, 0x00000100, 0xffffffff,
+       0x000004d8, 0x00000100, 0xffffffff,
+       0x00009784, 0x00000100, 0xffffffff,
+       0x00009698, 0x00000100, 0xffffffff,
+       0x000004d4, 0x00000200, 0xffffffff,
+       0x000004d0, 0x00000000, 0xffffffff,
+       0x000030cc, 0x00000100, 0xffffffff,
+       0x0000d0c0, 0x00000100, 0xffffffff,
+       0x0000915c, 0x00010000, 0xffffffff,
+       0x00009160, 0x00030002, 0xffffffff,
+       0x00009164, 0x00050004, 0xffffffff,
+       0x00009168, 0x00070006, 0xffffffff,
+       0x00009178, 0x00070000, 0xffffffff,
+       0x0000917c, 0x00030002, 0xffffffff,
+       0x00009180, 0x00050004, 0xffffffff,
+       0x0000918c, 0x00010006, 0xffffffff,
+       0x00009190, 0x00090008, 0xffffffff,
+       0x00009194, 0x00070000, 0xffffffff,
+       0x00009198, 0x00030002, 0xffffffff,
+       0x0000919c, 0x00050004, 0xffffffff,
+       0x000091a8, 0x00010006, 0xffffffff,
+       0x000091ac, 0x00090008, 0xffffffff,
+       0x000091b0, 0x00070000, 0xffffffff,
+       0x000091b4, 0x00030002, 0xffffffff,
+       0x000091b8, 0x00050004, 0xffffffff,
+       0x000091c4, 0x00010006, 0xffffffff,
+       0x000091c8, 0x00090008, 0xffffffff,
+       0x000091cc, 0x00070000, 0xffffffff,
+       0x000091d0, 0x00030002, 0xffffffff,
+       0x000091d4, 0x00050004, 0xffffffff,
+       0x000091e0, 0x00010006, 0xffffffff,
+       0x000091e4, 0x00090008, 0xffffffff,
+       0x000091e8, 0x00000000, 0xffffffff,
+       0x000091ec, 0x00070000, 0xffffffff,
+       0x000091f0, 0x00030002, 0xffffffff,
+       0x000091f4, 0x00050004, 0xffffffff,
+       0x00009200, 0x00010006, 0xffffffff,
+       0x00009204, 0x00090008, 0xffffffff,
+       0x00009208, 0x00070000, 0xffffffff,
+       0x0000920c, 0x00030002, 0xffffffff,
+       0x00009210, 0x00050004, 0xffffffff,
+       0x0000921c, 0x00010006, 0xffffffff,
+       0x00009220, 0x00090008, 0xffffffff,
+       0x00009294, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000010, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000011, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000012, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000013, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000014, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000015, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000016, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000017, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000018, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000019, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001a, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x0000001b, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff
+};
+#define TURKS_MGCG_DEFAULT_LENGTH sizeof(turks_mgcg_default) / (3 * sizeof(u32))
+
+static const u32 turks_mgcg_disable[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x000008f8, 0x00000000, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000001, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000002, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x000008f8, 0x00000003, 0xffffffff,
+       0x000008fc, 0xffffffff, 0xffffffff,
+       0x00009150, 0x00600000, 0xffffffff
+};
+#define TURKS_MGCG_DISABLE_LENGTH sizeof(turks_mgcg_disable) / (3 * sizeof(u32))
+
+static const u32 turks_mgcg_enable[] =
+{
+       0x0000802c, 0xc0000000, 0xffffffff,
+       0x000008f8, 0x00000000, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000001, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000002, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x000008f8, 0x00000003, 0xffffffff,
+       0x000008fc, 0x00000000, 0xffffffff,
+       0x00009150, 0x6e944000, 0xffffffff
+};
+#define TURKS_MGCG_ENABLE_LENGTH sizeof(turks_mgcg_enable) / (3 * sizeof(u32))
+
+#endif
+
+#ifndef BTC_SYSLS_SEQUENCE
+#define BTC_SYSLS_SEQUENCE  100
+
+
+//********* BARTS **************//
+static const u32 barts_sysls_default[] =
+{
+       /* Register,   Value,     Mask bits */
+       0x000055e8, 0x00000000, 0xffffffff,
+       0x0000d0bc, 0x00000000, 0xffffffff,
+       0x000015c0, 0x000c1401, 0xffffffff,
+       0x0000264c, 0x000c0400, 0xffffffff,
+       0x00002648, 0x000c0400, 0xffffffff,
+       0x00002650, 0x000c0400, 0xffffffff,
+       0x000020b8, 0x000c0400, 0xffffffff,
+       0x000020bc, 0x000c0400, 0xffffffff,
+       0x000020c0, 0x000c0c80, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680fff, 0xffffffff,
+       0x000004c8, 0x00000001, 0xffffffff,
+       0x000064ec, 0x00000000, 0xffffffff,
+       0x00000c7c, 0x00000000, 0xffffffff,
+       0x00006dfc, 0x00000000, 0xffffffff
+};
+#define BARTS_SYSLS_DEFAULT_LENGTH sizeof(barts_sysls_default) / (3 * sizeof(u32))
+
+static const u32 barts_sysls_disable[] =
+{
+       0x000055e8, 0x00000000, 0xffffffff,
+       0x0000d0bc, 0x00000000, 0xffffffff,
+       0x000015c0, 0x00041401, 0xffffffff,
+       0x0000264c, 0x00040400, 0xffffffff,
+       0x00002648, 0x00040400, 0xffffffff,
+       0x00002650, 0x00040400, 0xffffffff,
+       0x000020b8, 0x00040400, 0xffffffff,
+       0x000020bc, 0x00040400, 0xffffffff,
+       0x000020c0, 0x00040c80, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680000, 0xffffffff,
+       0x000004c8, 0x00000001, 0xffffffff,
+       0x000064ec, 0x00007ffd, 0xffffffff,
+       0x00000c7c, 0x0000ff00, 0xffffffff,
+       0x00006dfc, 0x0000007f, 0xffffffff
+};
+#define BARTS_SYSLS_DISABLE_LENGTH sizeof(barts_sysls_disable) / (3 * sizeof(u32))
+
+static const u32 barts_sysls_enable[] =
+{
+       0x000055e8, 0x00000001, 0xffffffff,
+       0x0000d0bc, 0x00000100, 0xffffffff,
+       0x000015c0, 0x000c1401, 0xffffffff,
+       0x0000264c, 0x000c0400, 0xffffffff,
+       0x00002648, 0x000c0400, 0xffffffff,
+       0x00002650, 0x000c0400, 0xffffffff,
+       0x000020b8, 0x000c0400, 0xffffffff,
+       0x000020bc, 0x000c0400, 0xffffffff,
+       0x000020c0, 0x000c0c80, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680fff, 0xffffffff,
+       0x000004c8, 0x00000000, 0xffffffff,
+       0x000064ec, 0x00000000, 0xffffffff,
+       0x00000c7c, 0x00000000, 0xffffffff,
+       0x00006dfc, 0x00000000, 0xffffffff
+};
+#define BARTS_SYSLS_ENABLE_LENGTH sizeof(barts_sysls_enable) / (3 * sizeof(u32))
+
+//********* CAICOS **************//
+static const u32 caicos_sysls_default[] =
+{
+       0x000055e8, 0x00000000, 0xffffffff,
+       0x0000d0bc, 0x00000000, 0xffffffff,
+       0x000015c0, 0x000c1401, 0xffffffff,
+       0x0000264c, 0x000c0400, 0xffffffff,
+       0x00002648, 0x000c0400, 0xffffffff,
+       0x00002650, 0x000c0400, 0xffffffff,
+       0x000020b8, 0x000c0400, 0xffffffff,
+       0x000020bc, 0x000c0400, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680fff, 0xffffffff,
+       0x000004c8, 0x00000001, 0xffffffff,
+       0x000064ec, 0x00000000, 0xffffffff,
+       0x00000c7c, 0x00000000, 0xffffffff,
+       0x00006dfc, 0x00000000, 0xffffffff
+};
+#define CAICOS_SYSLS_DEFAULT_LENGTH sizeof(caicos_sysls_default) / (3 * sizeof(u32))
+
+static const u32 caicos_sysls_disable[] =
+{
+       0x000055e8, 0x00000000, 0xffffffff,
+       0x0000d0bc, 0x00000000, 0xffffffff,
+       0x000015c0, 0x00041401, 0xffffffff,
+       0x0000264c, 0x00040400, 0xffffffff,
+       0x00002648, 0x00040400, 0xffffffff,
+       0x00002650, 0x00040400, 0xffffffff,
+       0x000020b8, 0x00040400, 0xffffffff,
+       0x000020bc, 0x00040400, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680000, 0xffffffff,
+       0x000004c8, 0x00000001, 0xffffffff,
+       0x000064ec, 0x00007ffd, 0xffffffff,
+       0x00000c7c, 0x0000ff00, 0xffffffff,
+       0x00006dfc, 0x0000007f, 0xffffffff
+};
+#define CAICOS_SYSLS_DISABLE_LENGTH sizeof(caicos_sysls_disable) / (3 * sizeof(u32))
+
+static const u32 caicos_sysls_enable[] =
+{
+       0x000055e8, 0x00000001, 0xffffffff,
+       0x0000d0bc, 0x00000100, 0xffffffff,
+       0x000015c0, 0x000c1401, 0xffffffff,
+       0x0000264c, 0x000c0400, 0xffffffff,
+       0x00002648, 0x000c0400, 0xffffffff,
+       0x00002650, 0x000c0400, 0xffffffff,
+       0x000020b8, 0x000c0400, 0xffffffff,
+       0x000020bc, 0x000c0400, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680fff, 0xffffffff,
+       0x000064ec, 0x00000000, 0xffffffff,
+       0x00000c7c, 0x00000000, 0xffffffff,
+       0x00006dfc, 0x00000000, 0xffffffff,
+       0x000004c8, 0x00000000, 0xffffffff
+};
+#define CAICOS_SYSLS_ENABLE_LENGTH sizeof(caicos_sysls_enable) / (3 * sizeof(u32))
+
+//********* TURKS **************//
+static const u32 turks_sysls_default[] =
+{
+       0x000055e8, 0x00000000, 0xffffffff,
+       0x0000d0bc, 0x00000000, 0xffffffff,
+       0x000015c0, 0x000c1401, 0xffffffff,
+       0x0000264c, 0x000c0400, 0xffffffff,
+       0x00002648, 0x000c0400, 0xffffffff,
+       0x00002650, 0x000c0400, 0xffffffff,
+       0x000020b8, 0x000c0400, 0xffffffff,
+       0x000020bc, 0x000c0400, 0xffffffff,
+       0x000020c0, 0x000c0c80, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680fff, 0xffffffff,
+       0x000004c8, 0x00000001, 0xffffffff,
+       0x000064ec, 0x00000000, 0xffffffff,
+       0x00000c7c, 0x00000000, 0xffffffff,
+       0x00006dfc, 0x00000000, 0xffffffff
+};
+#define TURKS_SYSLS_DEFAULT_LENGTH sizeof(turks_sysls_default) / (3 * sizeof(u32))
+
+static const u32 turks_sysls_disable[] =
+{
+       0x000055e8, 0x00000000, 0xffffffff,
+       0x0000d0bc, 0x00000000, 0xffffffff,
+       0x000015c0, 0x00041401, 0xffffffff,
+       0x0000264c, 0x00040400, 0xffffffff,
+       0x00002648, 0x00040400, 0xffffffff,
+       0x00002650, 0x00040400, 0xffffffff,
+       0x000020b8, 0x00040400, 0xffffffff,
+       0x000020bc, 0x00040400, 0xffffffff,
+       0x000020c0, 0x00040c80, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680000, 0xffffffff,
+       0x000004c8, 0x00000001, 0xffffffff,
+       0x000064ec, 0x00007ffd, 0xffffffff,
+       0x00000c7c, 0x0000ff00, 0xffffffff,
+       0x00006dfc, 0x0000007f, 0xffffffff
+};
+#define TURKS_SYSLS_DISABLE_LENGTH sizeof(turks_sysls_disable) / (3 * sizeof(u32))
+
+static const u32 turks_sysls_enable[] =
+{
+       0x000055e8, 0x00000001, 0xffffffff,
+       0x0000d0bc, 0x00000100, 0xffffffff,
+       0x000015c0, 0x000c1401, 0xffffffff,
+       0x0000264c, 0x000c0400, 0xffffffff,
+       0x00002648, 0x000c0400, 0xffffffff,
+       0x00002650, 0x000c0400, 0xffffffff,
+       0x000020b8, 0x000c0400, 0xffffffff,
+       0x000020bc, 0x000c0400, 0xffffffff,
+       0x000020c0, 0x000c0c80, 0xffffffff,
+       0x0000f4a0, 0x000000c0, 0xffffffff,
+       0x0000f4a4, 0x00680fff, 0xffffffff,
+       0x000004c8, 0x00000000, 0xffffffff,
+       0x000064ec, 0x00000000, 0xffffffff,
+       0x00000c7c, 0x00000000, 0xffffffff,
+       0x00006dfc, 0x00000000, 0xffffffff
+};
+#define TURKS_SYSLS_ENABLE_LENGTH sizeof(turks_sysls_enable) / (3 * sizeof(u32))
+
+#endif
+
+u32 btc_valid_sclk[40] =
+{
+       5000,   10000,  15000,  20000,  25000,  30000,  35000,  40000,  45000,  50000,
+       55000,  60000,  65000,  70000,  75000,  80000,  85000,  90000,  95000,  100000,
+       105000, 110000, 11500,  120000, 125000, 130000, 135000, 140000, 145000, 150000,
+       155000, 160000, 165000, 170000, 175000, 180000, 185000, 190000, 195000, 200000
+};
+
+static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
+{
+        { 10000, 30000, RADEON_SCLK_UP },
+        { 15000, 30000, RADEON_SCLK_UP },
+        { 20000, 30000, RADEON_SCLK_UP },
+        { 25000, 30000, RADEON_SCLK_UP }
+};
+
+void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
+                                       u32 clock, u16 max_voltage, u16 *voltage)
+{
+       u32 i;
+
+       if ((table == NULL) || (table->count == 0))
+               return;
+
+       for (i= 0; i < table->count; i++) {
+               if (clock <= table->entries[i].clk) {
+                       if (*voltage < table->entries[i].v)
+                               *voltage = (u16)((table->entries[i].v < max_voltage) ?
+                                                 table->entries[i].v : max_voltage);
+                       return;
+               }
+       }
+
+       *voltage = (*voltage > max_voltage) ? *voltage : max_voltage;
+}
+
+static u32 btc_find_valid_clock(struct radeon_clock_array *clocks,
+                               u32 max_clock, u32 requested_clock)
+{
+       unsigned int i;
+
+       if ((clocks == NULL) || (clocks->count == 0))
+               return (requested_clock < max_clock) ? requested_clock : max_clock;
+
+       for (i = 0; i < clocks->count; i++) {
+               if (clocks->values[i] >= requested_clock)
+                       return (clocks->values[i] < max_clock) ? clocks->values[i] : max_clock;
+       }
+
+       return (clocks->values[clocks->count - 1] < max_clock) ?
+               clocks->values[clocks->count - 1] : max_clock;
+}
+
+static u32 btc_get_valid_mclk(struct radeon_device *rdev,
+                             u32 max_mclk, u32 requested_mclk)
+{
+       return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_mclk_values,
+                                   max_mclk, requested_mclk);
+}
+
+static u32 btc_get_valid_sclk(struct radeon_device *rdev,
+                             u32 max_sclk, u32 requested_sclk)
+{
+       return btc_find_valid_clock(&rdev->pm.dpm.dyn_state.valid_sclk_values,
+                                   max_sclk, requested_sclk);
+}
+
+void btc_skip_blacklist_clocks(struct radeon_device *rdev,
+                              const u32 max_sclk, const u32 max_mclk,
+                              u32 *sclk, u32 *mclk)
+{
+       int i, num_blacklist_clocks;
+
+       if ((sclk == NULL) || (mclk == NULL))
+               return;
+
+       num_blacklist_clocks = ARRAY_SIZE(btc_blacklist_clocks);
+
+       for (i = 0; i < num_blacklist_clocks; i++) {
+               if ((btc_blacklist_clocks[i].sclk == *sclk) &&
+                   (btc_blacklist_clocks[i].mclk == *mclk))
+                       break;
+       }
+
+       if (i < num_blacklist_clocks) {
+               if (btc_blacklist_clocks[i].action == RADEON_SCLK_UP) {
+                       *sclk = btc_get_valid_sclk(rdev, max_sclk, *sclk + 1);
+
+                       if (*sclk < max_sclk)
+                               btc_skip_blacklist_clocks(rdev, max_sclk, max_mclk, sclk, mclk);
+               }
+       }
+}
+
+void btc_adjust_clock_combinations(struct radeon_device *rdev,
+                                  const struct radeon_clock_and_voltage_limits *max_limits,
+                                  struct rv7xx_pl *pl)
+{
+
+       if ((pl->mclk == 0) || (pl->sclk == 0))
+               return;
+
+       if (pl->mclk == pl->sclk)
+               return;
+
+       if (pl->mclk > pl->sclk) {
+               if (((pl->mclk + (pl->sclk - 1)) / pl->sclk) > rdev->pm.dpm.dyn_state.mclk_sclk_ratio)
+                       pl->sclk = btc_get_valid_sclk(rdev,
+                                                     max_limits->sclk,
+                                                     (pl->mclk +
+                                                      (rdev->pm.dpm.dyn_state.mclk_sclk_ratio - 1)) /
+                                                     rdev->pm.dpm.dyn_state.mclk_sclk_ratio);
+       } else {
+               if ((pl->sclk - pl->mclk) > rdev->pm.dpm.dyn_state.sclk_mclk_delta)
+                       pl->mclk = btc_get_valid_mclk(rdev,
+                                                     max_limits->mclk,
+                                                     pl->sclk -
+                                                     rdev->pm.dpm.dyn_state.sclk_mclk_delta);
+       }
+}
+
+static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
+{
+       unsigned int i;
+
+       for (i = 0; i < table->count; i++) {
+               if (voltage <= table->entries[i].value)
+                       return table->entries[i].value;
+       }
+
+       return table->entries[table->count - 1].value;
+}
+
+void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
+                                  u16 max_vddc, u16 max_vddci,
+                                  u16 *vddc, u16 *vddci)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       u16 new_voltage;
+
+       if ((0 == *vddc) || (0 == *vddci))
+               return;
+
+       if (*vddc > *vddci) {
+               if ((*vddc - *vddci) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
+                       new_voltage = btc_find_voltage(&eg_pi->vddci_voltage_table,
+                                                      (*vddc - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
+                       *vddci = (new_voltage < max_vddci) ? new_voltage : max_vddci;
+               }
+       } else {
+               if ((*vddci - *vddc) > rdev->pm.dpm.dyn_state.vddc_vddci_delta) {
+                       new_voltage = btc_find_voltage(&eg_pi->vddc_voltage_table,
+                                                      (*vddci - rdev->pm.dpm.dyn_state.vddc_vddci_delta));
+                       *vddc = (new_voltage < max_vddc) ? new_voltage : max_vddc;
+               }
+       }
+}
+
+static void btc_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
+                                            bool enable)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       u32 tmp, bif;
+
+       tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
+       if (enable) {
+               if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
+                   (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+                       if (!pi->boot_in_gen2) {
+                               bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
+                               bif |= CG_CLIENT_REQ(0xd);
+                               WREG32(CG_BIF_REQ_AND_RSP, bif);
+
+                               tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+                               tmp |= LC_HW_VOLTAGE_IF_CONTROL(1);
+                               tmp |= LC_GEN2_EN_STRAP;
+
+                               tmp |= LC_CLR_FAILED_SPD_CHANGE_CNT;
+                               WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+                               DRM_UDELAY(10);
+                               tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
+                               WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+                       }
+               }
+       } else {
+               if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
+                   (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
+                       if (!pi->boot_in_gen2) {
+                               bif = RREG32(CG_BIF_REQ_AND_RSP) & ~CG_CLIENT_REQ_MASK;
+                               bif |= CG_CLIENT_REQ(0xd);
+                               WREG32(CG_BIF_REQ_AND_RSP, bif);
+
+                               tmp &= ~LC_HW_VOLTAGE_IF_CONTROL_MASK;
+                               tmp &= ~LC_GEN2_EN_STRAP;
+                       }
+                       WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
+               }
+       }
+}
+
+static void btc_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
+                                        bool enable)
+{
+       btc_enable_bif_dynamic_pcie_gen2(rdev, enable);
+
+       if (enable)
+               WREG32_P(GENERAL_PWRMGT, ENABLE_GEN2PCIE, ~ENABLE_GEN2PCIE);
+       else
+               WREG32_P(GENERAL_PWRMGT, 0, ~ENABLE_GEN2PCIE);
+}
+
+static int btc_disable_ulv(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+       if (eg_pi->ulv.supported) {
+               if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableULV) != PPSMC_Result_OK)
+                       return -EINVAL;
+       }
+       return 0;
+}
+
+static int btc_populate_ulv_state(struct radeon_device *rdev,
+                                 RV770_SMC_STATETABLE *table)
+{
+       int ret = -EINVAL;
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
+
+       if (ulv_pl->vddc) {
+               ret = cypress_convert_power_level_to_smc(rdev,
+                                                        ulv_pl,
+                                                        &table->ULVState.levels[0],
+                                                        PPSMC_DISPLAY_WATERMARK_LOW);
+               if (ret == 0) {
+                       table->ULVState.levels[0].arbValue = MC_CG_ARB_FREQ_F0;
+                       table->ULVState.levels[0].ACIndex = 1;
+
+                       table->ULVState.levels[1] = table->ULVState.levels[0];
+                       table->ULVState.levels[2] = table->ULVState.levels[0];
+
+                       table->ULVState.flags |= PPSMC_SWSTATE_FLAG_DC;
+
+                       WREG32(CG_ULV_CONTROL, BTC_CGULVCONTROL_DFLT);
+                       WREG32(CG_ULV_PARAMETER, BTC_CGULVPARAMETER_DFLT);
+               }
+       }
+
+       return ret;
+}
+
+static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
+                                      RV770_SMC_STATETABLE *table)
+{
+       int ret = cypress_populate_smc_acpi_state(rdev, table);
+
+       if (ret == 0) {
+               table->ACPIState.levels[0].ACIndex = 0;
+               table->ACPIState.levels[1].ACIndex = 0;
+               table->ACPIState.levels[2].ACIndex = 0;
+       }
+
+       return ret;
+}
+
+void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
+                                 const u32 *sequence, u32 count)
+{
+       u32 i, length = count * 3;
+       u32 tmp;
+
+       for (i = 0; i < length; i+=3) {
+               tmp = RREG32(sequence[i]);
+               tmp &= ~sequence[i+2];
+               tmp |= sequence[i+1] & sequence[i+2];
+               WREG32(sequence[i], tmp);
+       }
+}
+
+static void btc_cg_clock_gating_default(struct radeon_device *rdev)
+{
+       u32 count;
+       const u32 *p = NULL;
+
+       if (rdev->family == CHIP_BARTS) {
+               p = (const u32 *)&barts_cgcg_cgls_default;
+               count = BARTS_CGCG_CGLS_DEFAULT_LENGTH;
+       } else if (rdev->family == CHIP_TURKS) {
+               p = (const u32 *)&turks_cgcg_cgls_default;
+               count = TURKS_CGCG_CGLS_DEFAULT_LENGTH;
+       } else if (rdev->family == CHIP_CAICOS) {
+               p = (const u32 *)&caicos_cgcg_cgls_default;
+               count = CAICOS_CGCG_CGLS_DEFAULT_LENGTH;
+       } else
+               return;
+
+       btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_cg_clock_gating_enable(struct radeon_device *rdev,
+                                      bool enable)
+{
+       u32 count;
+       const u32 *p = NULL;
+
+       if (enable) {
+               if (rdev->family == CHIP_BARTS) {
+                       p = (const u32 *)&barts_cgcg_cgls_enable;
+                       count = BARTS_CGCG_CGLS_ENABLE_LENGTH;
+               } else if (rdev->family == CHIP_TURKS) {
+                       p = (const u32 *)&turks_cgcg_cgls_enable;
+                       count = TURKS_CGCG_CGLS_ENABLE_LENGTH;
+               } else if (rdev->family == CHIP_CAICOS) {
+                       p = (const u32 *)&caicos_cgcg_cgls_enable;
+                       count = CAICOS_CGCG_CGLS_ENABLE_LENGTH;
+               } else
+                       return;
+       } else {
+               if (rdev->family == CHIP_BARTS) {
+                       p = (const u32 *)&barts_cgcg_cgls_disable;
+                       count = BARTS_CGCG_CGLS_DISABLE_LENGTH;
+               } else if (rdev->family == CHIP_TURKS) {
+                       p = (const u32 *)&turks_cgcg_cgls_disable;
+                       count = TURKS_CGCG_CGLS_DISABLE_LENGTH;
+               } else if (rdev->family == CHIP_CAICOS) {
+                       p = (const u32 *)&caicos_cgcg_cgls_disable;
+                       count = CAICOS_CGCG_CGLS_DISABLE_LENGTH;
+               } else
+                       return;
+       }
+
+       btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_mg_clock_gating_default(struct radeon_device *rdev)
+{
+       u32 count;
+       const u32 *p = NULL;
+
+       if (rdev->family == CHIP_BARTS) {
+               p = (const u32 *)&barts_mgcg_default;
+               count = BARTS_MGCG_DEFAULT_LENGTH;
+       } else if (rdev->family == CHIP_TURKS) {
+               p = (const u32 *)&turks_mgcg_default;
+               count = TURKS_MGCG_DEFAULT_LENGTH;
+       } else if (rdev->family == CHIP_CAICOS) {
+               p = (const u32 *)&caicos_mgcg_default;
+               count = CAICOS_MGCG_DEFAULT_LENGTH;
+       } else
+               return;
+
+       btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_mg_clock_gating_enable(struct radeon_device *rdev,
+                                      bool enable)
+{
+       u32 count;
+       const u32 *p = NULL;
+
+       if (enable) {
+               if (rdev->family == CHIP_BARTS) {
+                       p = (const u32 *)&barts_mgcg_enable;
+                       count = BARTS_MGCG_ENABLE_LENGTH;
+               } else if (rdev->family == CHIP_TURKS) {
+                       p = (const u32 *)&turks_mgcg_enable;
+                       count = TURKS_MGCG_ENABLE_LENGTH;
+               } else if (rdev->family == CHIP_CAICOS) {
+                       p = (const u32 *)&caicos_mgcg_enable;
+                       count = CAICOS_MGCG_ENABLE_LENGTH;
+               } else
+                       return;
+       } else {
+               if (rdev->family == CHIP_BARTS) {
+                       p = (const u32 *)&barts_mgcg_disable[0];
+                       count = BARTS_MGCG_DISABLE_LENGTH;
+               } else if (rdev->family == CHIP_TURKS) {
+                       p = (const u32 *)&turks_mgcg_disable[0];
+                       count = TURKS_MGCG_DISABLE_LENGTH;
+               } else if (rdev->family == CHIP_CAICOS) {
+                       p = (const u32 *)&caicos_mgcg_disable[0];
+                       count = CAICOS_MGCG_DISABLE_LENGTH;
+               } else
+                       return;
+       }
+
+       btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_ls_clock_gating_default(struct radeon_device *rdev)
+{
+       u32 count;
+       const u32 *p = NULL;
+
+       if (rdev->family == CHIP_BARTS) {
+               p = (const u32 *)&barts_sysls_default;
+               count = BARTS_SYSLS_DEFAULT_LENGTH;
+       } else if (rdev->family == CHIP_TURKS) {
+               p = (const u32 *)&turks_sysls_default;
+               count = TURKS_SYSLS_DEFAULT_LENGTH;
+       } else if (rdev->family == CHIP_CAICOS) {
+               p = (const u32 *)&caicos_sysls_default;
+               count = CAICOS_SYSLS_DEFAULT_LENGTH;
+       } else
+               return;
+
+       btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
+                                      bool enable)
+{
+       u32 count;
+       const u32 *p = NULL;
+
+       if (enable) {
+               if (rdev->family == CHIP_BARTS) {
+                       p = (const u32 *)&barts_sysls_enable;
+                       count = BARTS_SYSLS_ENABLE_LENGTH;
+               } else if (rdev->family == CHIP_TURKS) {
+                       p = (const u32 *)&turks_sysls_enable;
+                       count = TURKS_SYSLS_ENABLE_LENGTH;
+               } else if (rdev->family == CHIP_CAICOS) {
+                       p = (const u32 *)&caicos_sysls_enable;
+                       count = CAICOS_SYSLS_ENABLE_LENGTH;
+               } else
+                       return;
+       } else {
+               if (rdev->family == CHIP_BARTS) {
+                       p = (const u32 *)&barts_sysls_disable;
+                       count = BARTS_SYSLS_DISABLE_LENGTH;
+               } else if (rdev->family == CHIP_TURKS) {
+                       p = (const u32 *)&turks_sysls_disable;
+                       count = TURKS_SYSLS_DISABLE_LENGTH;
+               } else if (rdev->family == CHIP_CAICOS) {
+                       p = (const u32 *)&caicos_sysls_disable;
+                       count = CAICOS_SYSLS_DISABLE_LENGTH;
+               } else
+                       return;
+       }
+
+       btc_program_mgcg_hw_sequence(rdev, p, count);
+}
+
+bool btc_dpm_enabled(struct radeon_device *rdev)
+{
+       if (rv770_is_smc_running(rdev))
+               return true;
+       else
+               return false;
+}
+
+static int btc_init_smc_table(struct radeon_device *rdev,
+                             struct radeon_ps *radeon_boot_state)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       RV770_SMC_STATETABLE *table = &pi->smc_statetable;
+       int ret;
+
+       memset(table, 0, sizeof(RV770_SMC_STATETABLE));
+
+       cypress_populate_smc_voltage_tables(rdev, table);
+
+       switch (rdev->pm.int_thermal_type) {
+        case THERMAL_TYPE_EVERGREEN:
+        case THERMAL_TYPE_EMC2103_WITH_INTERNAL:
+               table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_INTERNAL;
+               break;
+        case THERMAL_TYPE_NONE:
+               table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_NONE;
+               break;
+        default:
+               table->thermalProtectType = PPSMC_THERMAL_PROTECT_TYPE_EXTERNAL;
+               break;
+       }
+
+       if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_HARDWAREDC)
+               table->systemFlags |= PPSMC_SYSTEMFLAG_GPIO_DC;
+
+       if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_REGULATOR_HOT)
+               table->systemFlags |= PPSMC_SYSTEMFLAG_REGULATOR_HOT;
+
+       if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_STEPVDDC)
+               table->systemFlags |= PPSMC_SYSTEMFLAG_STEPVDDC;
+
+       if (pi->mem_gddr5)
+               table->systemFlags |= PPSMC_SYSTEMFLAG_GDDR5;
+
+       ret = cypress_populate_smc_initial_state(rdev, radeon_boot_state, table);
+       if (ret)
+               return ret;
+
+       if (eg_pi->sclk_deep_sleep)
+               WREG32_P(SCLK_PSKIP_CNTL, PSKIP_ON_ALLOW_STOP_HI(32),
+                        ~PSKIP_ON_ALLOW_STOP_HI_MASK);
+
+       ret = btc_populate_smc_acpi_state(rdev, table);
+       if (ret)
+               return ret;
+
+       if (eg_pi->ulv.supported) {
+               ret = btc_populate_ulv_state(rdev, table);
+               if (ret)
+                       eg_pi->ulv.supported = false;
+       }
+
+       table->driverState = table->initialState;
+
+       return rv770_copy_bytes_to_smc(rdev,
+                                      pi->state_table_start,
+                                      (u8 *)table,
+                                      sizeof(RV770_SMC_STATETABLE),
+                                      pi->sram_end);
+}
+
+static void btc_set_at_for_uvd(struct radeon_device *rdev,
+                              struct radeon_ps *radeon_new_state)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       int idx = 0;
+
+       if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2))
+               idx = 1;
+
+       if ((idx == 1) && !eg_pi->smu_uvd_hs) {
+               pi->rlp = 10;
+               pi->rmp = 100;
+               pi->lhp = 100;
+               pi->lmp = 10;
+       } else {
+               pi->rlp = eg_pi->ats[idx].rlp;
+               pi->rmp = eg_pi->ats[idx].rmp;
+               pi->lhp = eg_pi->ats[idx].lhp;
+               pi->lmp = eg_pi->ats[idx].lmp;
+       }
+
+}
+
+void btc_notify_uvd_to_smc(struct radeon_device *rdev,
+                          struct radeon_ps *radeon_new_state)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+       if (r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
+               rv770_write_smc_soft_register(rdev,
+                                             RV770_SMC_SOFT_REGISTER_uvd_enabled, 1);
+               eg_pi->uvd_enabled = true;
+       } else {
+               rv770_write_smc_soft_register(rdev,
+                                             RV770_SMC_SOFT_REGISTER_uvd_enabled, 0);
+               eg_pi->uvd_enabled = false;
+       }
+}
+
+int btc_reset_to_default(struct radeon_device *rdev)
+{
+       if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK)
+               return -EINVAL;
+
+       return 0;
+}
+
+static void btc_stop_smc(struct radeon_device *rdev)
+{
+       int i;
+
+       for (i = 0; i < rdev->usec_timeout; i++) {
+               if (((RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK) >> LB_SYNC_RESET_SEL_SHIFT) != 1)
+                       break;
+               DRM_UDELAY(1);
+       }
+       DRM_UDELAY(100);
+
+       r7xx_stop_smc(rdev);
+}
+
+void btc_read_arb_registers(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct evergreen_arb_registers *arb_registers =
+               &eg_pi->bootup_arb_registers;
+
+       arb_registers->mc_arb_dram_timing = RREG32(MC_ARB_DRAM_TIMING);
+       arb_registers->mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
+       arb_registers->mc_arb_rfsh_rate = RREG32(MC_ARB_RFSH_RATE);
+       arb_registers->mc_arb_burst_time = RREG32(MC_ARB_BURST_TIME);
+}
+
+
+static void btc_set_arb0_registers(struct radeon_device *rdev,
+                                  struct evergreen_arb_registers *arb_registers)
+{
+       u32 val;
+
+       WREG32(MC_ARB_DRAM_TIMING,  arb_registers->mc_arb_dram_timing);
+       WREG32(MC_ARB_DRAM_TIMING2, arb_registers->mc_arb_dram_timing2);
+
+       val = (arb_registers->mc_arb_rfsh_rate & POWERMODE0_MASK) >>
+               POWERMODE0_SHIFT;
+       WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
+
+       val = (arb_registers->mc_arb_burst_time & STATE0_MASK) >>
+               STATE0_SHIFT;
+       WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
+}
+
+static void btc_set_boot_state_timing(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+       if (eg_pi->ulv.supported)
+               btc_set_arb0_registers(rdev, &eg_pi->bootup_arb_registers);
+}
+
+static bool btc_is_state_ulv_compatible(struct radeon_device *rdev,
+                                       struct radeon_ps *radeon_state)
+{
+       struct rv7xx_ps *state = rv770_get_ps(radeon_state);
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
+
+       if (state->low.mclk != ulv_pl->mclk)
+               return false;
+
+       if (state->low.vddci != ulv_pl->vddci)
+               return false;
+
+       /* XXX check minclocks, etc. */
+
+       return true;
+}
+
+
+static int btc_set_ulv_dram_timing(struct radeon_device *rdev)
+{
+       u32 val;
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct rv7xx_pl *ulv_pl = eg_pi->ulv.pl;
+
+       radeon_atom_set_engine_dram_timings(rdev,
+                                           ulv_pl->sclk,
+                                           ulv_pl->mclk);
+
+       val = rv770_calculate_memory_refresh_rate(rdev, ulv_pl->sclk);
+       WREG32_P(MC_ARB_RFSH_RATE, POWERMODE0(val), ~POWERMODE0_MASK);
+
+       val = cypress_calculate_burst_time(rdev, ulv_pl->sclk, ulv_pl->mclk);
+       WREG32_P(MC_ARB_BURST_TIME, STATE0(val), ~STATE0_MASK);
+
+       return 0;
+}
+
+static int btc_enable_ulv(struct radeon_device *rdev)
+{
+       if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableULV) != PPSMC_Result_OK)
+               return -EINVAL;
+
+       return 0;
+}
+
+static int btc_set_power_state_conditionally_enable_ulv(struct radeon_device *rdev,
+                                                       struct radeon_ps *radeon_new_state)
+{
+       int ret = 0;
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+       if (eg_pi->ulv.supported) {
+               if (btc_is_state_ulv_compatible(rdev, radeon_new_state)) {
+                       // Set ARB[0] to reflect the DRAM timing needed for ULV.
+                       ret = btc_set_ulv_dram_timing(rdev);
+                       if (ret == 0)
+                               ret = btc_enable_ulv(rdev);
+               }
+       }
+
+       return ret;
+}
+
+static bool btc_check_s0_mc_reg_index(u16 in_reg, u16 *out_reg)
+{
+       bool result = true;
+
+       switch (in_reg) {
+       case MC_SEQ_RAS_TIMING >> 2:
+               *out_reg = MC_SEQ_RAS_TIMING_LP >> 2;
+               break;
+        case MC_SEQ_CAS_TIMING >> 2:
+               *out_reg = MC_SEQ_CAS_TIMING_LP >> 2;
+               break;
+        case MC_SEQ_MISC_TIMING >> 2:
+               *out_reg = MC_SEQ_MISC_TIMING_LP >> 2;
+               break;
+        case MC_SEQ_MISC_TIMING2 >> 2:
+               *out_reg = MC_SEQ_MISC_TIMING2_LP >> 2;
+               break;
+        case MC_SEQ_RD_CTL_D0 >> 2:
+               *out_reg = MC_SEQ_RD_CTL_D0_LP >> 2;
+               break;
+        case MC_SEQ_RD_CTL_D1 >> 2:
+               *out_reg = MC_SEQ_RD_CTL_D1_LP >> 2;
+               break;
+        case MC_SEQ_WR_CTL_D0 >> 2:
+               *out_reg = MC_SEQ_WR_CTL_D0_LP >> 2;
+               break;
+        case MC_SEQ_WR_CTL_D1 >> 2:
+               *out_reg = MC_SEQ_WR_CTL_D1_LP >> 2;
+               break;
+        case MC_PMG_CMD_EMRS >> 2:
+               *out_reg = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+               break;
+        case MC_PMG_CMD_MRS >> 2:
+               *out_reg = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+               break;
+        case MC_PMG_CMD_MRS1 >> 2:
+               *out_reg = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+               break;
+        default:
+               result = false;
+               break;
+       }
+
+       return result;
+}
+
+static void btc_set_valid_flag(struct evergreen_mc_reg_table *table)
+{
+       u8 i, j;
+
+       for (i = 0; i < table->last; i++) {
+               for (j = 1; j < table->num_entries; j++) {
+                       if (table->mc_reg_table_entry[j-1].mc_data[i] !=
+                           table->mc_reg_table_entry[j].mc_data[i]) {
+                               table->valid_flag |= (1 << i);
+                               break;
+                       }
+               }
+       }
+}
+
+static int btc_set_mc_special_registers(struct radeon_device *rdev,
+                                       struct evergreen_mc_reg_table *table)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       u8 i, j, k;
+       u32 tmp;
+
+       for (i = 0, j = table->last; i < table->last; i++) {
+               switch (table->mc_reg_address[i].s1) {
+               case MC_SEQ_MISC1 >> 2:
+                       tmp = RREG32(MC_PMG_CMD_EMRS);
+                       table->mc_reg_address[j].s1 = MC_PMG_CMD_EMRS >> 2;
+                       table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_EMRS_LP >> 2;
+                       for (k = 0; k < table->num_entries; k++) {
+                               table->mc_reg_table_entry[k].mc_data[j] =
+                                       ((tmp & 0xffff0000)) |
+                                       ((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
+                       }
+                       j++;
+
+                       if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
+                               return -EINVAL;
+
+                       tmp = RREG32(MC_PMG_CMD_MRS);
+                       table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS >> 2;
+                       table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS_LP >> 2;
+                       for (k = 0; k < table->num_entries; k++) {
+                               table->mc_reg_table_entry[k].mc_data[j] =
+                                       (tmp & 0xffff0000) |
+                                       (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+                               if (!pi->mem_gddr5)
+                                       table->mc_reg_table_entry[k].mc_data[j] |= 0x100;
+                       }
+                       j++;
+
+                       if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
+                               return -EINVAL;
+                       break;
+               case MC_SEQ_RESERVE_M >> 2:
+                       tmp = RREG32(MC_PMG_CMD_MRS1);
+                       table->mc_reg_address[j].s1 = MC_PMG_CMD_MRS1 >> 2;
+                       table->mc_reg_address[j].s0 = MC_SEQ_PMG_CMD_MRS1_LP >> 2;
+                       for (k = 0; k < table->num_entries; k++) {
+                               table->mc_reg_table_entry[k].mc_data[j] =
+                                       (tmp & 0xffff0000) |
+                                       (table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
+                       }
+                       j++;
+
+                       if (j > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
+                               return -EINVAL;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       table->last = j;
+
+       return 0;
+}
+
+static void btc_set_s0_mc_reg_index(struct evergreen_mc_reg_table *table)
+{
+       u32 i;
+       u16 address;
+
+       for (i = 0; i < table->last; i++) {
+               table->mc_reg_address[i].s0 =
+                       btc_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
+                       address : table->mc_reg_address[i].s1;
+       }
+}
+
+static int btc_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
+                                      struct evergreen_mc_reg_table *eg_table)
+{
+       u8 i, j;
+
+       if (table->last > SMC_EVERGREEN_MC_REGISTER_ARRAY_SIZE)
+               return -EINVAL;
+
+       if (table->num_entries > MAX_AC_TIMING_ENTRIES)
+               return -EINVAL;
+
+       for (i = 0; i < table->last; i++)
+               eg_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
+       eg_table->last = table->last;
+
+       for (i = 0; i < table->num_entries; i++) {
+               eg_table->mc_reg_table_entry[i].mclk_max =
+                       table->mc_reg_table_entry[i].mclk_max;
+               for(j = 0; j < table->last; j++)
+                       eg_table->mc_reg_table_entry[i].mc_data[j] =
+                               table->mc_reg_table_entry[i].mc_data[j];
+       }
+       eg_table->num_entries = table->num_entries;
+
+       return 0;
+}
+
+static int btc_initialize_mc_reg_table(struct radeon_device *rdev)
+{
+       int ret;
+       struct atom_mc_reg_table *table;
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct evergreen_mc_reg_table *eg_table = &eg_pi->mc_reg_table;
+       u8 module_index = rv770_get_memory_module_index(rdev);
+
+       table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL);
+       if (!table)
+               return -ENOMEM;
+
+       /* Program additional LP registers that are no longer programmed by VBIOS */
+       WREG32(MC_SEQ_RAS_TIMING_LP, RREG32(MC_SEQ_RAS_TIMING));
+       WREG32(MC_SEQ_CAS_TIMING_LP, RREG32(MC_SEQ_CAS_TIMING));
+       WREG32(MC_SEQ_MISC_TIMING_LP, RREG32(MC_SEQ_MISC_TIMING));
+       WREG32(MC_SEQ_MISC_TIMING2_LP, RREG32(MC_SEQ_MISC_TIMING2));
+       WREG32(MC_SEQ_RD_CTL_D0_LP, RREG32(MC_SEQ_RD_CTL_D0));
+       WREG32(MC_SEQ_RD_CTL_D1_LP, RREG32(MC_SEQ_RD_CTL_D1));
+       WREG32(MC_SEQ_WR_CTL_D0_LP, RREG32(MC_SEQ_WR_CTL_D0));
+       WREG32(MC_SEQ_WR_CTL_D1_LP, RREG32(MC_SEQ_WR_CTL_D1));
+       WREG32(MC_SEQ_PMG_CMD_EMRS_LP, RREG32(MC_PMG_CMD_EMRS));
+       WREG32(MC_SEQ_PMG_CMD_MRS_LP, RREG32(MC_PMG_CMD_MRS));
+       WREG32(MC_SEQ_PMG_CMD_MRS1_LP, RREG32(MC_PMG_CMD_MRS1));
+
+       ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
+
+       if (ret)
+               goto init_mc_done;
+
+       ret = btc_copy_vbios_mc_reg_table(table, eg_table);
+
+       if (ret)
+               goto init_mc_done;
+
+       btc_set_s0_mc_reg_index(eg_table);
+       ret = btc_set_mc_special_registers(rdev, eg_table);
+
+       if (ret)
+               goto init_mc_done;
+
+       btc_set_valid_flag(eg_table);
+
+init_mc_done:
+       kfree(table);
+
+       return ret;
+}
+
+static void btc_init_stutter_mode(struct radeon_device *rdev)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       u32 tmp;
+
+       if (pi->mclk_stutter_mode_threshold) {
+               if (pi->mem_gddr5) {
+                       tmp = RREG32(MC_PMG_AUTO_CFG);
+                       if ((0x200 & tmp) == 0) {
+                               tmp = (tmp & 0xfffffc0b) | 0x204;
+                               WREG32(MC_PMG_AUTO_CFG, tmp);
+                       }
+               }
+       }
+}
+
+bool btc_dpm_vblank_too_short(struct radeon_device *rdev)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       u32 vblank_time = r600_dpm_get_vblank_time(rdev);
+       u32 switch_limit = pi->mem_gddr5 ? 450 : 100;
+
+       if (vblank_time < switch_limit)
+               return true;
+       else
+               return false;
+
+}
+
+static void btc_apply_state_adjust_rules(struct radeon_device *rdev,
+                                        struct radeon_ps *rps)
+{
+       struct rv7xx_ps *ps = rv770_get_ps(rps);
+       struct radeon_clock_and_voltage_limits *max_limits;
+       bool disable_mclk_switching;
+       u32 mclk, sclk;
+       u16 vddc, vddci;
+
+       if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
+           btc_dpm_vblank_too_short(rdev))
+               disable_mclk_switching = true;
+       else
+               disable_mclk_switching = false;
+
+       if (rdev->pm.dpm.ac_power)
+               max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac;
+       else
+               max_limits = &rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc;
+
+       if (rdev->pm.dpm.ac_power == false) {
+               if (ps->high.mclk > max_limits->mclk)
+                       ps->high.mclk = max_limits->mclk;
+               if (ps->high.sclk > max_limits->sclk)
+                       ps->high.sclk = max_limits->sclk;
+               if (ps->high.vddc > max_limits->vddc)
+                       ps->high.vddc = max_limits->vddc;
+               if (ps->high.vddci > max_limits->vddci)
+                       ps->high.vddci = max_limits->vddci;
+
+               if (ps->medium.mclk > max_limits->mclk)
+                       ps->medium.mclk = max_limits->mclk;
+               if (ps->medium.sclk > max_limits->sclk)
+                       ps->medium.sclk = max_limits->sclk;
+               if (ps->medium.vddc > max_limits->vddc)
+                       ps->medium.vddc = max_limits->vddc;
+               if (ps->medium.vddci > max_limits->vddci)
+                       ps->medium.vddci = max_limits->vddci;
+
+               if (ps->low.mclk > max_limits->mclk)
+                       ps->low.mclk = max_limits->mclk;
+               if (ps->low.sclk > max_limits->sclk)
+                       ps->low.sclk = max_limits->sclk;
+               if (ps->low.vddc > max_limits->vddc)
+                       ps->low.vddc = max_limits->vddc;
+               if (ps->low.vddci > max_limits->vddci)
+                       ps->low.vddci = max_limits->vddci;
+       }
+
+       /* XXX validate the min clocks required for display */
+
+       if (disable_mclk_switching) {
+               sclk = ps->low.sclk;
+               mclk = ps->high.mclk;
+               vddc = ps->low.vddc;
+               vddci = ps->high.vddci;
+       } else {
+               sclk = ps->low.sclk;
+               mclk = ps->low.mclk;
+               vddc = ps->low.vddc;
+               vddci = ps->low.vddci;
+       }
+
+       /* adjusted low state */
+       ps->low.sclk = sclk;
+       ps->low.mclk = mclk;
+       ps->low.vddc = vddc;
+       ps->low.vddci = vddci;
+
+       btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
+                                 &ps->low.sclk, &ps->low.mclk);
+
+       /* adjusted medium, high states */
+       if (ps->medium.sclk < ps->low.sclk)
+               ps->medium.sclk = ps->low.sclk;
+       if (ps->medium.vddc < ps->low.vddc)
+               ps->medium.vddc = ps->low.vddc;
+       if (ps->high.sclk < ps->medium.sclk)
+               ps->high.sclk = ps->medium.sclk;
+       if (ps->high.vddc < ps->medium.vddc)
+               ps->high.vddc = ps->medium.vddc;
+
+       if (disable_mclk_switching) {
+               mclk = ps->low.mclk;
+               if (mclk < ps->medium.mclk)
+                       mclk = ps->medium.mclk;
+               if (mclk < ps->high.mclk)
+                       mclk = ps->high.mclk;
+               ps->low.mclk = mclk;
+               ps->low.vddci = vddci;
+               ps->medium.mclk = mclk;
+               ps->medium.vddci = vddci;
+               ps->high.mclk = mclk;
+               ps->high.vddci = vddci;
+       } else {
+               if (ps->medium.mclk < ps->low.mclk)
+                       ps->medium.mclk = ps->low.mclk;
+               if (ps->medium.vddci < ps->low.vddci)
+                       ps->medium.vddci = ps->low.vddci;
+               if (ps->high.mclk < ps->medium.mclk)
+                       ps->high.mclk = ps->medium.mclk;
+               if (ps->high.vddci < ps->medium.vddci)
+                       ps->high.vddci = ps->medium.vddci;
+       }
+
+       btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
+                                 &ps->medium.sclk, &ps->medium.mclk);
+       btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
+                                 &ps->high.sclk, &ps->high.mclk);
+
+       btc_adjust_clock_combinations(rdev, max_limits, &ps->low);
+       btc_adjust_clock_combinations(rdev, max_limits, &ps->medium);
+       btc_adjust_clock_combinations(rdev, max_limits, &ps->high);
+
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+                                          ps->low.sclk, max_limits->vddc, &ps->low.vddc);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+                                          ps->low.mclk, max_limits->vddci, &ps->low.vddci);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+                                          ps->low.mclk, max_limits->vddc, &ps->low.vddc);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+                                          rdev->clock.current_dispclk, max_limits->vddc, &ps->low.vddc);
+
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+                                          ps->medium.sclk, max_limits->vddc, &ps->medium.vddc);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+                                          ps->medium.mclk, max_limits->vddci, &ps->medium.vddci);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+                                          ps->medium.mclk, max_limits->vddc, &ps->medium.vddc);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+                                          rdev->clock.current_dispclk, max_limits->vddc, &ps->medium.vddc);
+
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
+                                          ps->high.sclk, max_limits->vddc, &ps->high.vddc);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
+                                          ps->high.mclk, max_limits->vddci, &ps->high.vddci);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
+                                          ps->high.mclk, max_limits->vddc, &ps->high.vddc);
+       btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk,
+                                          rdev->clock.current_dispclk, max_limits->vddc, &ps->high.vddc);
+
+       btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
+                                     &ps->low.vddc, &ps->low.vddci);
+       btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
+                                     &ps->medium.vddc, &ps->medium.vddci);
+       btc_apply_voltage_delta_rules(rdev, max_limits->vddc, max_limits->vddci,
+                                     &ps->high.vddc, &ps->high.vddci);
+
+       if ((ps->high.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
+           (ps->medium.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc) &&
+           (ps->low.vddc <= rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc))
+               ps->dc_compatible = true;
+       else
+               ps->dc_compatible = false;
+
+       if (ps->low.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
+               ps->low.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
+       if (ps->medium.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
+               ps->medium.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
+       if (ps->high.vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
+               ps->high.flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
+}
+
+static void btc_update_current_ps(struct radeon_device *rdev,
+                                 struct radeon_ps *rps)
+{
+       struct rv7xx_ps *new_ps = rv770_get_ps(rps);
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+       eg_pi->current_rps = *rps;
+       eg_pi->current_ps = *new_ps;
+       eg_pi->current_rps.ps_priv = &eg_pi->current_ps;
+}
+
+static void btc_update_requested_ps(struct radeon_device *rdev,
+                                   struct radeon_ps *rps)
+{
+       struct rv7xx_ps *new_ps = rv770_get_ps(rps);
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+       eg_pi->requested_rps = *rps;
+       eg_pi->requested_ps = *new_ps;
+       eg_pi->requested_rps.ps_priv = &eg_pi->requested_ps;
+}
+
+void btc_dpm_reset_asic(struct radeon_device *rdev)
+{
+       rv770_restrict_performance_levels_before_switch(rdev);
+       btc_disable_ulv(rdev);
+       btc_set_boot_state_timing(rdev);
+       rv770_set_boot_state(rdev);
+}
+
+int btc_dpm_pre_set_power_state(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct radeon_ps requested_ps = *rdev->pm.dpm.requested_ps;
+       struct radeon_ps *new_ps = &requested_ps;
+
+       btc_update_requested_ps(rdev, new_ps);
+
+       btc_apply_state_adjust_rules(rdev, &eg_pi->requested_rps);
+
+       return 0;
+}
+
+int btc_dpm_set_power_state(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct radeon_ps *new_ps = &eg_pi->requested_rps;
+       struct radeon_ps *old_ps = &eg_pi->current_rps;
+       int ret;
+
+       ret = btc_disable_ulv(rdev);
+       btc_set_boot_state_timing(rdev);
+       ret = rv770_restrict_performance_levels_before_switch(rdev);
+       if (ret) {
+               DRM_ERROR("rv770_restrict_performance_levels_before_switch failed\n");
+               return ret;
+       }
+       if (eg_pi->pcie_performance_request)
+               cypress_notify_link_speed_change_before_state_change(rdev, new_ps, old_ps);
+
+       rv770_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
+       ret = rv770_halt_smc(rdev);
+       if (ret) {
+               DRM_ERROR("rv770_halt_smc failed\n");
+               return ret;
+       }
+       btc_set_at_for_uvd(rdev, new_ps);
+       if (eg_pi->smu_uvd_hs)
+               btc_notify_uvd_to_smc(rdev, new_ps);
+       ret = cypress_upload_sw_state(rdev, new_ps);
+       if (ret) {
+               DRM_ERROR("cypress_upload_sw_state failed\n");
+               return ret;
+       }
+       if (eg_pi->dynamic_ac_timing) {
+               ret = cypress_upload_mc_reg_table(rdev, new_ps);
+               if (ret) {
+                       DRM_ERROR("cypress_upload_mc_reg_table failed\n");
+                       return ret;
+               }
+       }
+
+       cypress_program_memory_timing_parameters(rdev, new_ps);
+
+       ret = rv770_resume_smc(rdev);
+       if (ret) {
+               DRM_ERROR("rv770_resume_smc failed\n");
+               return ret;
+       }
+       ret = rv770_set_sw_state(rdev);
+       if (ret) {
+               DRM_ERROR("rv770_set_sw_state failed\n");
+               return ret;
+       }
+       rv770_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
+
+       if (eg_pi->pcie_performance_request)
+               cypress_notify_link_speed_change_after_state_change(rdev, new_ps, old_ps);
+
+       ret = btc_set_power_state_conditionally_enable_ulv(rdev, new_ps);
+       if (ret) {
+               DRM_ERROR("btc_set_power_state_conditionally_enable_ulv failed\n");
+               return ret;
+       }
+
+       ret = rv770_dpm_force_performance_level(rdev, RADEON_DPM_FORCED_LEVEL_AUTO);
+       if (ret) {
+               DRM_ERROR("rv770_dpm_force_performance_level failed\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+void btc_dpm_post_set_power_state(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct radeon_ps *new_ps = &eg_pi->requested_rps;
+
+       btc_update_current_ps(rdev, new_ps);
+}
+
+int btc_dpm_enable(struct radeon_device *rdev)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps;
+       int ret;
+
+       if (pi->gfx_clock_gating)
+               btc_cg_clock_gating_default(rdev);
+
+       if (btc_dpm_enabled(rdev))
+               return -EINVAL;
+
+       if (pi->mg_clock_gating)
+               btc_mg_clock_gating_default(rdev);
+
+       if (eg_pi->ls_clock_gating)
+               btc_ls_clock_gating_default(rdev);
+
+       if (pi->voltage_control) {
+               rv770_enable_voltage_control(rdev, true);
+               ret = cypress_construct_voltage_tables(rdev);
+               if (ret) {
+                       DRM_ERROR("cypress_construct_voltage_tables failed\n");
+                       return ret;
+               }
+       }
+
+       if (pi->mvdd_control) {
+               ret = cypress_get_mvdd_configuration(rdev);
+               if (ret) {
+                       DRM_ERROR("cypress_get_mvdd_configuration failed\n");
+                       return ret;
+               }
+       }
+
+       if (eg_pi->dynamic_ac_timing) {
+               ret = btc_initialize_mc_reg_table(rdev);
+               if (ret)
+                       eg_pi->dynamic_ac_timing = false;
+       }
+
+       if (rdev->pm.dpm.platform_caps & ATOM_PP_PLATFORM_CAP_BACKBIAS)
+               rv770_enable_backbias(rdev, true);
+
+       if (pi->dynamic_ss)
+               cypress_enable_spread_spectrum(rdev, true);
+
+       if (pi->thermal_protection)
+               rv770_enable_thermal_protection(rdev, true);
+
+       rv770_setup_bsp(rdev);
+       rv770_program_git(rdev);
+       rv770_program_tp(rdev);
+       rv770_program_tpp(rdev);
+       rv770_program_sstp(rdev);
+       rv770_program_engine_speed_parameters(rdev);
+       cypress_enable_display_gap(rdev);
+       rv770_program_vc(rdev);
+
+       if (pi->dynamic_pcie_gen2)
+               btc_enable_dynamic_pcie_gen2(rdev, true);
+
+       ret = rv770_upload_firmware(rdev);
+       if (ret) {
+               DRM_ERROR("rv770_upload_firmware failed\n");
+               return ret;
+       }
+       ret = cypress_get_table_locations(rdev);
+       if (ret) {
+               DRM_ERROR("cypress_get_table_locations failed\n");
+               return ret;
+       }
+       ret = btc_init_smc_table(rdev, boot_ps);
+       if (ret)
+               return ret;
+
+       if (eg_pi->dynamic_ac_timing) {
+               ret = cypress_populate_mc_reg_table(rdev, boot_ps);
+               if (ret) {
+                       DRM_ERROR("cypress_populate_mc_reg_table failed\n");
+                       return ret;
+               }
+       }
+
+       cypress_program_response_times(rdev);
+       r7xx_start_smc(rdev);
+       ret = cypress_notify_smc_display_change(rdev, false);
+       if (ret) {
+               DRM_ERROR("cypress_notify_smc_display_change failed\n");
+               return ret;
+       }
+       cypress_enable_sclk_control(rdev, true);
+
+       if (eg_pi->memory_transition)
+               cypress_enable_mclk_control(rdev, true);
+
+       cypress_start_dpm(rdev);
+
+       if (pi->gfx_clock_gating)
+               btc_cg_clock_gating_enable(rdev, true);
+
+       if (pi->mg_clock_gating)
+               btc_mg_clock_gating_enable(rdev, true);
+
+       if (eg_pi->ls_clock_gating)
+               btc_ls_clock_gating_enable(rdev, true);
+
+       if (rdev->irq.installed &&
+           r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+               PPSMC_Result result;
+
+               ret = rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, R600_TEMP_RANGE_MAX);
+               if (ret)
+                       return ret;
+               rdev->irq.dpm_thermal = true;
+               radeon_irq_set(rdev);
+               result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableThermalInterrupt);
+
+               if (result != PPSMC_Result_OK)
+                       DRM_DEBUG_KMS("Could not enable thermal interrupts.\n");
+       }
+
+       rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true);
+
+       btc_init_stutter_mode(rdev);
+
+       btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+
+       return 0;
+};
+
+void btc_dpm_disable(struct radeon_device *rdev)
+{
+       struct rv7xx_power_info *pi = rv770_get_pi(rdev);
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+       if (!btc_dpm_enabled(rdev))
+               return;
+
+       rv770_clear_vc(rdev);
+
+       if (pi->thermal_protection)
+               rv770_enable_thermal_protection(rdev, false);
+
+       if (pi->dynamic_pcie_gen2)
+               btc_enable_dynamic_pcie_gen2(rdev, false);
+
+       if (rdev->irq.installed &&
+           r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
+               rdev->irq.dpm_thermal = false;
+               radeon_irq_set(rdev);
+       }
+
+       if (pi->gfx_clock_gating)
+               btc_cg_clock_gating_enable(rdev, false);
+
+       if (pi->mg_clock_gating)
+               btc_mg_clock_gating_enable(rdev, false);
+
+       if (eg_pi->ls_clock_gating)
+               btc_ls_clock_gating_enable(rdev, false);
+
+       rv770_stop_dpm(rdev);
+       btc_reset_to_default(rdev);
+       btc_stop_smc(rdev);
+       cypress_enable_spread_spectrum(rdev, false);
+
+       btc_update_current_ps(rdev, rdev->pm.dpm.boot_ps);
+}
+
+void btc_dpm_setup_asic(struct radeon_device *rdev)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+
+       rv770_get_memory_type(rdev);
+       rv740_read_clock_registers(rdev);
+       btc_read_arb_registers(rdev);
+       rv770_read_voltage_smio_registers(rdev);
+
+       if (eg_pi->pcie_performance_request)
+               cypress_advertise_gen2_capability(rdev);
+
+       rv770_get_pcie_gen2_status(rdev);
+       rv770_enable_acpi_pm(rdev);
+}
+
+int btc_dpm_init(struct radeon_device *rdev)
+{
+       struct rv7xx_power_info *pi;
+       struct evergreen_power_info *eg_pi;
+       struct atom_clock_dividers dividers;
+       int ret;
+
+       eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL);
+       if (eg_pi == NULL)
+               return -ENOMEM;
+       rdev->pm.dpm.priv = eg_pi;
+       pi = &eg_pi->rv7xx;
+
+       rv770_get_max_vddc(rdev);
+
+       eg_pi->ulv.supported = false;
+       pi->acpi_vddc = 0;
+       eg_pi->acpi_vddci = 0;
+       pi->min_vddc_in_table = 0;
+       pi->max_vddc_in_table = 0;
+
+       ret = rv7xx_parse_power_table(rdev);
+       if (ret)
+               return ret;
+       ret = r600_parse_extended_power_table(rdev);
+       if (ret)
+               return ret;
+
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries =
+               kzalloc(4 * sizeof(struct radeon_clock_voltage_dependency_entry), GFP_KERNEL);
+       if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) {
+               r600_free_extended_power_table(rdev);
+               return -ENOMEM;
+       }
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.count = 4;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].clk = 0;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[0].v = 0;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].clk = 36000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[1].v = 800;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].clk = 54000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[2].v = 800;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].clk = 72000;
+       rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries[3].v = 800;
+
+       if (rdev->pm.dpm.voltage_response_time == 0)
+               rdev->pm.dpm.voltage_response_time = R600_VOLTAGERESPONSETIME_DFLT;
+       if (rdev->pm.dpm.backbias_response_time == 0)
+               rdev->pm.dpm.backbias_response_time = R600_BACKBIASRESPONSETIME_DFLT;
+
+       ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
+                                            0, false, &dividers);
+       if (ret)
+               pi->ref_div = dividers.ref_div + 1;
+       else
+               pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
+
+       pi->mclk_strobe_mode_threshold = 40000;
+       pi->mclk_edc_enable_threshold = 40000;
+       eg_pi->mclk_edc_wr_enable_threshold = 40000;
+
+       pi->rlp = RV770_RLP_DFLT;
+       pi->rmp = RV770_RMP_DFLT;
+       pi->lhp = RV770_LHP_DFLT;
+       pi->lmp = RV770_LMP_DFLT;
+
+       eg_pi->ats[0].rlp = RV770_RLP_DFLT;
+       eg_pi->ats[0].rmp = RV770_RMP_DFLT;
+       eg_pi->ats[0].lhp = RV770_LHP_DFLT;
+       eg_pi->ats[0].lmp = RV770_LMP_DFLT;
+
+       eg_pi->ats[1].rlp = BTC_RLP_UVD_DFLT;
+       eg_pi->ats[1].rmp = BTC_RMP_UVD_DFLT;
+       eg_pi->ats[1].lhp = BTC_LHP_UVD_DFLT;
+       eg_pi->ats[1].lmp = BTC_LMP_UVD_DFLT;
+
+       eg_pi->smu_uvd_hs = true;
+
+       pi->voltage_control =
+               radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC, 0);
+
+       pi->mvdd_control =
+               radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC, 0);
+
+       eg_pi->vddci_control =
+               radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI, 0);
+
+       rv770_get_engine_memory_ss(rdev);
+
+       pi->asi = RV770_ASI_DFLT;
+       pi->pasi = CYPRESS_HASI_DFLT;
+       pi->vrc = CYPRESS_VRC_DFLT;
+
+       pi->power_gating = false;
+
+       pi->gfx_clock_gating = true;
+
+       pi->mg_clock_gating = true;
+       pi->mgcgtssm = true;
+       eg_pi->ls_clock_gating = false;
+       eg_pi->sclk_deep_sleep = false;
+
+       pi->dynamic_pcie_gen2 = true;
+
+       if (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE)
+               pi->thermal_protection = true;
+       else
+               pi->thermal_protection = false;
+
+       pi->display_gap = true;
+
+       if (rdev->flags & RADEON_IS_MOBILITY)
+               pi->dcodt = true;
+       else
+               pi->dcodt = false;
+
+       pi->ulps = true;
+
+       eg_pi->dynamic_ac_timing = true;
+       eg_pi->abm = true;
+       eg_pi->mcls = true;
+       eg_pi->light_sleep = true;
+       eg_pi->memory_transition = true;
+#if defined(CONFIG_ACPI)
+       eg_pi->pcie_performance_request =
+               radeon_acpi_is_pcie_performance_request_supported(rdev);
+#else
+       eg_pi->pcie_performance_request = false;
+#endif
+
+       if (rdev->family == CHIP_BARTS)
+               eg_pi->dll_default_on = true;
+       else
+               eg_pi->dll_default_on = false;
+
+       eg_pi->sclk_deep_sleep = false;
+       if (ASIC_IS_LOMBOK(rdev))
+               pi->mclk_stutter_mode_threshold = 30000;
+       else
+               pi->mclk_stutter_mode_threshold = 0;
+
+       pi->sram_end = SMC_RAM_END;
+
+       rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 4;
+       rdev->pm.dpm.dyn_state.vddc_vddci_delta = 200;
+       rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2 = 900;
+       rdev->pm.dpm.dyn_state.valid_sclk_values.count = ARRAY_SIZE(btc_valid_sclk);
+       rdev->pm.dpm.dyn_state.valid_sclk_values.values = btc_valid_sclk;
+       rdev->pm.dpm.dyn_state.valid_mclk_values.count = 0;
+       rdev->pm.dpm.dyn_state.valid_mclk_values.values = NULL;
+
+       if (rdev->family == CHIP_TURKS)
+               rdev->pm.dpm.dyn_state.sclk_mclk_delta = 15000;
+       else
+               rdev->pm.dpm.dyn_state.sclk_mclk_delta = 10000;
+
+       return 0;
+}
+
+void btc_dpm_fini(struct radeon_device *rdev)
+{
+       int i;
+
+       for (i = 0; i < rdev->pm.dpm.num_ps; i++) {
+               kfree(rdev->pm.dpm.ps[i].ps_priv);
+       }
+       kfree(rdev->pm.dpm.ps);
+       kfree(rdev->pm.dpm.priv);
+       kfree(rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries);
+       r600_free_extended_power_table(rdev);
+}
+
+u32 btc_dpm_get_sclk(struct radeon_device *rdev, bool low)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
+
+       if (low)
+               return requested_state->low.sclk;
+       else
+               return requested_state->high.sclk;
+}
+
+u32 btc_dpm_get_mclk(struct radeon_device *rdev, bool low)
+{
+       struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
+       struct rv7xx_ps *requested_state = rv770_get_ps(&eg_pi->requested_rps);
+
+       if (low)
+               return requested_state->low.mclk;
+       else
+               return requested_state->high.mclk;
+}
diff --git a/sys/dev/drm/radeon/btc_dpm.h b/sys/dev/drm/radeon/btc_dpm.h
new file mode 100644 (file)
index 0000000..1a15e0e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2011 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ */
+#ifndef __BTC_DPM_H__
+#define __BTC_DPM_H__
+
+#define BTC_RLP_UVD_DFLT                              20
+#define BTC_RMP_UVD_DFLT                              50
+#define BTC_LHP_UVD_DFLT                              50
+#define BTC_LMP_UVD_DFLT                              20
+#define BARTS_MGCGCGTSSMCTRL_DFLT                     0x81944000
+#define TURKS_MGCGCGTSSMCTRL_DFLT                     0x6e944000
+#define CAICOS_MGCGCGTSSMCTRL_DFLT                    0x46944040
+#define BTC_CGULVPARAMETER_DFLT                       0x00040035
+#define BTC_CGULVCONTROL_DFLT                         0x00001450
+
+extern u32 btc_valid_sclk[40];
+
+void btc_read_arb_registers(struct radeon_device *rdev);
+void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
+                                 const u32 *sequence, u32 count);
+void btc_skip_blacklist_clocks(struct radeon_device *rdev,
+                              const u32 max_sclk, const u32 max_mclk,
+                              u32 *sclk, u32 *mclk);
+void btc_adjust_clock_combinations(struct radeon_device *rdev,
+                                  const struct radeon_clock_and_voltage_limits *max_limits,
+                                  struct rv7xx_pl *pl);
+void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
+                                       u32 clock, u16 max_voltage, u16 *voltage);
+void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
+                                  u16 max_vddc, u16 max_vddci,
+                                  u16 *vddc, u16 *vddci);
+bool btc_dpm_enabled(struct radeon_device *rdev);
+int btc_reset_to_default(struct radeon_device *rdev);
+void btc_notify_uvd_to_smc(struct radeon_device *rdev,
+                          struct radeon_ps *radeon_new_state);
+
+#endif
diff --git a/sys/dev/drm/radeon/btcd.h b/sys/dev/drm/radeon/btcd.h
new file mode 100644 (file)
index 0000000..29e32de
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2010 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+#ifndef _BTCD_H_
+#define _BTCD_H_
+
+/* pm registers */
+
+#define GENERAL_PWRMGT                                  0x63c
+#       define GLOBAL_PWRMGT_EN                         (1 << 0)
+#       define STATIC_PM_EN                             (1 << 1)
+#       define THERMAL_PROTECTION_DIS                   (1 << 2)
+#       define THERMAL_PROTECTION_TYPE                  (1 << 3)
+#       define ENABLE_GEN2PCIE                          (1 << 4)
+#       define ENABLE_GEN2XSP                           (1 << 5)
+#       define SW_SMIO_INDEX(x)                         ((x) << 6)
+#       define SW_SMIO_INDEX_MASK                       (3 << 6)
+#       define SW_SMIO_INDEX_SHIFT                      6
+#       define LOW_VOLT_D2_ACPI                         (1 << 8)
+#       define LOW_VOLT_D3_ACPI                         (1 << 9)
+#       define VOLT_PWRMGT_EN                           (1 << 10)
+#       define BACKBIAS_PAD_EN                          (1 << 18)
+#       define BACKBIAS_VALUE                           (1 << 19)
+#       define DYN_SPREAD_SPECTRUM_EN                   (1 << 23)
+#       define AC_DC_SW                                 (1 << 24)
+
+#define        CG_BIF_REQ_AND_RSP                              0x7f4
+#define                CG_CLIENT_REQ(x)                        ((x) << 0)
+#define                CG_CLIENT_REQ_MASK                      (0xff << 0)
+#define                CG_CLIENT_REQ_SHIFT                     0
+#define                CG_CLIENT_RESP(x)                       ((x) << 8)
+#define                CG_CLIENT_RESP_MASK                     (0xff << 8)
+#define                CG_CLIENT_RESP_SHIFT                    8
+#define                CLIENT_CG_REQ(x)                        ((x) << 16)
+#define                CLIENT_CG_REQ_MASK                      (0xff << 16)
+#define                CLIENT_CG_REQ_SHIFT                     16
+#define                CLIENT_CG_RESP(x)                       ((x) << 24)
+#define                CLIENT_CG_RESP_MASK                     (0xff << 24)
+#define                CLIENT_CG_RESP_SHIFT                    24
+
+#define        SCLK_PSKIP_CNTL                                 0x8c0
+#define                PSKIP_ON_ALLOW_STOP_HI(x)               ((x) << 16)
+#define                PSKIP_ON_ALLOW_STOP_HI_MASK             (0xff << 16)
+#define                PSKIP_ON_ALLOW_STOP_HI_SHIFT            16
+
+#define        CG_ULV_CONTROL                                  0x8c8
+#define        CG_ULV_PARAMETER                                0x8cc
+
+#define        MC_ARB_DRAM_TIMING                              0x2774
+#define        MC_ARB_DRAM_TIMING2                             0x2778
+
+#define        MC_ARB_RFSH_RATE                                0x27b0
+#define                POWERMODE0(x)                           ((x) << 0)
+#define                POWERMODE0_MASK                         (0xff << 0)
+#define                POWERMODE0_SHIFT                        0
+#define                POWERMODE1(x)                           ((x) << 8)
+#define                POWERMODE1_MASK                         (0xff << 8)
+#define                POWERMODE1_SHIFT                        8
+#define                POWERMODE2(x)                           ((x) << 16)
+#define                POWERMODE2_MASK                         (0xff << 16)
+#define                POWERMODE2_SHIFT                        16
+#define                POWERMODE3(x)                           ((x) << 24)
+#define                POWERMODE3_MASK                         (0xff << 24)
+#define                POWERMODE3_SHIFT                        24
+
+#define MC_ARB_BURST_TIME                               0x2808
+#define                STATE0(x)                               ((x) << 0)
+#define                STATE0_MASK                             (0x1f << 0)
+#define                STATE0_SHIFT                            0
+#define                STATE1(x)                               ((x) << 5)
+#define                STATE1_MASK                             (0x1f << 5)
+#define                STATE1_SHIFT                            5
+#define                STATE2(x)                               ((x) << 10)
+#define                STATE2_MASK                             (0x1f << 10)
+#define                STATE2_SHIFT                            10
+#define                STATE3(x)                               ((x) << 15)
+#define                STATE3_MASK                             (0x1f << 15)
+#define                STATE3_SHIFT                            15
+
+#define MC_SEQ_RAS_TIMING                               0x28a0
+#define MC_SEQ_CAS_TIMING                               0x28a4
+#define MC_SEQ_MISC_TIMING                              0x28a8
+#define MC_SEQ_MISC_TIMING2                             0x28ac
+
+#define MC_SEQ_RD_CTL_D0                                0x28b4
+#define MC_SEQ_RD_CTL_D1                                0x28b8
+#define MC_SEQ_WR_CTL_D0                                0x28bc
+#define MC_SEQ_WR_CTL_D1                                0x28c0
+
+#define MC_PMG_AUTO_CFG                                 0x28d4
+
+#define MC_SEQ_STATUS_M                                 0x29f4
+#       define PMG_PWRSTATE                             (1 << 16)
+
+#define MC_SEQ_MISC0                                    0x2a00
+#define         MC_SEQ_MISC0_GDDR5_SHIFT                28
+#define         MC_SEQ_MISC0_GDDR5_MASK                 0xf0000000
+#define         MC_SEQ_MISC0_GDDR5_VALUE                5
+#define MC_SEQ_MISC1                                    0x2a04
+#define MC_SEQ_RESERVE_M                                0x2a08
+#define MC_PMG_CMD_EMRS                                 0x2a0c
+
+#define MC_SEQ_MISC3                                    0x2a2c
+
+#define MC_SEQ_MISC5                                    0x2a54
+#define MC_SEQ_MISC6                                    0x2a58
+
+#define MC_SEQ_MISC7                                    0x2a64
+
+#define MC_SEQ_CG                                       0x2a68
+#define                CG_SEQ_REQ(x)                           ((x) << 0)
+#define                CG_SEQ_REQ_MASK                         (0xff << 0)
+#define                CG_SEQ_REQ_SHIFT                        0
+#define                CG_SEQ_RESP(x)                          ((x) << 8)
+#define                CG_SEQ_RESP_MASK                        (0xff << 8)
+#define                CG_SEQ_RESP_SHIFT                       8
+#define                SEQ_CG_REQ(x)                           ((x) << 16)
+#define                SEQ_CG_REQ_MASK                         (0xff << 16)
+#define                SEQ_CG_REQ_SHIFT                        16
+#define                SEQ_CG_RESP(x)                          ((x) << 24)
+#define                SEQ_CG_RESP_MASK                        (0xff << 24)
+#define                SEQ_CG_RESP_SHIFT                       24
+#define MC_SEQ_RAS_TIMING_LP                            0x2a6c
+#define MC_SEQ_CAS_TIMING_LP                            0x2a70
+#define MC_SEQ_MISC_TIMING_LP                           0x2a74
+#define MC_SEQ_MISC_TIMING2_LP                          0x2a78
+#define MC_SEQ_WR_CTL_D0_LP                             0x2a7c
+#define MC_SEQ_WR_CTL_D1_LP                             0x2a80
+#define MC_SEQ_PMG_CMD_EMRS_LP                          0x2a84
+#define MC_SEQ_PMG_CMD_MRS_LP                           0x2a88
+
+#define MC_PMG_CMD_MRS                                  0x2aac
+
+#define MC_SEQ_RD_CTL_D0_LP                             0x2b1c
+#define MC_SEQ_RD_CTL_D1_LP                             0x2b20
+
+#define MC_PMG_CMD_MRS1                                 0x2b44
+#define MC_SEQ_PMG_CMD_MRS1_LP                          0x2b48
+
+#define        LB_SYNC_RESET_SEL                               0x6b28
+#define                LB_SYNC_RESET_SEL_MASK                  (3 << 0)
+#define                LB_SYNC_RESET_SEL_SHIFT                 0
+
+/* PCIE link stuff */
+#define PCIE_LC_SPEED_CNTL                                0xa4 /* PCIE_P */
+#       define LC_GEN2_EN_STRAP                           (1 << 0)
+#       define LC_TARGET_LINK_SPEED_OVERRIDE_EN           (1 << 1)
+#       define LC_FORCE_EN_HW_SPEED_CHANGE                (1 << 5)
+#       define LC_FORCE_DIS_HW_SPEED_CHANGE               (1 << 6)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK      (0x3 << 8)
+#       define LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT     3
+#       define LC_CURRENT_DATA_RATE                       (1 << 11)
+#       define LC_HW_VOLTAGE_IF_CONTROL(x)                ((x) << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_MASK              (3 << 12)
+#       define LC_HW_VOLTAGE_IF_CONTROL_SHIFT             12
+#       define LC_VOLTAGE_TIMER_SEL_MASK                  (0xf << 14)
+#       define LC_CLR_FAILED_SPD_CHANGE_CNT               (1 << 21)
+#       define LC_OTHER_SIDE_EVER_SENT_GEN2               (1 << 23)
+#       define LC_OTHER_SIDE_SUPPORTS_GEN2                (1 << 24)
+
+#endif
index 9bc3657..6b36b06 100644 (file)
@@ -22,8 +22,6 @@
  *
  * Authors:
  *     Alex Deucher <alexander.deucher@amd.com>
- *
- * $FreeBSD: head/sys/dev/drm2/radeon/cayman_blit_shaders.c 254885 2013-08-25 19:37:15Z dumbbell $
  */
 
 #include <drm/drmP.h>
index bc1a689..f5d0e9a 100644 (file)
@@ -20,7 +20,6 @@
  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  * DEALINGS IN THE SOFTWARE.
  *
- * $FreeBSD: head/sys/dev/drm2/radeon/cayman_blit_shaders.h 254885 2013-08-25 19:37:15Z dumbbell $
  */
 
 #ifndef CAYMAN_BLIT_SHADERS_H
diff --git a/sys/dev/drm/radeon/cik.c b/sys/dev/drm/radeon/cik.c
new file mode 100644 (file)
index 0000000..deaa610
--- /dev/null
@@ -0,0 +1,7039 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
+ *
+ * Authors: Alex Deucher
+ */
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <drm/drmP.h>
+#include "radeon.h"
+#include "radeon_asic.h"
+#include "cikd.h"
+#include "atom.h"
+#include "cik_blit_shaders.h"
+
+/* GFX */
+#define CIK_PFP_UCODE_SIZE 2144
+#define CIK_ME_UCODE_SIZE 2144
+#define CIK_CE_UCODE_SIZE 2144
+/* compute */
+#define CIK_MEC_UCODE_SIZE 4192
+/* interrupts */
+#define BONAIRE_RLC_UCODE_SIZE 2048
+#define KB_RLC_UCODE_SIZE 2560
+#define KV_RLC_UCODE_SIZE 2560
+/* gddr controller */
+#define CIK_MC_UCODE_SIZE 7866
+/* sdma */
+#define CIK_SDMA_UCODE_SIZE 1050
+#define CIK_SDMA_UCODE_VERSION 64
+
+MODULE_FIRMWARE("radeon/BONAIRE_pfp.bin");
+MODULE_FIRMWARE("radeon/BONAIRE_me.bin");
+MODULE_FIRMWARE("radeon/BONAIRE_ce.bin");
+MODULE_FIRMWARE("radeon/BONAIRE_mec.bin");
+MODULE_FIRMWARE("radeon/BONAIRE_mc.bin");
+MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin");
+MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin");
+MODULE_FIRMWARE("radeon/KAVERI_pfp.bin");
+MODULE_FIRMWARE("radeon/KAVERI_me.bin");
+MODULE_FIRMWARE("radeon/KAVERI_ce.bin");
+MODULE_FIRMWARE("radeon/KAVERI_mec.bin");
+MODULE_FIRMWARE("radeon/KAVERI_rlc.bin");
+MODULE_FIRMWARE("radeon/KAVERI_sdma.bin");
+MODULE_FIRMWARE("radeon/KABINI_pfp.bin");
+MODULE_FIRMWARE("radeon/KABINI_me.bin");
+MODULE_FIRMWARE("radeon/KABINI_ce.bin");
+MODULE_FIRMWARE("radeon/KABINI_mec.bin");
+MODULE_FIRMWARE("radeon/KABINI_rlc.bin");
+MODULE_FIRMWARE("radeon/KABINI_sdma.bin");
+
+static void cik_rlc_stop(struct radeon_device *rdev);
+
+/*
+ * Indirect registers accessor
+ */
+u32 cik_pciep_rreg(struct radeon_device *rdev, u32 reg)
+{
+       u32 r;
+
+       WREG32(PCIE_INDEX, reg);
+       (void)RREG32(PCIE_INDEX);
+       r = RREG32(PCIE_DATA);
+       return r;
+}
+
+void cik_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
+{
+       WREG32(PCIE_INDEX, reg);
+       (void)RREG32(PCIE_INDEX);
+       WREG32(PCIE_DATA, v);
+       (void)RREG32(PCIE_DATA);
+}
+
+static const u32 bonaire_golden_spm_registers[] =
+{
+       0x30800, 0xe0ffffff, 0xe0000000
+};
+
+static const u32 bonaire_golden_common_registers[] =
+{
+       0xc770, 0xffffffff, 0x00000800,
+       0xc774, 0xffffffff, 0x00000800,
+       0xc798, 0xffffffff, 0x00007fbf,
+       0xc79c, 0xffffffff, 0x00007faf
+};
+
+static const u32 bonaire_golden_registers[] =
+{
+       0x3354, 0x00000333, 0x00000333,
+       0x3350, 0x000c0fc0, 0x00040200,
+       0x9a10, 0x00010000, 0x00058208,
+       0x3c000, 0xffff1fff, 0x00140000,
+       0x3c200, 0xfdfc0fff, 0x00000100,
+       0x3c234, 0x40000000, 0x40000200,
+       0x9830, 0xffffffff, 0x00000000,
+       0x9834, 0xf00fffff, 0x00000400,
+       0x9838, 0x0002021c, 0x00020200,
+       0xc78, 0x00000080, 0x00000000,
+       0x5bb0, 0x000000f0, 0x00000070,
+       0x5bc0, 0xf0311fff, 0x80300000,
+       0x98f8, 0x73773777, 0x12010001,
+       0x350c, 0x00810000, 0x408af000,
+       0x7030, 0x31000111, 0x00000011,
+       0x2f48, 0x73773777, 0x12010001,
+       0x220c, 0x00007fb6, 0x0021a1b1,
+       0x2210, 0x00007fb6, 0x002021b1,
+       0x2180, 0x00007fb6, 0x00002191,
+       0x2218, 0x00007fb6, 0x002121b1,
+       0x221c, 0x00007fb6, 0x002021b1,
+       0x21dc, 0x00007fb6, 0x00002191,
+       0x21e0, 0x00007fb6, 0x00002191,
+       0x3628, 0x0000003f, 0x0000000a,
+       0x362c, 0x0000003f, 0x0000000a,
+       0x2ae4, 0x00073ffe, 0x000022a2,
+       0x240c, 0x000007ff, 0x00000000,
+       0x8a14, 0xf000003f, 0x00000007,
+       0x8bf0, 0x00002001, 0x00000001,
+       0x8b24, 0xffffffff, 0x00ffffff,
+       0x30a04, 0x0000ff0f, 0x00000000,
+       0x28a4c, 0x07ffffff, 0x06000000,
+       0x4d8, 0x00000fff, 0x00000100,
+       0x3e78, 0x00000001, 0x00000002,
+       0x9100, 0x03000000, 0x0362c688,
+       0x8c00, 0x000000ff, 0x00000001,
+       0xe40, 0x00001fff, 0x00001fff,
+       0x9060, 0x0000007f, 0x00000020,
+       0x9508, 0x00010000, 0x00010000,
+       0xac14, 0x000003ff, 0x000000f3,
+       0xac0c, 0xffffffff, 0x00001032
+};
+
+static const u32 bonaire_mgcg_cgcg_init[] =
+{
+       0xc420, 0xffffffff, 0xfffffffc,
+       0x30800, 0xffffffff, 0xe0000000,
+       0x3c2a0, 0xffffffff, 0x00000100,
+       0x3c208, 0xffffffff, 0x00000100,
+       0x3c2c0, 0xffffffff, 0xc0000100,
+       0x3c2c8, 0xffffffff, 0xc0000100,
+       0x3c2c4, 0xffffffff, 0xc0000100,
+       0x55e4, 0xffffffff, 0x00600100,
+       0x3c280, 0xffffffff, 0x00000100,
+       0x3c214, 0xffffffff, 0x06000100,
+       0x3c220, 0xffffffff, 0x00000100,
+       0x3c218, 0xffffffff, 0x06000100,
+       0x3c204, 0xffffffff, 0x00000100,
+       0x3c2e0, 0xffffffff, 0x00000100,
+       0x3c224, 0xffffffff, 0x00000100,
+       0x3c200, 0xffffffff, 0x00000100,
+       0x3c230, 0xffffffff, 0x00000100,
+       0x3c234, 0xffffffff, 0x00000100,
+       0x3c250, 0xffffffff, 0x00000100,
+       0x3c254, 0xffffffff, 0x00000100,
+       0x3c258, 0xffffffff, 0x00000100,
+       0x3c25c, 0xffffffff, 0x00000100,
+       0x3c260, 0xffffffff, 0x00000100,
+       0x3c27c, 0xffffffff, 0x00000100,
+       0x3c278, 0xffffffff, 0x00000100,
+       0x3c210, 0xffffffff, 0x06000100,
+       0x3c290, 0xffffffff, 0x00000100,
+       0x3c274, 0xffffffff, 0x00000100,
+       0x3c2b4, 0xffffffff, 0x00000100,
+       0x3c2b0, 0xffffffff, 0x00000100,
+       0x3c270, 0xffffffff, 0x00000100,
+       0x30800, 0xffffffff, 0xe0000000,
+       0x3c020, 0xffffffff, 0x00010000,
+       0x3c024, 0xffffffff, 0x00030002,
+       0x3c028, 0xffffffff, 0x00040007,
+       0x3c02c, 0xffffffff, 0x00060005,
+       0x3c030, 0xffffffff, 0x00090008,
+       0x3c034, 0xffffffff, 0x00010000,
+       0x3c038, 0xffffffff, 0x00030002,
+       0x3c03c, 0xffffffff, 0x00040007,
+       0x3c040, 0xffffffff, 0x00060005,
+       0x3c044, 0xffffffff, 0x00090008,
+       0x3c048, 0xffffffff, 0x00010000,
+       0x3c04c, 0xffffffff, 0x00030002,
+       0x3c050, 0xffffffff, 0x00040007,
+       0x3c054, 0xffffffff, 0x00060005,
+       0x3c058, 0xffffffff, 0x00090008,
+       0x3c05c, 0xffffffff, 0x00010000,
+       0x3c060, 0xffffffff, 0x00030002,
+       0x3c064, 0xffffffff, 0x00040007,
+       0x3c068, 0xffffffff, 0x00060005,
+       0x3c06c, 0xffffffff, 0x00090008,
+       0x3c070, 0xffffffff, 0x00010000,
+       0x3c074, 0xffffffff, 0x00030002,
+       0x3c078, 0xffffffff, 0x00040007,
+       0x3c07c, 0xffffffff, 0x00060005,
+       0x3c080, 0xffffffff, 0x00090008,
+       0x3c084, 0xffffffff, 0x00010000,
+       0x3c088, 0xffffffff, 0x00030002,
+       0x3c08c, 0xffffffff, 0x00040007,
+       0x3c090, 0xffffffff, 0x00060005,
+       0x3c094, 0xffffffff, 0x00090008,
+       0x3c098, 0xffffffff, 0x00010000,
+       0x3c09c, 0xffffffff, 0x00030002,
+       0x3c0a0, 0xffffffff, 0x00040007,
+       0x3c0a4, 0xffffffff, 0x00060005,
+       0x3c0a8, 0xffffffff, 0x00090008,
+       0x3c000, 0xffffffff, 0x96e00200,
+       0x8708, 0xffffffff, 0x00900100,
+       0xc424, 0xffffffff, 0x0020003f,
+       0x38, 0xffffffff, 0x0140001c,
+       0x3c, 0x000f0000, 0x000f0000,
+       0x220, 0xffffffff, 0xC060000C,
+       0x224, 0xc0000fff, 0x00000100,
+       0xf90, 0xffffffff, 0x00000100,
+       0xf98, 0x00000101, 0x00000000,
+       0x20a8, 0xffffffff, 0x00000104,
+       0x55e4, 0xff000fff, 0x00000100,
+       0x30cc, 0xc0000fff, 0x00000104,
+       0xc1e4, 0x00000001, 0x00000001,
+       0xd00c, 0xff000ff0, 0x00000100,
+       0xd80c, 0xff000ff0, 0x00000100
+};
+
+static const u32 spectre_golden_spm_registers[] =
+{
+       0x30800, 0xe0ffffff, 0xe0000000
+};
+
+static const u32 spectre_golden_common_registers[] =
+{
+       0xc770, 0xffffffff, 0x00000800,
+       0xc774, 0xffffffff, 0x00000800,
+       0xc798, 0xffffffff, 0x00007fbf,
+       0xc79c, 0xffffffff, 0x00007faf
+};
+
+static const u32 spectre_golden_registers[] =
+{
+       0x3c000, 0xffff1fff, 0x96940200,
+       0x3c00c, 0xffff0001, 0xff000000,
+       0x3c200, 0xfffc0fff, 0x00000100,
+       0x6ed8, 0x00010101, 0x00010000,
+       0x9834, 0xf00fffff, 0x00000400,
+       0x9838, 0xfffffffc, 0x00020200,
+       0x5bb0, 0x000000f0, 0x00000070,
+       0x5bc0, 0xf0311fff, 0x80300000,
+       0x98f8, 0x73773777, 0x12010001,
+       0x9b7c, 0x00ff0000, 0x00fc0000,
+       0x2f48, 0x73773777, 0x12010001,
+       0x8a14, 0xf000003f, 0x00000007,
+       0x8b24, 0xffffffff, 0x00ffffff,
+       0x28350, 0x3f3f3fff, 0x00000082,
+       0x28355, 0x0000003f, 0x00000000,
+       0x3e78, 0x00000001, 0x00000002,
+       0x913c, 0xffff03df, 0x00000004,
+       0xc768, 0x00000008, 0x00000008,
+       0x8c00, 0x000008ff, 0x00000800,
+       0x9508, 0x00010000, 0x00010000,
+       0xac0c, 0xffffffff, 0x54763210,
+       0x214f8, 0x01ff01ff, 0x00000002,
+       0x21498, 0x007ff800, 0x00200000,
+       0x2015c, 0xffffffff, 0x00000f40,
+       0x30934, 0xffffffff, 0x00000001
+};
+
+static const u32 spectre_mgcg_cgcg_init[] =
+{
+       0xc420, 0xffffffff, 0xfffffffc,
+       0x30800, 0xffffffff, 0xe0000000,
+       0x3c2a0, 0xffffffff, 0x00000100,
+       0x3c208, 0xffffffff, 0x00000100,
+       0x3c2c0, 0xffffffff, 0x00000100,
+       0x3c2c8, 0xffffffff, 0x00000100,
+       0x3c2c4, 0xffffffff, 0x00000100,
+       0x55e4, 0xffffffff, 0x00600100,
+       0x3c280, 0xffffffff, 0x00000100,
+       0x3c214, 0xffffffff, 0x06000100,
+       0x3c220, 0xffffffff, 0x00000100,
+       0x3c218, 0xffffffff, 0x06000100,
+       0x3c204, 0xffffffff, 0x00000100,
+       0x3c2e0, 0xffffffff, 0x00000100,
+       0x3c224, 0xffffffff, 0x00000100,
+       0x3c200, 0xffffffff, 0x00000100,
+       0x3c230, 0xffffffff, 0x00000100,
+       0x3c234, 0xffffffff, 0x00000100,
+       0x3c250, 0xffffffff, 0x00000100,
+       0x3c254, 0xffffffff, 0x00000100,
+       0x3c258, 0xffffffff, 0x00000100,
+       0x3c25c, 0xffffffff, 0x00000100,
+       0x3c260, 0xffffffff, 0x00000100,
+       0x3c27c, 0xffffffff, 0x00000100,
+       0x3c278, 0xffffffff, 0x00000100,
+       0x3c210, 0xffffffff, 0x06000100,
+       0x3c290, 0xffffffff, 0x00000100,
+       0x3c274, 0xffffffff, 0x00000100,
+       0x3c2b4, 0xffffffff, 0x00000100,
+       0x3c2b0, 0xffffffff, 0x00000100,
+       0x3c270, 0xffffffff, 0x00000100,
+       0x30800, 0xffffffff, 0xe0000000,
+       0x3c020, 0xffffffff, 0x00010000,
+       0x3c024, 0xffffffff, 0x00030002,
+       0x3c028, 0xffffffff, 0x00040007,
+       0x3c02c, 0xffffffff, 0x00060005,
+       0x3c030, 0xffffffff, 0x00090008,
+       0x3c034, 0xffffffff, 0x00010000,
+       0x3c038, 0xffffffff, 0x00030002,
+       0x3c03c, 0xffffffff, 0x00040007,
+       0x3c040, 0xffffffff, 0x00060005,
+       0x3c044, 0xffffffff, 0x00090008,
+       0x3c048, 0xffffffff, 0x00010000,
+       0x3c04c, 0xffffffff, 0x00030002,
+       0x3c050, 0xffffffff, 0x00040007,
+       0x3c054, 0xffffffff, 0x00060005,
+       0x3c058, 0xffffffff, 0x00090008,
+       0x3c05c, 0xffffffff, 0x00010000,
+       0x3c060, 0xffffffff, 0x00030002,
+       0x3c064, 0xffffffff, 0x00040007,
+       0x3c068, 0xffffffff, 0x00060005,
+       0x3c06c, 0xffffffff, 0x00090008,
+       0x3c070, 0xffffffff, 0x00010000,
+       0x3c074, 0xffffffff, 0x00030002,
+       0x3c078, 0xffffffff, 0x00040007,
+       0x3c07c, 0xffffffff, 0x00060005,
+       0x3c080, 0xffffffff, 0x00090008,
+       0x3c084, 0xffffffff, 0x00010000,
+       0x3c088, 0xffffffff, 0x00030002,
+       0x3c08c, 0xffffffff, 0x00040007,
+       0x3c090, 0xffffffff, 0x00060005,
+       0x3c094, 0xffffffff, 0x00090008,
+       0x3c098, 0xffffffff, 0x00010000,
+       0x3c09c, 0xffffffff, 0x00030002,
+       0x3c0a0, 0xffffffff, 0x00040007,
+       0x3c0a4, 0xffffffff, 0x00060005,
+       0x3c0a8, 0xffffffff, 0x00090008,
+       0x3c0ac, 0xffffffff, 0x00010000,
+       0x3c0b0, 0xffffffff, 0x00030002,
+       0x3c0b4, 0xffffffff, 0x00040007,
+       0x3c0b8, 0xffffffff, 0x00060005,
+       0x3c0bc, 0xffffffff, 0x00090008,
+       0x3c000, 0xffffffff, 0x96e00200,
+       0x8708, 0xffffffff, 0x00900100,
+       0xc424, 0xffffffff, 0x0020003f,
+       0x38, 0xffffffff, 0x0140001c,
+       0x3c, 0x000f0000, 0x000f0000,
+       0x220, 0xffffffff, 0xC060000C,
+       0x224, 0xc0000fff, 0x00000100,
+       0xf90, 0xffffffff, 0x00000100,
+       0xf98, 0x00000101, 0x00000000,
+       0x20a8, 0xffffffff, 0x00000104,
+       0x55e4, 0xff000fff, 0x00000100,
+       0x30cc, 0xc0000fff, 0x00000104,
+       0xc1e4, 0x00000001, 0x00000001,
+       0xd00c, 0xff000ff0, 0x00000100,
+       0xd80c, 0xff000ff0, 0x00000100
+};
+
+static const u32 kalindi_golden_spm_registers[] =
+{
+       0x30800, 0xe0ffffff, 0xe0000000
+};
+
+static const u32 kalindi_golden_common_registers[] =
+{
+       0xc770, 0xffffffff, 0x00000800,
+       0xc774, 0xffffffff, 0x00000800,
+       0xc798, 0xffffffff, 0x00007fbf,
+       0xc79c, 0xffffffff, 0x00007faf
+};
+
+static const u32 kalindi_golden_registers[] =
+{
+       0x3c000, 0xffffdfff, 0x6e944040,
+       0x55e4, 0xff607fff, 0xfc000100,
+       0x3c220, 0xff000fff, 0x00000100,
+       0x3c224, 0xff000fff, 0x00000100,
+       0x3c200, 0xfffc0fff, 0x00000100,
+       0x6ed8, 0x00010101, 0x00010000,
+       0x9830, 0xffffffff, 0x00000000,
+       0x9834, 0xf00fffff, 0x00000400,
+       0x5bb0, 0x000000f0, 0x00000070,
+       0x5bc0, 0xf0311fff, 0x80300000,
+       0x98f8, 0x73773777, 0x12010001,
+       0x98fc, 0xffffffff, 0x00000010,
+       0x9b7c, 0x00ff0000, 0x00fc0000,
+       0x8030, 0x00001f0f, 0x0000100a,
+       0x2f48, 0x73773777, 0x12010001,
+       0x2408, 0x000fffff, 0x000c007f,
+       0x8a14, 0xf000003f, 0x00000007,
+       0x8b24, 0x3fff3fff, 0x00ffcfff,
+       0x30a04, 0x0000ff0f, 0x00000000,
+       0x28a4c, 0x07ffffff, 0x06000000,
+       0x4d8, 0x00000fff, 0x00000100,
+       0x3e78, 0x00000001, 0x00000002,
+       0xc768, 0x00000008, 0x00000008,
+       0x8c00, 0x000000ff, 0x00000003,
+       0x214f8, 0x01ff01ff, 0x00000002,
+       0x21498, 0x007ff800, 0x00200000,
+       0x2015c, 0xffffffff, 0x00000f40,
+       0x88c4, 0x001f3ae3, 0x00000082,
+       0x88d4, 0x0000001f, 0x00000010,
+       0x30934, 0xffffffff, 0x00000000
+};
+
+static const u32 kalindi_mgcg_cgcg_init[] =
+{
+       0xc420, 0xffffffff, 0xfffffffc,
+       0x30800, 0xffffffff, 0xe0000000,
+       0x3c2a0, 0xffffffff, 0x00000100,
+       0x3c208, 0xffffffff, 0x00000100,
+       0x3c2c0, 0xffffffff, 0x00000100,
+       0x3c2c8, 0xffffffff, 0x00000100,
+       0x3c2c4, 0xffffffff, 0x00000100,
+       0x55e4, 0xffffffff, 0x00600100,
+       0x3c280, 0xffffffff, 0x00000100,
+       0x3c214, 0xffffffff, 0x06000100,
+       0x3c220, 0xffffffff, 0x00000100,
+       0x3c218, 0xffffffff, 0x06000100,
+       0x3c204, 0xffffffff, 0x00000100,
+       0x3c2e0, 0xffffffff, 0x00000100,
+       0x3c224, 0xffffffff, 0x00000100,
+       0x3c200, 0xffffffff, 0x00000100,
+       0x3c230, 0xffffffff, 0x00000100,
+       0x3c234, 0xffffffff, 0x00000100,
+       0x3c250, 0xffffffff, 0x00000100,
+       0x3c254, 0xffffffff, 0x00000100,
+       0x3c258, 0xffffffff, 0x00000100,
+       0x3c25c, 0xffffffff, 0x00000100,
+       0x3c260, 0xffffffff, 0x00000100,
+       0x3c27c, 0xffffffff, 0x00000100,
+       0x3c278, 0xffffffff, 0x00000100,
+       0x3c210, 0xffffffff, 0x06000100,
+       0x3c290, 0xffffffff, 0x00000100,
+       0x3c274, 0xffffffff, 0x00000100,
+       0x3c2b4, 0xffffffff, 0x00000100,
+       0x3c2b0, 0xffffffff, 0x00000100,
+       0x3c270, 0xffffffff, 0x00000100,
+       0x30800, 0xffffffff, 0xe0000000,
+       0x3c020, 0xffffffff, 0x00010000,
+       0x3c024, 0xffffffff, 0x00030002,
+       0x3c028, 0xffffffff, 0x00040007,
+       0x3c02c, 0xffffffff, 0x00060005,
+       0x3c030, 0xffffffff, 0x00090008,
+       0x3c034, 0xffffffff, 0x00010000,
+       0x3c038, 0xffffffff, 0x00030002,
+       0x3c03c, 0xffffffff, 0x00040007,
+       0x3c040, 0xffffffff, 0x00060005,
+       0x3c044, 0xffffffff, 0x00090008,
+       0x3c000, 0xffffffff, 0x96e00200,
+       0x8708, 0xffffffff, 0x00900100,
+       0xc424, 0xffffffff, 0x0020003f,
+       0x38, 0xffffffff, 0x0140001c,
+       0x3c, 0x000f0000, 0x000f0000,
+       0x220, 0xffffffff, 0xC060000C,
+       0x224, 0xc0000fff, 0x00000100,
+       0x20a8, 0xffffffff, 0x00000104,
+       0x55e4, 0xff000fff, 0x00000100,
+       0x30cc, 0xc0000fff, 0x00000104,
+       0xc1e4, 0x00000001, 0x00000001,
+       0xd00c, 0xff000ff0, 0x00000100,
+       0xd80c, 0xff000ff0, 0x00000100
+};
+
+static void cik_init_golden_registers(struct radeon_device *rdev)
+{
+       switch (rdev->family) {
+       case CHIP_BONAIRE:
+               radeon_program_register_sequence(rdev,
+                                                bonaire_mgcg_cgcg_init,
+                                                (const u32)ARRAY_SIZE(bonaire_mgcg_cgcg_init));
+               radeon_program_register_sequence(rdev,
+                                                bonaire_golden_registers,
+                                                (const u32)ARRAY_SIZE(bonaire_golden_registers));
+               radeon_program_register_sequence(rdev,
+                                                bonaire_golden_common_registers,
+                                                (const u32)ARRAY_SIZE(bonaire_golden_common_registers));
+               radeon_program_register_sequence(rdev,
+                                                bonaire_golden_spm_registers,
+                                                (const u32)ARRAY_SIZE(bonaire_golden_spm_registers));
+               break;
+       case CHIP_KABINI:
+               radeon_program_register_sequence(rdev,
+                                                kalindi_mgcg_cgcg_init,
+                                                (const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init));
+               radeon_program_register_sequence(rdev,
+                                                kalindi_golden_registers,
+                                                (const u32)ARRAY_SIZE(kalindi_golden_registers));
+               radeon_program_register_sequence(rdev,
+                                                kalindi_golden_common_registers,
+                                                (const u32)ARRAY_SIZE(kalindi_golden_common_registers));
+               radeon_program_register_sequence(rdev,
+                                                kalindi_golden_spm_registers,
+                                                (const u32)ARRAY_SIZE(kalindi_golden_spm_registers));
+               break;
+       case CHIP_KAVERI:
+               radeon_program_register_sequence(rdev,
+                                                spectre_mgcg_cgcg_init,
+                                                (const u32)ARRAY_SIZE(spectre_mgcg_cgcg_init));
+               radeon_program_register_sequence(rdev,
+                                                spectre_golden_registers,
+                                                (const u32)ARRAY_SIZE(spectre_golden_registers));
+               radeon_program_register_sequence(rdev,
+                                                spectre_golden_common_registers,
+                                                (const u32)ARRAY_SIZE(spectre_golden_common_registers));
+               radeon_program_register_sequence(rdev,
+                                                spectre_golden_spm_registers,
+                                                (const u32)ARRAY_SIZE(spectre_golden_spm_registers));
+               break;
+       default:
+               break;
+       }
+}
+
+/**
+ * cik_get_xclk - get the xclk
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Returns the reference clock used by the gfx engine
+ * (CIK).
+ */
+u32 cik_get_xclk(struct radeon_device *rdev)
+{
+        u32 reference_clock = rdev->clock.spll.reference_freq;
+
+       if (rdev->flags & RADEON_IS_IGP) {
+               if (RREG32_SMC(GENERAL_PWRMGT) & GPU_COUNTER_CLK)
+                       return reference_clock / 2;
+       } else {
+               if (RREG32_SMC(CG_CLKPIN_CNTL) & XTALIN_DIVIDE)
+                       return reference_clock / 4;
+       }
+       return reference_clock;
+}
+
+/**
+ * cik_mm_rdoorbell - read a doorbell dword
+ *
+ * @rdev: radeon_device pointer
+ * @offset: byte offset into the aperture
+ *
+ * Returns the value in the doorbell aperture at the
+ * requested offset (CIK).
+ */
+u32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 offset)
+{
+       if (offset < rdev->doorbell.size) {
+               return readl(((uint8_t __iomem *)rdev->doorbell.ptr) + offset);
+       } else {
+               DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", offset);
+               return 0;
+       }
+}
+
+/**
+ * cik_mm_wdoorbell - write a doorbell dword
+ *
+ * @rdev: radeon_device pointer
+ * @offset: byte offset into the aperture
+ * @v: value to write
+ *
+ * Writes @v to the doorbell aperture at the
+ * requested offset (CIK).
+ */
+void cik_mm_wdoorbell(struct radeon_device *rdev, u32 offset, u32 v)
+{
+       if (offset < rdev->doorbell.size) {
+               writel(v, ((uint8_t __iomem *)rdev->doorbell.ptr) + offset);
+       } else {
+               DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", offset);
+       }
+}
+
+#define BONAIRE_IO_MC_REGS_SIZE 36
+
+static const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] =
+{
+       {0x00000070, 0x04400000},
+       {0x00000071, 0x80c01803},
+       {0x00000072, 0x00004004},
+       {0x00000073, 0x00000100},
+       {0x00000074, 0x00ff0000},
+       {0x00000075, 0x34000000},
+       {0x00000076, 0x08000014},
+       {0x00000077, 0x00cc08ec},
+       {0x00000078, 0x00000400},
+       {0x00000079, 0x00000000},
+       {0x0000007a, 0x04090000},
+       {0x0000007c, 0x00000000},
+       {0x0000007e, 0x4408a8e8},
+       {0x0000007f, 0x00000304},
+       {0x00000080, 0x00000000},
+       {0x00000082, 0x00000001},
+       {0x00000083, 0x00000002},
+       {0x00000084, 0xf3e4f400},
+       {0x00000085, 0x052024e3},
+       {0x00000087, 0x00000000},
+       {0x00000088, 0x01000000},
+       {0x0000008a, 0x1c0a0000},
+       {0x0000008b, 0xff010000},
+       {0x0000008d, 0xffffefff},
+       {0x0000008e, 0xfff3efff},
+       {0x0000008f, 0xfff3efbf},
+       {0x00000092, 0xf7ffffff},
+       {0x00000093, 0xffffff7f},
+       {0x00000095, 0x00101101},
+       {0x00000096, 0x00000fff},
+       {0x00000097, 0x00116fff},
+       {0x00000098, 0x60010000},
+       {0x00000099, 0x10010000},
+       {0x0000009a, 0x00006000},
+       {0x0000009b, 0x00001000},
+       {0x0000009f, 0x00b48000}
+};
+
+/**
+ * cik_srbm_select - select specific register instances
+ *
+ * @rdev: radeon_device pointer
+ * @me: selected ME (micro engine)
+ * @pipe: pipe
+ * @queue: queue
+ * @vmid: VMID
+ *
+ * Switches the currently active registers instances.  Some
+ * registers are instanced per VMID, others are instanced per
+ * me/pipe/queue combination.
+ */
+static void cik_srbm_select(struct radeon_device *rdev,
+                           u32 me, u32 pipe, u32 queue, u32 vmid)
+{
+       u32 srbm_gfx_cntl = (PIPEID(pipe & 0x3) |
+                            MEID(me & 0x3) |
+                            VMID(vmid & 0xf) |
+                            QUEUEID(queue & 0x7));
+       WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl);
+}
+
+/* ucode loading */
+/**
+ * ci_mc_load_microcode - load MC ucode into the hw
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Load the GDDR MC ucode into the hw (CIK).
+ * Returns 0 on success, error on failure.
+ */
+static __unused int ci_mc_load_microcode(struct radeon_device *rdev)
+{
+       const __be32 *fw_data;
+       u32 running, blackout = 0;
+       u32 *io_mc_regs;
+       int i, ucode_size, regs_size;
+
+       if (!rdev->mc_fw)
+               return -EINVAL;
+
+       switch (rdev->family) {
+       case CHIP_BONAIRE:
+       default:
+               io_mc_regs = (u32 *)&bonaire_io_mc_regs;
+               ucode_size = CIK_MC_UCODE_SIZE;
+               regs_size = BONAIRE_IO_MC_REGS_SIZE;
+               break;
+       }
+
+       running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
+
+       if (running == 0) {
+               if (running) {
+                       blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
+                       WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
+               }
+
+               /* reset the engine and set to writable */
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
+
+               /* load mc io regs */
+               for (i = 0; i < regs_size; i++) {
+                       WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
+                       WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
+               }
+               /* load the MC ucode */
+               fw_data = (const __be32 *)rdev->mc_fw->data;
+               for (i = 0; i < ucode_size; i++)
+                       WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
+
+               /* put the engine back into the active state */
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
+               WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
+
+               /* wait for training to complete */
+               for (i = 0; i < rdev->usec_timeout; i++) {
+                       if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
+                               break;
+                       DRM_UDELAY(1);
+               }
+               for (i = 0; i < rdev->usec_timeout; i++) {
+                       if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
+                               break;
+                       DRM_UDELAY(1);
+               }
+
+               if (running)
+                       WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
+       }
+
+       return 0;
+}
+
+/**
+ * cik_init_microcode - load ucode images from disk
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Use the firmware interface to load the ucode images into
+ * the driver (not loaded into hw).
+ * Returns 0 on success, error on failure.
+ */
+static int cik_init_microcode(struct radeon_device *rdev)
+{
+       const char *chip_name;
+       size_t pfp_req_size, me_req_size, ce_req_size,
+               mec_req_size, rlc_req_size, mc_req_size,
+               sdma_req_size;
+       char fw_name[30];
+       int err;
+
+       DRM_DEBUG("\n");
+
+       switch (rdev->family) {
+       case CHIP_BONAIRE:
+               chip_name = "BONAIRE";
+               pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
+               me_req_size = CIK_ME_UCODE_SIZE * 4;
+               ce_req_size = CIK_CE_UCODE_SIZE * 4;
+               mec_req_size = CIK_MEC_UCODE_SIZE * 4;
+               rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
+               mc_req_size = CIK_MC_UCODE_SIZE * 4;
+               sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+               break;
+       case CHIP_KAVERI:
+               chip_name = "KAVERI";
+               pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
+               me_req_size = CIK_ME_UCODE_SIZE * 4;
+               ce_req_size = CIK_CE_UCODE_SIZE * 4;
+               mec_req_size = CIK_MEC_UCODE_SIZE * 4;
+               rlc_req_size = KV_RLC_UCODE_SIZE * 4;
+               sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+               break;
+       case CHIP_KABINI:
+               chip_name = "KABINI";
+               pfp_req_size = CIK_PFP_UCODE_SIZE * 4;
+               me_req_size = CIK_ME_UCODE_SIZE * 4;
+               ce_req_size = CIK_CE_UCODE_SIZE * 4;
+               mec_req_size = CIK_MEC_UCODE_SIZE * 4;
+               rlc_req_size = KB_RLC_UCODE_SIZE * 4;
+               sdma_req_size = CIK_SDMA_UCODE_SIZE * 4;
+               break;
+       default: BUG();
+       }
+
+       DRM_INFO("Loading %s Microcode\n", chip_name);
+       err = 0;
+
+       ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name);
+       rdev->pfp_fw = firmware_get(fw_name);
+       if (rdev->pfp_fw == NULL) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (rdev->pfp_fw->datasize != pfp_req_size) {
+               printk(KERN_ERR
+                      "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->pfp_fw->datasize, fw_name);
+               err = -EINVAL;
+               goto out;
+       }
+
+       ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name);
+       rdev->me_fw = firmware_get(fw_name);
+       if (rdev->me_fw == NULL) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (rdev->me_fw->datasize != me_req_size) {
+               printk(KERN_ERR
+                      "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->me_fw->datasize, fw_name);
+               err = -EINVAL;
+       }
+
+       ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_ce", chip_name);
+       rdev->ce_fw = firmware_get(fw_name);
+       if (rdev->ce_fw == NULL) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (rdev->ce_fw->datasize != ce_req_size) {
+               printk(KERN_ERR
+                      "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->ce_fw->datasize, fw_name);
+               err = -EINVAL;
+       }
+
+       ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mec", chip_name);
+       rdev->mec_fw = firmware_get(fw_name);
+       if (rdev->mec_fw == NULL) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (rdev->mec_fw->datasize != mec_req_size) {
+               printk(KERN_ERR
+                      "cik_cp: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->mec_fw->datasize, fw_name);
+               err = -EINVAL;
+       }
+
+       ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", chip_name);
+       rdev->rlc_fw = firmware_get(fw_name);
+       if (rdev->rlc_fw == NULL) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (rdev->rlc_fw->datasize != rlc_req_size) {
+               printk(KERN_ERR
+                      "cik_rlc: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->rlc_fw->datasize, fw_name);
+               err = -EINVAL;
+       }
+
+       ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_sdma", chip_name);
+       rdev->sdma_fw = firmware_get(fw_name);
+       if (rdev->sdma_fw == NULL) {
+               err = -ENOENT;
+               goto out;
+       }
+       if (rdev->sdma_fw->datasize != sdma_req_size) {
+               printk(KERN_ERR
+                      "cik_sdma: Bogus length %zu in firmware \"%s\"\n",
+                      rdev->sdma_fw->datasize, fw_name);
+               err = -EINVAL;
+       }
+
+       /* No MC ucode on APUs */
+       if (!(rdev->flags & RADEON_IS_IGP)) {
+               ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", chip_name);
+               rdev->mc_fw = firmware_get(fw_name);
+               if (rdev->mc_fw == NULL) {
+                       err = -ENOENT;
+                       goto out;
+               }
+               if (rdev->mc_fw->datasize != mc_req_size) {
+                       printk(KERN_ERR
+                              "cik_mc: Bogus length %zu in firmware \"%s\"\n",
+                              rdev->mc_fw->datasize, fw_name);
+                       err = -EINVAL;
+               }
+       }
+
+out:
+       if (err) {
+               if (err != -EINVAL)
+                       printk(KERN_ERR
+                              "cik_cp: Failed to load firmware \"%s\"\n",
+                              fw_name);
+               if (rdev->pfp_fw != NULL) {
+                       firmware_put(rdev->pfp_fw, FIRMWARE_UNLOAD);
+                       rdev->pfp_fw = NULL;
+               }
+               if (rdev->me_fw != NULL) {
+                       firmware_put(rdev->me_fw, FIRMWARE_UNLOAD);
+                       rdev->me_fw = NULL;
+               }
+               if (rdev->ce_fw != NULL) {
+                       firmware_put(rdev->ce_fw, FIRMWARE_UNLOAD);
+                       rdev->ce_fw = NULL;
+               }
+               if (rdev->mec_fw != NULL) {
+                       firmware_put(rdev->mec_fw, FIRMWARE_UNLOAD);
+                       rdev->mec_fw = NULL;
+               }
+               if (rdev->rlc_fw != NULL) {
+                       firmware_put(rdev->rlc_fw, FIRMWARE_UNLOAD);
+                       rdev->rlc_fw = NULL;
+               }
+               if (rdev->sdma_fw != NULL) {
+                       firmware_put(rdev->sdma_fw, FIRMWARE_UNLOAD);
+                       rdev->sdma_fw = NULL;
+               }
+               if (rdev->mc_fw != NULL) {
+                       firmware_put(rdev->mc_fw, FIRMWARE_UNLOAD);
+                       rdev->mc_fw = NULL;
+               }
+       }
+       return err;
+}
+
+/*
+ * Core functions
+ */
+/**
+ * cik_tiling_mode_table_init - init the hw tiling table
+ *
+ * @rdev: radeon_device pointer
+ *
+ * Starting with SI, the tiling setup is done globally in a
+ * set of 32 tiling modes.  Rather than selecting each set of
+ * parameters per surface as on older asics, we just select
+ * which index in the tiling table we want to use, and the
+ * surface uses those parameters (CIK).
+ */
+static void cik_tiling_mode_table_init(struct radeon_device *rdev)
+{
+       const u32 num_tile_mode_states = 32;
+       const u32 num_secondary_tile_mode_states = 16;
+       u32 reg_offset, gb_tile_moden, split_equal_to_row_size;
+       u32 num_pipe_configs;
+       u32 num_rbs = rdev->config.cik.max_backends_per_se *
+               rdev->config.cik.max_shader_engines;
+
+       switch (rdev->config.cik.mem_row_size_in_kb) {
+       case 1:
+               split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB;
+               break;
+       case 2:
+       default:
+               split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB;
+               break;
+       case 4:
+               split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB;
+               break;
+       }
+
+       num_pipe_configs = rdev->config.cik.max_tile_pipes;
+       if (num_pipe_configs > 8)
+               num_pipe_configs = 8; /* ??? */
+
+       if (num_pipe_configs == 8) {
+               for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
+                       switch (reg_offset) {
+                       case 0:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+                               break;
+                       case 1:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+                               break;
+                       case 2:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+                               break;
+                       case 3:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+                               break;
+                       case 4:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                TILE_SPLIT(split_equal_to_row_size));
+                               break;
+                       case 5:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+                               break;
+                       case 6:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+                               break;
+                       case 7:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                TILE_SPLIT(split_equal_to_row_size));
+                               break;
+                       case 8:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16));
+                               break;
+                       case 9:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+                               break;
+                       case 10:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       case 11:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       case 12:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       case 13:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+                               break;
+                       case 14:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       case 16:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       case 17:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       case 27:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+                               break;
+                       case 28:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       case 29:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       case 30:
+                               gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                                                PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) |
+                                                SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                               break;
+                       default:
+                               gb_tile_moden = 0;
+                               break;
+                       }
+                       rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
+                       WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+               }
+               for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) {
+                       switch (reg_offset) {
+                       case 0:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+                                                NUM_BANKS(ADDR_SURF_16_BANK));
+                               break;
+                       case 1:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+                                                NUM_BANKS(ADDR_SURF_16_BANK));
+                               break;
+                       case 2:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+                                                NUM_BANKS(ADDR_SURF_16_BANK));
+                               break;
+                       case 3:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+                                                NUM_BANKS(ADDR_SURF_16_BANK));
+                               break;
+                       case 4:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+                                                NUM_BANKS(ADDR_SURF_8_BANK));
+                               break;
+                       case 5:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+                                                NUM_BANKS(ADDR_SURF_4_BANK));
+                               break;
+                       case 6:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+                                                NUM_BANKS(ADDR_SURF_2_BANK));
+                               break;
+                       case 8:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+                                                NUM_BANKS(ADDR_SURF_16_BANK));
+                               break;
+                       case 9:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) |
+                                                NUM_BANKS(ADDR_SURF_16_BANK));
+                               break;
+                       case 10:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+                                                NUM_BANKS(ADDR_SURF_16_BANK));
+                               break;
+                       case 11:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) |
+                                                NUM_BANKS(ADDR_SURF_16_BANK));
+                               break;
+                       case 12:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+                                                NUM_BANKS(ADDR_SURF_8_BANK));
+                               break;
+                       case 13:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+                                                NUM_BANKS(ADDR_SURF_4_BANK));
+                               break;
+                       case 14:
+                               gb_tile_moden = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
+                                                BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
+                                                MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) |
+                                                NUM_BANKS(ADDR_SURF_2_BANK));
+                               break;
+                       default:
+                               gb_tile_moden = 0;
+                               break;
+                       }
+                       WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+               }
+       } else if (num_pipe_configs == 4) {
+               if (num_rbs == 4) {
+                       for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
+                               switch (reg_offset) {
+                               case 0:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+                                       break;
+                               case 1:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+                                       break;
+                               case 2:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+                                       break;
+                               case 3:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+                                       break;
+                               case 4:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        TILE_SPLIT(split_equal_to_row_size));
+                                       break;
+                               case 5:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+                                       break;
+                               case 6:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+                                       break;
+                               case 7:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        TILE_SPLIT(split_equal_to_row_size));
+                                       break;
+                               case 8:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16));
+                                       break;
+                               case 9:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+                                       break;
+                               case 10:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 11:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 12:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 13:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING));
+                                       break;
+                               case 14:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 16:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 17:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 27:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING));
+                                       break;
+                               case 28:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 29:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 30:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_16x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               default:
+                                       gb_tile_moden = 0;
+                                       break;
+                               }
+                               rdev->config.cik.tile_mode_array[reg_offset] = gb_tile_moden;
+                               WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
+                       }
+               } else if (num_rbs < 4) {
+                       for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
+                               switch (reg_offset) {
+                               case 0:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B));
+                                       break;
+                               case 1:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B));
+                                       break;
+                               case 2:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+                                       break;
+                               case 3:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B));
+                                       break;
+                               case 4:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        TILE_SPLIT(split_equal_to_row_size));
+                                       break;
+                               case 5:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING));
+                                       break;
+                               case 6:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B));
+                                       break;
+                               case 7:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        TILE_SPLIT(split_equal_to_row_size));
+                                       break;
+                               case 8:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
+                                                PIPE_CONFIG(ADDR_SURF_P4_8x16));
+                                       break;
+                               case 9:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING));
+                                       break;
+                               case 10:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 11:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 12:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) |
+                                                        MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) |
+                                                        PIPE_CONFIG(ADDR_SURF_P4_8x16) |
+                                                        SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2));
+                                       break;
+                               case 13:
+                                       gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
+