All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jerome Glisse <j.glisse@gmail.com>
To: alexdeucher@gmail.com
Cc: Alex Deucher <alexander.deucher@amd.com>,
	dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 093/165] drm/radeon/kms: add dpm support for cayman
Date: Wed, 26 Jun 2013 07:29:29 -0400	[thread overview]
Message-ID: <20130626112928.GF2480@gmail.com> (raw)
In-Reply-To: <1372253045-17042-94-git-send-email-alexdeucher@gmail.com>

On Wed, Jun 26, 2013 at 09:22:53AM -0400, alexdeucher@gmail.com wrote:
> From: Alex Deucher <alexander.deucher@amd.com>
> 
> This adds dpm support for cayman asics.  This includes:
> - clockgating
> - dynamic engine clock scaling
> - dynamic memory clock scaling
> - dynamic voltage scaling
> - dynamic pcie gen1/gen2 switching (requires additional acpi support)
> - power containment
> - shader power scaling
> 
> Set radeon.dpm=1 to enable.
> 
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

Reviewed-by: Jerome Glisse <jglisse@redhat.com>

> ---
>  drivers/gpu/drm/radeon/Makefile       |    2 +-
>  drivers/gpu/drm/radeon/btc_dpm.c      |   36 +-
>  drivers/gpu/drm/radeon/btc_dpm.h      |   20 +-
>  drivers/gpu/drm/radeon/cypress_dpm.c  |   11 +-
>  drivers/gpu/drm/radeon/cypress_dpm.h  |    4 +
>  drivers/gpu/drm/radeon/ni.c           |    4 +-
>  drivers/gpu/drm/radeon/ni_dpm.c       | 4093 +++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/radeon/ni_dpm.h       |  233 ++
>  drivers/gpu/drm/radeon/nid.h          |  552 +++++
>  drivers/gpu/drm/radeon/nislands_smc.h |  329 +++
>  drivers/gpu/drm/radeon/ppsmc.h        |   12 +
>  drivers/gpu/drm/radeon/radeon_asic.c  |   12 +
>  drivers/gpu/drm/radeon/radeon_asic.h  |   10 +
>  drivers/gpu/drm/radeon/radeon_pm.c    |    1 +
>  drivers/gpu/drm/radeon/radeon_ucode.h |    5 +
>  drivers/gpu/drm/radeon/rv770_smc.c    |   27 +
>  16 files changed, 5323 insertions(+), 28 deletions(-)
>  create mode 100644 drivers/gpu/drm/radeon/ni_dpm.c
>  create mode 100644 drivers/gpu/drm/radeon/ni_dpm.h
>  create mode 100644 drivers/gpu/drm/radeon/nislands_smc.h
> 
> diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
> index 2239ec2..32d1c7f 100644
> --- a/drivers/gpu/drm/radeon/Makefile
> +++ b/drivers/gpu/drm/radeon/Makefile
> @@ -79,7 +79,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \
>  	si_blit_shaders.o radeon_prime.o radeon_uvd.o cik.o cik_blit_shaders.o \
>  	r600_dpm.o rs780_dpm.o rv6xx_dpm.o rv770_dpm.o rv730_dpm.o rv740_dpm.o \
>  	rv770_smc.o cypress_dpm.o btc_dpm.o sumo_dpm.o sumo_smc.o trinity_dpm.o \
> -	trinity_smc.o
> +	trinity_smc.o ni_dpm.o
>  
>  radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
>  radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o
> diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c
> index 989592e..79f5ed4 100644
> --- a/drivers/gpu/drm/radeon/btc_dpm.c
> +++ b/drivers/gpu/drm/radeon/btc_dpm.c
> @@ -1152,7 +1152,7 @@ static const u32 turks_sysls_enable[] =
>  
>  #endif
>  
> -u32 btc_valid_sclk[] =
> +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,
> @@ -1168,8 +1168,8 @@ static const struct radeon_blacklist_clocks btc_blacklist_clocks[] =
>          { 25000, 30000, RADEON_SCLK_UP }
>  };
>  
> -static void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
> -					       u32 clock, u16 max_voltage, u16 *voltage)
> +void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
> +					u32 clock, u16 max_voltage, u16 *voltage)
>  {
>  	u32 i;
>  
> @@ -1219,9 +1219,9 @@ static u32 btc_get_valid_sclk(struct radeon_device *rdev,
>  				    max_sclk, requested_sclk);
>  }
>  
> -static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
> -				      const u32 max_sclk, const u32 max_mclk,
> -				      u32 *sclk, u32 *mclk)
> +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;
>  
> @@ -1246,9 +1246,9 @@ static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
>  	}
>  }
>  
> -static void btc_adjust_clock_combinations(struct radeon_device *rdev,
> -					  const struct radeon_clock_and_voltage_limits *max_limits,
> -					  struct rv7xx_pl *pl)
> +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))
> @@ -1285,9 +1285,9 @@ static u16 btc_find_voltage(struct atom_voltage_table *table, u16 voltage)
>  	return table->entries[table->count - 1].value;
>  }
>  
> -static void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
> -					  u16 max_vddc, u16 max_vddci,
> -					  u16 *vddc, u16 *vddci)
> +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;
> @@ -1417,8 +1417,8 @@ static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
>  	return ret;
>  }
>  
> -static void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
> -					 const u32 *sequence, u32 count)
> +void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
> +				  const u32 *sequence, u32 count)
>  {
>  	u32 i, length = count * 3;
>  	u32 tmp;
> @@ -1596,7 +1596,7 @@ static void btc_ls_clock_gating_enable(struct radeon_device *rdev,
>  	btc_program_mgcg_hw_sequence(rdev, p, count);
>  }
>  
> -static bool btc_dpm_enabled(struct radeon_device *rdev)
> +bool btc_dpm_enabled(struct radeon_device *rdev)
>  {
>  	if (rv770_is_smc_running(rdev))
>  		return true;
> @@ -1692,7 +1692,7 @@ static void btc_set_at_for_uvd(struct radeon_device *rdev)
>  
>  }
>  
> -static void btc_notify_uvd_to_smc(struct radeon_device *rdev)
> +void btc_notify_uvd_to_smc(struct radeon_device *rdev)
>  {
>  	struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
>  	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> @@ -1708,7 +1708,7 @@ static void btc_notify_uvd_to_smc(struct radeon_device *rdev)
>  	}
>  }
>  
> -static int btc_reset_to_default(struct radeon_device *rdev)
> +int btc_reset_to_default(struct radeon_device *rdev)
>  {
>  	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_ResetToDefaults) != PPSMC_Result_OK)
>  		return -EINVAL;
> @@ -1730,7 +1730,7 @@ static void btc_stop_smc(struct radeon_device *rdev)
>  	r7xx_stop_smc(rdev);
>  }
>  
> -static void btc_read_arb_registers(struct radeon_device *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 =
> diff --git a/drivers/gpu/drm/radeon/btc_dpm.h b/drivers/gpu/drm/radeon/btc_dpm.h
> index 807024d..c22d39f 100644
> --- a/drivers/gpu/drm/radeon/btc_dpm.h
> +++ b/drivers/gpu/drm/radeon/btc_dpm.h
> @@ -33,6 +33,24 @@
>  #define BTC_CGULVPARAMETER_DFLT                       0x00040035
>  #define BTC_CGULVCONTROL_DFLT                         0x00001450
>  
> -extern u32 btc_valid_sclk[];
> +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);
>  
>  #endif
> diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c
> index 403ee15..22297b1 100644
> --- a/drivers/gpu/drm/radeon/cypress_dpm.c
> +++ b/drivers/gpu/drm/radeon/cypress_dpm.c
> @@ -45,9 +45,6 @@ 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);
>  
> -static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
> -					   u32 memory_clock, bool strobe_mode);
> -
>  static void cypress_enable_bif_dynamic_pcie_gen2(struct radeon_device *rdev,
>  						 bool enable)
>  {
> @@ -416,7 +413,7 @@ static int cypress_populate_voltage_value(struct radeon_device *rdev,
>  	return 0;
>  }
>  
> -static u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
> +u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
>  {
>  	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
>  	u8 result = 0;
> @@ -434,7 +431,7 @@ static u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk)
>  	return result;
>  }
>  
> -static u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf)
> +u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf)
>  {
>  	u32 ref_clk = rdev->clock.mpll.reference_freq;
>  	u32 vco = clkf * ref_clk;
> @@ -603,8 +600,8 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev,
>  	return 0;
>  }
>  
> -static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
> -					   u32 memory_clock, bool strobe_mode)
> +u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
> +				    u32 memory_clock, bool strobe_mode)
>  {
>  	u8 mc_para_index;
>  
> diff --git a/drivers/gpu/drm/radeon/cypress_dpm.h b/drivers/gpu/drm/radeon/cypress_dpm.h
> index 9e24d7a..9b6198e 100644
> --- a/drivers/gpu/drm/radeon/cypress_dpm.h
> +++ b/drivers/gpu/drm/radeon/cypress_dpm.h
> @@ -141,5 +141,9 @@ void cypress_enable_mclk_control(struct radeon_device *rdev,
>  				 bool enable);
>  void cypress_start_dpm(struct radeon_device *rdev);
>  void cypress_advertise_gen2_capability(struct radeon_device *rdev);
> +u32 cypress_map_clkf_to_ibias(struct radeon_device *rdev, u32 clkf);
> +u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
> +				    u32 memory_clock, bool strobe_mode);
> +u8 cypress_get_strobe_mode_settings(struct radeon_device *rdev, u32 mclk);
>  
>  #endif
> diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
> index 7407762..ad65143 100644
> --- a/drivers/gpu/drm/radeon/ni.c
> +++ b/drivers/gpu/drm/radeon/ni.c
> @@ -194,6 +194,7 @@ MODULE_FIRMWARE("radeon/CAYMAN_pfp.bin");
>  MODULE_FIRMWARE("radeon/CAYMAN_me.bin");
>  MODULE_FIRMWARE("radeon/CAYMAN_mc.bin");
>  MODULE_FIRMWARE("radeon/CAYMAN_rlc.bin");
> +MODULE_FIRMWARE("radeon/CAYMAN_smc.bin");
>  MODULE_FIRMWARE("radeon/ARUBA_pfp.bin");
>  MODULE_FIRMWARE("radeon/ARUBA_me.bin");
>  MODULE_FIRMWARE("radeon/ARUBA_rlc.bin");
> @@ -734,6 +735,7 @@ int ni_init_microcode(struct radeon_device *rdev)
>  		me_req_size = CAYMAN_PM4_UCODE_SIZE * 4;
>  		rlc_req_size = CAYMAN_RLC_UCODE_SIZE * 4;
>  		mc_req_size = CAYMAN_MC_UCODE_SIZE * 4;
> +		smc_req_size = ALIGN(CAYMAN_SMC_UCODE_SIZE, 4);
>  		break;
>  	case CHIP_ARUBA:
>  		chip_name = "ARUBA";
> @@ -797,7 +799,7 @@ int ni_init_microcode(struct radeon_device *rdev)
>  		}
>  	}
>  
> -	if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAICOS)) {
> +	if ((rdev->family >= CHIP_BARTS) && (rdev->family <= CHIP_CAYMAN)) {
>  		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
>  		err = request_firmware(&rdev->smc_fw, fw_name, &pdev->dev);
>  		if (err)
> diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c
> new file mode 100644
> index 0000000..635bf04
> --- /dev/null
> +++ b/drivers/gpu/drm/radeon/ni_dpm.c
> @@ -0,0 +1,4093 @@
> +/*
> + * 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.
> + *
> + */
> +
> +#include "drmP.h"
> +#include "radeon.h"
> +#include "nid.h"
> +#include "r600_dpm.h"
> +#include "ni_dpm.h"
> +#include "atom.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 SMC_RAM_END 0xC000
> +
> +static const struct ni_cac_weights cac_weights_cayman_xt =
> +{
> +	0x15,
> +	0x2,
> +	0x19,
> +	0x2,
> +	0x8,
> +	0x14,
> +	0x2,
> +	0x16,
> +	0xE,
> +	0x17,
> +	0x13,
> +	0x2B,
> +	0x10,
> +	0x7,
> +	0x5,
> +	0x5,
> +	0x5,
> +	0x2,
> +	0x3,
> +	0x9,
> +	0x10,
> +	0x10,
> +	0x2B,
> +	0xA,
> +	0x9,
> +	0x4,
> +	0xD,
> +	0xD,
> +	0x3E,
> +	0x18,
> +	0x14,
> +	0,
> +	0x3,
> +	0x3,
> +	0x5,
> +	0,
> +	0x2,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0x1CC,
> +	0,
> +	0x164,
> +	1,
> +	1,
> +	1,
> +	1,
> +	12,
> +	12,
> +	12,
> +	0x12,
> +	0x1F,
> +	132,
> +	5,
> +	7,
> +	0,
> +	{ 0, 0, 0, 0, 0, 0, 0, 0 },
> +	{ 0, 0, 0, 0 },
> +	true
> +};
> +
> +static const struct ni_cac_weights cac_weights_cayman_pro =
> +{
> +	0x16,
> +	0x4,
> +	0x10,
> +	0x2,
> +	0xA,
> +	0x16,
> +	0x2,
> +	0x18,
> +	0x10,
> +	0x1A,
> +	0x16,
> +	0x2D,
> +	0x12,
> +	0xA,
> +	0x6,
> +	0x6,
> +	0x6,
> +	0x2,
> +	0x4,
> +	0xB,
> +	0x11,
> +	0x11,
> +	0x2D,
> +	0xC,
> +	0xC,
> +	0x7,
> +	0x10,
> +	0x10,
> +	0x3F,
> +	0x1A,
> +	0x16,
> +	0,
> +	0x7,
> +	0x4,
> +	0x6,
> +	1,
> +	0x2,
> +	0x1,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0x30,
> +	0,
> +	0x1CF,
> +	0,
> +	0x166,
> +	1,
> +	1,
> +	1,
> +	1,
> +	12,
> +	12,
> +	12,
> +	0x15,
> +	0x1F,
> +	132,
> +	6,
> +	6,
> +	0,
> +	{ 0, 0, 0, 0, 0, 0, 0, 0 },
> +	{ 0, 0, 0, 0 },
> +	true
> +};
> +
> +static const struct ni_cac_weights cac_weights_cayman_le =
> +{
> +	0x7,
> +	0xE,
> +	0x1,
> +	0xA,
> +	0x1,
> +	0x3F,
> +	0x2,
> +	0x18,
> +	0x10,
> +	0x1A,
> +	0x1,
> +	0x3F,
> +	0x1,
> +	0xE,
> +	0x6,
> +	0x6,
> +	0x6,
> +	0x2,
> +	0x4,
> +	0x9,
> +	0x1A,
> +	0x1A,
> +	0x2C,
> +	0xA,
> +	0x11,
> +	0x8,
> +	0x19,
> +	0x19,
> +	0x1,
> +	0x1,
> +	0x1A,
> +	0,
> +	0x8,
> +	0x5,
> +	0x8,
> +	0x1,
> +	0x3,
> +	0x1,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0,
> +	0x38,
> +	0x38,
> +	0x239,
> +	0x3,
> +	0x18A,
> +	1,
> +	1,
> +	1,
> +	1,
> +	12,
> +	12,
> +	12,
> +	0x15,
> +	0x22,
> +	132,
> +	6,
> +	6,
> +	0,
> +	{ 0, 0, 0, 0, 0, 0, 0, 0 },
> +	{ 0, 0, 0, 0 },
> +	true
> +};
> +
> +#define NISLANDS_MGCG_SEQUENCE  300
> +
> +static const u32 cayman_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 CAYMAN_CGCG_CGLS_DEFAULT_LENGTH sizeof(cayman_cgcg_cgls_default) / (3 * sizeof(u32))
> +
> +static const u32 cayman_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, 0x000f7902, 0x001f4180,
> +	0x00000644, 0x000f3802, 0x001f4180
> +};
> +#define CAYMAN_CGCG_CGLS_DISABLE_LENGTH sizeof(cayman_cgcg_cgls_disable) / (3 * sizeof(u32))
> +
> +static const u32 cayman_cgcg_cgls_enable[] =
> +{
> +	0x00000644, 0x000f7882, 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 CAYMAN_CGCG_CGLS_ENABLE_LENGTH  sizeof(cayman_cgcg_cgls_enable) / (3 * sizeof(u32))
> +
> +static const u32 cayman_mgcg_default[] =
> +{
> +	0x0000802c, 0xc0000000, 0xffffffff,
> +	0x00003fc4, 0xc0000000, 0xffffffff,
> +	0x00005448, 0x00000100, 0xffffffff,
> +	0x000055e4, 0x00000100, 0xffffffff,
> +	0x0000160c, 0x00000100, 0xffffffff,
> +	0x00008984, 0x06000100, 0xffffffff,
> +	0x0000c164, 0x00000100, 0xffffffff,
> +	0x00008a18, 0x00000100, 0xffffffff,
> +	0x0000897c, 0x06000100, 0xffffffff,
> +	0x00008b28, 0x00000100, 0xffffffff,
> +	0x00009144, 0x00800200, 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,
> +	0x00009744, 0x00000100, 0xffffffff,
> +	0x00003f80, 0x00000100, 0xffffffff,
> +	0x0000a210, 0x00000100, 0xffffffff,
> +	0x0000a214, 0x00000100, 0xffffffff,
> +	0x000004d8, 0x00000100, 0xffffffff,
> +	0x00009664, 0x00000100, 0xffffffff,
> +	0x00009698, 0x00000100, 0xffffffff,
> +	0x000004d4, 0x00000200, 0xffffffff,
> +	0x000004d0, 0x00000000, 0xffffffff,
> +	0x000030cc, 0x00000104, 0xffffffff,
> +	0x0000d0c0, 0x00000100, 0xffffffff,
> +	0x0000d8c0, 0x00000100, 0xffffffff,
> +	0x0000802c, 0x40000000, 0xffffffff,
> +	0x00003fc4, 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,
> +	0x00009240, 0x00070000, 0xffffffff,
> +	0x00009244, 0x00030002, 0xffffffff,
> +	0x00009248, 0x00050004, 0xffffffff,
> +	0x00009254, 0x00010006, 0xffffffff,
> +	0x00009258, 0x00090008, 0xffffffff,
> +	0x0000925c, 0x00070000, 0xffffffff,
> +	0x00009260, 0x00030002, 0xffffffff,
> +	0x00009264, 0x00050004, 0xffffffff,
> +	0x00009270, 0x00010006, 0xffffffff,
> +	0x00009274, 0x00090008, 0xffffffff,
> +	0x00009278, 0x00070000, 0xffffffff,
> +	0x0000927c, 0x00030002, 0xffffffff,
> +	0x00009280, 0x00050004, 0xffffffff,
> +	0x0000928c, 0x00010006, 0xffffffff,
> +	0x00009290, 0x00090008, 0xffffffff,
> +	0x000092a8, 0x00070000, 0xffffffff,
> +	0x000092ac, 0x00030002, 0xffffffff,
> +	0x000092b0, 0x00050004, 0xffffffff,
> +	0x000092bc, 0x00010006, 0xffffffff,
> +	0x000092c0, 0x00090008, 0xffffffff,
> +	0x000092c4, 0x00070000, 0xffffffff,
> +	0x000092c8, 0x00030002, 0xffffffff,
> +	0x000092cc, 0x00050004, 0xffffffff,
> +	0x000092d8, 0x00010006, 0xffffffff,
> +	0x000092dc, 0x00090008, 0xffffffff,
> +	0x00009294, 0x00000000, 0xffffffff,
> +	0x0000802c, 0x40010000, 0xffffffff,
> +	0x00003fc4, 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,
> +	0x00009240, 0x00070000, 0xffffffff,
> +	0x00009244, 0x00030002, 0xffffffff,
> +	0x00009248, 0x00050004, 0xffffffff,
> +	0x00009254, 0x00010006, 0xffffffff,
> +	0x00009258, 0x00090008, 0xffffffff,
> +	0x0000925c, 0x00070000, 0xffffffff,
> +	0x00009260, 0x00030002, 0xffffffff,
> +	0x00009264, 0x00050004, 0xffffffff,
> +	0x00009270, 0x00010006, 0xffffffff,
> +	0x00009274, 0x00090008, 0xffffffff,
> +	0x00009278, 0x00070000, 0xffffffff,
> +	0x0000927c, 0x00030002, 0xffffffff,
> +	0x00009280, 0x00050004, 0xffffffff,
> +	0x0000928c, 0x00010006, 0xffffffff,
> +	0x00009290, 0x00090008, 0xffffffff,
> +	0x000092a8, 0x00070000, 0xffffffff,
> +	0x000092ac, 0x00030002, 0xffffffff,
> +	0x000092b0, 0x00050004, 0xffffffff,
> +	0x000092bc, 0x00010006, 0xffffffff,
> +	0x000092c0, 0x00090008, 0xffffffff,
> +	0x000092c4, 0x00070000, 0xffffffff,
> +	0x000092c8, 0x00030002, 0xffffffff,
> +	0x000092cc, 0x00050004, 0xffffffff,
> +	0x000092d8, 0x00010006, 0xffffffff,
> +	0x000092dc, 0x00090008, 0xffffffff,
> +	0x00009294, 0x00000000, 0xffffffff,
> +	0x0000802c, 0xc0000000, 0xffffffff,
> +	0x00003fc4, 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 CAYMAN_MGCG_DEFAULT_LENGTH sizeof(cayman_mgcg_default) / (3 * sizeof(u32))
> +
> +static const u32 cayman_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 CAYMAN_MGCG_DISABLE_LENGTH   sizeof(cayman_mgcg_disable) / (3 * sizeof(u32))
> +
> +static const u32 cayman_mgcg_enable[] =
> +{
> +	0x0000802c, 0xc0000000, 0xffffffff,
> +	0x000008f8, 0x00000000, 0xffffffff,
> +	0x000008fc, 0x00000000, 0xffffffff,
> +	0x000008f8, 0x00000001, 0xffffffff,
> +	0x000008fc, 0x00000000, 0xffffffff,
> +	0x000008f8, 0x00000002, 0xffffffff,
> +	0x000008fc, 0x00600000, 0xffffffff,
> +	0x000008f8, 0x00000003, 0xffffffff,
> +	0x000008fc, 0x00000000, 0xffffffff,
> +	0x00009150, 0x96944200, 0xffffffff
> +};
> +
> +#define CAYMAN_MGCG_ENABLE_LENGTH   sizeof(cayman_mgcg_enable) / (3 * sizeof(u32))
> +
> +#define NISLANDS_SYSLS_SEQUENCE  100
> +
> +static const u32 cayman_sysls_default[] =
> +{
> +	/* Register,   Value,     Mask bits */
> +	0x000055e8, 0x00000000, 0xffffffff,
> +	0x0000d0bc, 0x00000000, 0xffffffff,
> +	0x0000d8bc, 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,
> +	0x00002f50, 0x00000404, 0xffffffff,
> +	0x000004c8, 0x00000001, 0xffffffff,
> +	0x000064ec, 0x00000000, 0xffffffff,
> +	0x00000c7c, 0x00000000, 0xffffffff,
> +	0x00008dfc, 0x00000000, 0xffffffff
> +};
> +#define CAYMAN_SYSLS_DEFAULT_LENGTH sizeof(cayman_sysls_default) / (3 * sizeof(u32))
> +
> +static const u32 cayman_sysls_disable[] =
> +{
> +	/* Register,   Value,     Mask bits */
> +	0x0000d0c0, 0x00000000, 0xffffffff,
> +	0x0000d8c0, 0x00000000, 0xffffffff,
> +	0x000055e8, 0x00000000, 0xffffffff,
> +	0x0000d0bc, 0x00000000, 0xffffffff,
> +	0x0000d8bc, 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,
> +	0x00002f50, 0x00000404, 0xffffffff,
> +	0x000004c8, 0x00000001, 0xffffffff,
> +	0x000064ec, 0x00007ffd, 0xffffffff,
> +	0x00000c7c, 0x0000ff00, 0xffffffff,
> +	0x00008dfc, 0x0000007f, 0xffffffff
> +};
> +#define CAYMAN_SYSLS_DISABLE_LENGTH sizeof(cayman_sysls_disable) / (3 * sizeof(u32))
> +
> +static const u32 cayman_sysls_enable[] =
> +{
> +	/* Register,   Value,     Mask bits */
> +	0x000055e8, 0x00000001, 0xffffffff,
> +	0x0000d0bc, 0x00000100, 0xffffffff,
> +	0x0000d8bc, 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,
> +	0x00002f50, 0x00000903, 0xffffffff,
> +	0x000004c8, 0x00000000, 0xffffffff,
> +	0x000064ec, 0x00000000, 0xffffffff,
> +	0x00000c7c, 0x00000000, 0xffffffff,
> +	0x00008dfc, 0x00000000, 0xffffffff
> +};
> +#define CAYMAN_SYSLS_ENABLE_LENGTH sizeof(cayman_sysls_enable) / (3 * sizeof(u32))
> +
> +struct rv7xx_power_info *rv770_get_pi(struct radeon_device *rdev);
> +struct evergreen_power_info *evergreen_get_pi(struct radeon_device *rdev);
> +
> +static struct ni_power_info *ni_get_pi(struct radeon_device *rdev)
> +{
> +        struct ni_power_info *pi = rdev->pm.dpm.priv;
> +
> +        return pi;
> +}
> +
> +struct ni_ps *ni_get_ps(struct radeon_ps *rps)
> +{
> +	struct ni_ps *ps = rps->ps_priv;
> +
> +	return ps;
> +}
> +
> +/* XXX: fix for kernel use  */
> +#if 0
> +static double ni_exp(double x)
> +{
> +	int count = 1;
> +	double sum = 1.0, term, tolerance = 0.000000001, y = x;
> +
> +	if (x < 0)
> +		y = -1 * x;
> +	term  = y;
> +
> +	while (term >= tolerance) {
> +		sum = sum + term;
> +		count = count + 1;
> +		term  = term * (y / count);
> +	}
> +
> +	if (x < 0)
> +		sum = 1.0 / sum;
> +
> +	return sum;
> +}
> +#endif
> +
> +static void ni_calculate_leakage_for_v_and_t_formula(const struct ni_leakage_coeffients *coeff,
> +						     u16 v, s32 t,
> +						     u32 ileakage,
> +						     u32 *leakage)
> +{
> +/* XXX: fix for kernel use  */
> +#if 0
> +	double kt, kv, leakage_w, i_leakage, vddc, temperature;
> +
> +	i_leakage   = ((double)ileakage) / 1000;
> +	vddc        = ((double)v) / 1000;
> +	temperature = ((double)t) / 1000;
> +
> +	kt = (((double)(coeff->at)) / 1000) * ni_exp((((double)(coeff->bt)) / 1000) * temperature);
> +	kv = (((double)(coeff->av)) / 1000) * ni_exp((((double)(coeff->bv)) / 1000) * vddc);
> +
> +	leakage_w = i_leakage * kt * kv * vddc;
> +
> +	*leakage = (u32)(leakage_w * 1000);
> +#endif
> +}
> +
> +static void ni_calculate_leakage_for_v_and_t(struct radeon_device *rdev,
> +					     const struct ni_leakage_coeffients *coeff,
> +					     u16 v,
> +					     s32 t,
> +					     u32 i_leakage,
> +					     u32 *leakage)
> +{
> +	ni_calculate_leakage_for_v_and_t_formula(coeff, v, t, i_leakage, leakage);
> +}
> +
> +static void ni_apply_state_adjust_rules(struct radeon_device *rdev)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	struct radeon_ps *rps = rdev->pm.dpm.requested_ps;
> +	struct ni_ps *ps = ni_get_ps(rps);
> +	struct radeon_clock_and_voltage_limits *max_limits;
> +	bool disable_mclk_switching;
> +	u32 mclk, sclk;
> +	u16 vddc, vddci;
> +	int i;
> +
> +	/* point to the hw copy since this function will modify the ps */
> +	ni_pi->hw_ps = *ps;
> +	rdev->pm.dpm.hw_ps.ps_priv = &ni_pi->hw_ps;
> +	ps = &ni_pi->hw_ps;
> +
> +	if (rdev->pm.dpm.new_active_crtc_count > 1)
> +		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) {
> +		for (i = 0; i < ps->performance_level_count; i++) {
> +			if (ps->performance_levels[i].mclk > max_limits->mclk)
> +				ps->performance_levels[i].mclk = max_limits->mclk;
> +			if (ps->performance_levels[i].sclk > max_limits->sclk)
> +				ps->performance_levels[i].sclk = max_limits->sclk;
> +			if (ps->performance_levels[i].vddc > max_limits->vddc)
> +				ps->performance_levels[i].vddc = max_limits->vddc;
> +			if (ps->performance_levels[i].vddci > max_limits->vddci)
> +				ps->performance_levels[i].vddci = max_limits->vddci;
> +		}
> +	}
> +
> +	/* XXX validate the min clocks required for display */
> +
> +	if (disable_mclk_switching) {
> +		mclk  = ps->performance_levels[ps->performance_level_count - 1].mclk;
> +		sclk = ps->performance_levels[0].sclk;
> +		vddc = ps->performance_levels[0].vddc;
> +		vddci = ps->performance_levels[ps->performance_level_count - 1].vddci;
> +	} else {
> +		sclk = ps->performance_levels[0].sclk;
> +		mclk = ps->performance_levels[0].mclk;
> +		vddc = ps->performance_levels[0].vddc;
> +		vddci = ps->performance_levels[0].vddci;
> +	}
> +
> +	/* adjusted low state */
> +	ps->performance_levels[0].sclk = sclk;
> +	ps->performance_levels[0].mclk = mclk;
> +	ps->performance_levels[0].vddc = vddc;
> +	ps->performance_levels[0].vddci = vddci;
> +
> +	btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
> +				  &ps->performance_levels[0].sclk,
> +				  &ps->performance_levels[0].mclk);
> +
> +	for (i = 1; i < ps->performance_level_count; i++) {
> +		if (ps->performance_levels[i].sclk < ps->performance_levels[i - 1].sclk)
> +			ps->performance_levels[i].sclk = ps->performance_levels[i - 1].sclk;
> +		if (ps->performance_levels[i].vddc < ps->performance_levels[i - 1].vddc)
> +			ps->performance_levels[i].vddc = ps->performance_levels[i - 1].vddc;
> +	}
> +
> +	if (disable_mclk_switching) {
> +		mclk = ps->performance_levels[0].mclk;
> +		for (i = 1; i < ps->performance_level_count; i++) {
> +			if (mclk < ps->performance_levels[i].mclk)
> +				mclk = ps->performance_levels[i].mclk;
> +		}
> +		for (i = 0; i < ps->performance_level_count; i++) {
> +			ps->performance_levels[i].mclk = mclk;
> +			ps->performance_levels[i].vddci = vddci;
> +		}
> +	} else {
> +		for (i = 1; i < ps->performance_level_count; i++) {
> +			if (ps->performance_levels[i].mclk < ps->performance_levels[i - 1].mclk)
> +				ps->performance_levels[i].mclk = ps->performance_levels[i - 1].mclk;
> +			if (ps->performance_levels[i].vddci < ps->performance_levels[i - 1].vddci)
> +				ps->performance_levels[i].vddci = ps->performance_levels[i - 1].vddci;
> +		}
> +	}
> +
> +	for (i = 1; i < ps->performance_level_count; i++)
> +		btc_skip_blacklist_clocks(rdev, max_limits->sclk, max_limits->mclk,
> +					  &ps->performance_levels[i].sclk,
> +					  &ps->performance_levels[i].mclk);
> +
> +	for (i = 0; i < ps->performance_level_count; i++)
> +		btc_adjust_clock_combinations(rdev, max_limits,
> +					      &ps->performance_levels[i]);
> +
> +	for (i = 0; i < ps->performance_level_count; i++) {
> +		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk,
> +						   ps->performance_levels[i].sclk,
> +						   max_limits->vddc,  &ps->performance_levels[i].vddc);
> +		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddci_dependency_on_mclk,
> +						   ps->performance_levels[i].mclk,
> +						   max_limits->vddci, &ps->performance_levels[i].vddci);
> +		btc_apply_voltage_dependency_rules(&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk,
> +						   ps->performance_levels[i].mclk,
> +						   max_limits->vddc,  &ps->performance_levels[i].vddc);
> +		/* XXX validate the voltage required for display */
> +	}
> +
> +	for (i = 0; i < ps->performance_level_count; i++) {
> +		btc_apply_voltage_delta_rules(rdev,
> +					      max_limits->vddc, max_limits->vddci,
> +					      &ps->performance_levels[i].vddc,
> +					      &ps->performance_levels[i].vddci);
> +	}
> +
> +	ps->dc_compatible = true;
> +	for (i = 0; i < ps->performance_level_count; i++) {
> +		if (ps->performance_levels[i].vddc > rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.vddc)
> +			ps->dc_compatible = false;
> +
> +		if (ps->performance_levels[i].vddc < rdev->pm.dpm.dyn_state.min_vddc_for_pcie_gen2)
> +			ps->performance_levels[i].flags &= ~ATOM_PPLIB_R600_FLAGS_PCIEGEN2;
> +	}
> +}
> +
> +static void ni_cg_clockgating_default(struct radeon_device *rdev)
> +{
> +	u32 count;
> +	const u32 *ps = NULL;
> +
> +	ps = (const u32 *)&cayman_cgcg_cgls_default;
> +	count = CAYMAN_CGCG_CGLS_DEFAULT_LENGTH;
> +
> +	btc_program_mgcg_hw_sequence(rdev, ps, count);
> +}
> +
> +static void ni_gfx_clockgating_enable(struct radeon_device *rdev,
> +				      bool enable)
> +{
> +	u32 count;
> +	const u32 *ps = NULL;
> +
> +	if (enable) {
> +		ps = (const u32 *)&cayman_cgcg_cgls_enable;
> +		count = CAYMAN_CGCG_CGLS_ENABLE_LENGTH;
> +	} else {
> +		ps = (const u32 *)&cayman_cgcg_cgls_disable;
> +		count = CAYMAN_CGCG_CGLS_DISABLE_LENGTH;
> +	}
> +
> +	btc_program_mgcg_hw_sequence(rdev, ps, count);
> +}
> +
> +static void ni_mg_clockgating_default(struct radeon_device *rdev)
> +{
> +	u32 count;
> +	const u32 *ps = NULL;
> +
> +	ps = (const u32 *)&cayman_mgcg_default;
> +	count = CAYMAN_MGCG_DEFAULT_LENGTH;
> +
> +	btc_program_mgcg_hw_sequence(rdev, ps, count);
> +}
> +
> +static void ni_mg_clockgating_enable(struct radeon_device *rdev,
> +				     bool enable)
> +{
> +	u32 count;
> +	const u32 *ps = NULL;
> +
> +	if (enable) {
> +		ps = (const u32 *)&cayman_mgcg_enable;
> +		count = CAYMAN_MGCG_ENABLE_LENGTH;
> +	} else {
> +		ps = (const u32 *)&cayman_mgcg_disable;
> +		count = CAYMAN_MGCG_DISABLE_LENGTH;
> +	}
> +
> +	btc_program_mgcg_hw_sequence(rdev, ps, count);
> +}
> +
> +static void ni_ls_clockgating_default(struct radeon_device *rdev)
> +{
> +	u32 count;
> +	const u32 *ps = NULL;
> +
> +	ps = (const u32 *)&cayman_sysls_default;
> +	count = CAYMAN_SYSLS_DEFAULT_LENGTH;
> +
> +	btc_program_mgcg_hw_sequence(rdev, ps, count);
> +}
> +
> +static void ni_ls_clockgating_enable(struct radeon_device *rdev,
> +				     bool enable)
> +{
> +	u32 count;
> +	const u32 *ps = NULL;
> +
> +	if (enable) {
> +		ps = (const u32 *)&cayman_sysls_enable;
> +		count = CAYMAN_SYSLS_ENABLE_LENGTH;
> +	} else {
> +		ps = (const u32 *)&cayman_sysls_disable;
> +		count = CAYMAN_SYSLS_DISABLE_LENGTH;
> +	}
> +
> +	btc_program_mgcg_hw_sequence(rdev, ps, count);
> +
> +}
> +
> +static int ni_patch_single_dependency_table_based_on_leakage(struct radeon_device *rdev,
> +							     struct radeon_clock_voltage_dependency_table *table)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	u32 i;
> +
> +	if (table) {
> +		for (i = 0; i < table->count; i++) {
> +			if (0xff01 == table->entries[i].v) {
> +				if (pi->max_vddc == 0)
> +					return -EINVAL;
> +				table->entries[i].v = pi->max_vddc;
> +			}
> +		}
> +	}
> +	return 0;
> +}
> +
> +static int ni_patch_dependency_tables_based_on_leakage(struct radeon_device *rdev)
> +{
> +	int ret = 0;
> +
> +	ret = ni_patch_single_dependency_table_based_on_leakage(rdev,
> +								&rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk);
> +
> +	ret = ni_patch_single_dependency_table_based_on_leakage(rdev,
> +								&rdev->pm.dpm.dyn_state.vddc_dependency_on_mclk);
> +	return ret;
> +}
> +
> +static void ni_stop_dpm(struct radeon_device *rdev)
> +{
> +	WREG32_P(GENERAL_PWRMGT, 0, ~GLOBAL_PWRMGT_EN);
> +}
> +
> +#if 0
> +static int ni_notify_hw_of_power_source(struct radeon_device *rdev,
> +					bool ac_power)
> +{
> +	if (ac_power)
> +		return (rv770_send_msg_to_smc(rdev, PPSMC_MSG_RunningOnAC) == PPSMC_Result_OK) ?
> +			0 : -EINVAL;
> +
> +	return 0;
> +}
> +#endif
> +
> +static PPSMC_Result ni_send_msg_to_smc_with_parameter(struct radeon_device *rdev,
> +						      PPSMC_Msg msg, u32 parameter)
> +{
> +	WREG32(SMC_SCRATCH0, parameter);
> +	return rv770_send_msg_to_smc(rdev, msg);
> +}
> +
> +static int ni_restrict_performance_levels_before_switch(struct radeon_device *rdev)
> +{
> +	if (rv770_send_msg_to_smc(rdev, PPSMC_MSG_NoForcedLevel) != PPSMC_Result_OK)
> +		return -EINVAL;
> +
> +	return (ni_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_SetEnabledLevels, 1) == PPSMC_Result_OK) ?
> +		0 : -EINVAL;
> +}
> +
> +static void ni_stop_smc(struct radeon_device *rdev)
> +{
> +	u32 tmp;
> +	int i;
> +
> +	for (i = 0; i < rdev->usec_timeout; i++) {
> +		tmp = RREG32(LB_SYNC_RESET_SEL) & LB_SYNC_RESET_SEL_MASK;
> +		if (tmp != 1)
> +			break;
> +		udelay(1);
> +	}
> +
> +	udelay(100);
> +
> +	r7xx_stop_smc(rdev);
> +}
> +
> +static int ni_process_firmware_header(struct radeon_device *rdev)
> +{
> +        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +        struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 tmp;
> +	int ret;
> +
> +	ret = rv770_read_smc_sram_dword(rdev,
> +					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
> +					NISLANDS_SMC_FIRMWARE_HEADER_stateTable,
> +					&tmp, pi->sram_end);
> +
> +	if (ret)
> +		return ret;
> +
> +	pi->state_table_start = (u16)tmp;
> +
> +	ret = rv770_read_smc_sram_dword(rdev,
> +					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
> +					NISLANDS_SMC_FIRMWARE_HEADER_softRegisters,
> +					&tmp, pi->sram_end);
> +
> +	if (ret)
> +		return ret;
> +
> +	pi->soft_regs_start = (u16)tmp;
> +
> +	ret = rv770_read_smc_sram_dword(rdev,
> +					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
> +					NISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable,
> +					&tmp, pi->sram_end);
> +
> +	if (ret)
> +		return ret;
> +
> +	eg_pi->mc_reg_table_start = (u16)tmp;
> +
> +	ret = rv770_read_smc_sram_dword(rdev,
> +					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
> +					NISLANDS_SMC_FIRMWARE_HEADER_fanTable,
> +					&tmp, pi->sram_end);
> +
> +	if (ret)
> +		return ret;
> +
> +	ni_pi->fan_table_start = (u16)tmp;
> +
> +	ret = rv770_read_smc_sram_dword(rdev,
> +					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
> +					NISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable,
> +					&tmp, pi->sram_end);
> +
> +	if (ret)
> +		return ret;
> +
> +	ni_pi->arb_table_start = (u16)tmp;
> +
> +	ret = rv770_read_smc_sram_dword(rdev,
> +					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
> +					NISLANDS_SMC_FIRMWARE_HEADER_cacTable,
> +					&tmp, pi->sram_end);
> +
> +	if (ret)
> +		return ret;
> +
> +	ni_pi->cac_table_start = (u16)tmp;
> +
> +	ret = rv770_read_smc_sram_dword(rdev,
> +					NISLANDS_SMC_FIRMWARE_HEADER_LOCATION +
> +					NISLANDS_SMC_FIRMWARE_HEADER_spllTable,
> +					&tmp, pi->sram_end);
> +
> +	if (ret)
> +		return ret;
> +
> +	ni_pi->spll_table_start = (u16)tmp;
> +
> +
> +	return ret;
> +}
> +
> +static void ni_read_clock_registers(struct radeon_device *rdev)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +
> +	ni_pi->clock_registers.cg_spll_func_cntl = RREG32(CG_SPLL_FUNC_CNTL);
> +	ni_pi->clock_registers.cg_spll_func_cntl_2 = RREG32(CG_SPLL_FUNC_CNTL_2);
> +	ni_pi->clock_registers.cg_spll_func_cntl_3 = RREG32(CG_SPLL_FUNC_CNTL_3);
> +	ni_pi->clock_registers.cg_spll_func_cntl_4 = RREG32(CG_SPLL_FUNC_CNTL_4);
> +	ni_pi->clock_registers.cg_spll_spread_spectrum = RREG32(CG_SPLL_SPREAD_SPECTRUM);
> +	ni_pi->clock_registers.cg_spll_spread_spectrum_2 = RREG32(CG_SPLL_SPREAD_SPECTRUM_2);
> +	ni_pi->clock_registers.mpll_ad_func_cntl = RREG32(MPLL_AD_FUNC_CNTL);
> +	ni_pi->clock_registers.mpll_ad_func_cntl_2 = RREG32(MPLL_AD_FUNC_CNTL_2);
> +	ni_pi->clock_registers.mpll_dq_func_cntl = RREG32(MPLL_DQ_FUNC_CNTL);
> +	ni_pi->clock_registers.mpll_dq_func_cntl_2 = RREG32(MPLL_DQ_FUNC_CNTL_2);
> +	ni_pi->clock_registers.mclk_pwrmgt_cntl = RREG32(MCLK_PWRMGT_CNTL);
> +	ni_pi->clock_registers.dll_cntl = RREG32(DLL_CNTL);
> +	ni_pi->clock_registers.mpll_ss1 = RREG32(MPLL_SS1);
> +	ni_pi->clock_registers.mpll_ss2 = RREG32(MPLL_SS2);
> +}
> +
> +#if 0
> +static int ni_enter_ulp_state(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +
> +	if (pi->gfx_clock_gating) {
> +                WREG32_P(SCLK_PWRMGT_CNTL, 0, ~DYN_GFX_CLK_OFF_EN);
> +		WREG32_P(SCLK_PWRMGT_CNTL, GFX_CLK_FORCE_ON, ~GFX_CLK_FORCE_ON);
> +                WREG32_P(SCLK_PWRMGT_CNTL, 0, ~GFX_CLK_FORCE_ON);
> +		RREG32(GB_ADDR_CONFIG);
> +        }
> +
> +	WREG32_P(SMC_MSG, HOST_SMC_MSG(PPSMC_MSG_SwitchToMinimumPower),
> +                 ~HOST_SMC_MSG_MASK);
> +
> +	udelay(25000);
> +
> +	return 0;
> +}
> +#endif
> +
> +static void ni_program_response_times(struct radeon_device *rdev)
> +{
> +	u32 voltage_response_time, backbias_response_time, acpi_delay_time, vbi_time_out;
> +	u32 vddc_dly, bb_dly, acpi_dly, vbi_dly, mclk_switch_limit;
> +	u32 reference_clock;
> +
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mvdd_chg_time, 1);
> +
> +        voltage_response_time = (u32)rdev->pm.dpm.voltage_response_time;
> +        backbias_response_time = (u32)rdev->pm.dpm.backbias_response_time;
> +
> +        if (voltage_response_time == 0)
> +                voltage_response_time = 1000;
> +
> +        if (backbias_response_time == 0)
> +                backbias_response_time = 1000;
> +

^
Broken indentation.

> +	acpi_delay_time = 15000;
> +	vbi_time_out = 100000;
> +
> +	reference_clock = radeon_get_xclk(rdev);
> +
> +	vddc_dly = (voltage_response_time  * reference_clock) / 1600;
> +	bb_dly   = (backbias_response_time * reference_clock) / 1600;
> +	acpi_dly = (acpi_delay_time * reference_clock) / 1600;
> +	vbi_dly  = (vbi_time_out * reference_clock) / 1600;
> +
> +	mclk_switch_limit = (460 * reference_clock) / 100;
> +
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_vreg,  vddc_dly);
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_bbias, bb_dly);
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_delay_acpi,  acpi_dly);
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mclk_chg_timeout, vbi_dly);
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mc_block_delay, 0xAA);
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_mclk_switch_lim, mclk_switch_limit);
> +}
> +
> +static void ni_populate_smc_voltage_table(struct radeon_device *rdev,
> +					  struct atom_voltage_table *voltage_table,
> +					  NISLANDS_SMC_STATETABLE *table)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < voltage_table->count; i++) {
> +		table->highSMIO[i] = 0;
> +		table->lowSMIO[i] |= cpu_to_be32(voltage_table->entries[i].smio_low);
> +	}
> +}
> +
> +static void ni_populate_smc_voltage_tables(struct radeon_device *rdev,
> +					   NISLANDS_SMC_STATETABLE *table)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
^
Broken indentation.

> +	unsigned char i;
> +
> +	if (eg_pi->vddc_voltage_table.count) {
> +		ni_populate_smc_voltage_table(rdev, &eg_pi->vddc_voltage_table, table);
> +		table->voltageMaskTable.highMask[NISLANDS_SMC_VOLTAGEMASK_VDDC] = 0;
> +		table->voltageMaskTable.lowMask[NISLANDS_SMC_VOLTAGEMASK_VDDC] =
> +			cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
> +
> +		for (i = 0; i < eg_pi->vddc_voltage_table.count; i++) {
> +			if (pi->max_vddc_in_table <= eg_pi->vddc_voltage_table.entries[i].value) {
> +				table->maxVDDCIndexInPPTable = i;
> +				break;
> +			}
> +		}
> +	}
> +
> +	if (eg_pi->vddci_voltage_table.count) {
> +		ni_populate_smc_voltage_table(rdev, &eg_pi->vddci_voltage_table, table);
> +
> +		table->voltageMaskTable.highMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] = 0;
> +		table->voltageMaskTable.lowMask[NISLANDS_SMC_VOLTAGEMASK_VDDCI] =
> +			cpu_to_be32(eg_pi->vddc_voltage_table.mask_low);
> +	}
> +}
> +
> +static int ni_populate_voltage_value(struct radeon_device *rdev,
> +				     struct atom_voltage_table *table,
> +				     u16 value,
> +				     NISLANDS_SMC_VOLTAGE_VALUE *voltage)
> +{
> +	unsigned int i;
> +
> +	for (i = 0; i < table->count; i++) {
> +		if (value <= table->entries[i].value) {
> +			voltage->index = (u8)i;
> +			voltage->value = cpu_to_be16(table->entries[i].value);
> +			break;
> +		}
> +	}
> +
> +	if (i >= table->count)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static void ni_populate_mvdd_value(struct radeon_device *rdev,
> +				   u32 mclk,
> +				   NISLANDS_SMC_VOLTAGE_VALUE *voltage)
> +{
> +        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
^
Broken indentation.
> +
> +	if (!pi->mvdd_control) {
> +		voltage->index = eg_pi->mvdd_high_index;
> +                voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
> +		return;
> +        }
> +
> +        if (mclk <= pi->mvdd_split_frequency) {
> +                voltage->index = eg_pi->mvdd_low_index;
> +                voltage->value = cpu_to_be16(MVDD_LOW_VALUE);
^
Broken indentation.
> +	} else {
> +		voltage->index = eg_pi->mvdd_high_index;
> +		voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
> +        }
^
Broken indentation.
> +}
> +
> +static int ni_get_std_voltage_value(struct radeon_device *rdev,
> +				    NISLANDS_SMC_VOLTAGE_VALUE *voltage,
> +				    u16 *std_voltage)
> +{
> +	if (rdev->pm.dpm.dyn_state.cac_leakage_table.entries &&
> +	    ((u32)voltage->index < rdev->pm.dpm.dyn_state.cac_leakage_table.count))
> +		*std_voltage = rdev->pm.dpm.dyn_state.cac_leakage_table.entries[voltage->index].vddc;
> +	else
> +		*std_voltage = be16_to_cpu(voltage->value);
> +
> +	return 0;
> +}
> +
> +static void ni_populate_std_voltage_value(struct radeon_device *rdev,
> +					  u16 value, u8 index,
> +					  NISLANDS_SMC_VOLTAGE_VALUE *voltage)
> +{
> +	voltage->index = index;
> +	voltage->value = cpu_to_be16(value);
> +}
> +
> +static u32 ni_get_smc_power_scaling_factor(struct radeon_device *rdev)
> +{
> +	u32 xclk_period;
> +	u32 xclk = radeon_get_xclk(rdev);
> +	u32 tmp = RREG32(CG_CAC_CTRL) & TID_CNT_MASK;
> +
> +	xclk_period = (1000000000UL / xclk);
> +	xclk_period /= 10000UL;
> +
> +	return tmp * xclk_period;
> +}
> +
> +static u32 ni_scale_power_for_smc(u32 power_in_watts, u32 scaling_factor)
> +{
> +	return (power_in_watts * scaling_factor) << 2;
> +}
> +
> +static u32 ni_calculate_power_boost_limit(struct radeon_device *rdev,
> +					  struct radeon_ps *radeon_state,
> +					  u32 near_tdp_limit)
> +{
> +	struct ni_ps *state = ni_get_ps(radeon_state);
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 power_boost_limit = 0;
> +	int ret;
> +
> +	if (ni_pi->enable_power_containment &&
> +	    ni_pi->use_power_boost_limit) {
> +		NISLANDS_SMC_VOLTAGE_VALUE vddc;
> +		u16 std_vddc_med;
> +		u16 std_vddc_high;
> +		u64 tmp;
> +
> +		if (state->performance_level_count < 3)
> +			return 0;
> +
> +		ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
> +						state->performance_levels[state->performance_level_count - 2].vddc,
> +						&vddc);
> +		if (ret)
> +			return 0;
> +
> +		ret = ni_get_std_voltage_value(rdev, &vddc, &std_vddc_med);
> +		if (ret)
> +			return 0;
> +
> +		ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
> +						state->performance_levels[state->performance_level_count - 1].vddc,
> +						&vddc);
> +		if (ret)
> +			return 0;
> +
> +		ret = ni_get_std_voltage_value(rdev, &vddc, &std_vddc_high);
> +		if (ret)
> +			return 0;
> +
> +		tmp = ((u64)near_tdp_limit * ((u64)std_vddc_med * (u64)std_vddc_med) * 90) /
> +			((u64)std_vddc_high * (u64)std_vddc_high * 100);
> +		if (tmp >> 32)
> +			return 0;
> +		power_boost_limit = (u32)tmp;
> +	}
> +
> +	return power_boost_limit;
> +}
> +
> +static int ni_calculate_adjusted_tdp_limits(struct radeon_device *rdev,
> +					    bool adjust_polarity,
> +					    u32 tdp_adjustment,
> +					    u32 *tdp_limit,
> +					    u32 *near_tdp_limit)
> +{
> +	if (tdp_adjustment > (u32)rdev->pm.dpm.tdp_od_limit)
> +		return -EINVAL;
> +
> +	if (adjust_polarity) {
> +		*tdp_limit = ((100 + tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
> +		*near_tdp_limit = rdev->pm.dpm.near_tdp_limit + (*tdp_limit - rdev->pm.dpm.tdp_limit);
> +	} else {
> +		*tdp_limit = ((100 - tdp_adjustment) * rdev->pm.dpm.tdp_limit) / 100;
> +		*near_tdp_limit = rdev->pm.dpm.near_tdp_limit - (rdev->pm.dpm.tdp_limit - *tdp_limit);
> +	}
> +
> +	return 0;
> +}
> +
> +static int ni_populate_smc_tdp_limits(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +
> +	if (ni_pi->enable_power_containment) {
> +		struct radeon_ps *radeon_state = rdev->pm.dpm.requested_ps;
> +		NISLANDS_SMC_STATETABLE *smc_table = &ni_pi->smc_statetable;
> +		u32 scaling_factor = ni_get_smc_power_scaling_factor(rdev);
> +		u32 tdp_limit;
> +		u32 near_tdp_limit;
> +		u32 power_boost_limit;
> +		int ret;
> +
> +		if (scaling_factor == 0)
> +			return -EINVAL;
> +
> +		memset(smc_table, 0, sizeof(NISLANDS_SMC_STATETABLE));
> +
> +		ret = ni_calculate_adjusted_tdp_limits(rdev,
> +						       false, /* ??? */
> +						       rdev->pm.dpm.tdp_adjustment,
> +						       &tdp_limit,
> +						       &near_tdp_limit);
> +		if (ret)
> +			return ret;
> +
> +		power_boost_limit = ni_calculate_power_boost_limit(rdev, radeon_state,
> +								   near_tdp_limit);
> +
> +		smc_table->dpm2Params.TDPLimit =
> +			cpu_to_be32(ni_scale_power_for_smc(tdp_limit, scaling_factor));
> +		smc_table->dpm2Params.NearTDPLimit =
> +			cpu_to_be32(ni_scale_power_for_smc(near_tdp_limit, scaling_factor));
> +		smc_table->dpm2Params.SafePowerLimit =
> +			cpu_to_be32(ni_scale_power_for_smc((near_tdp_limit * NISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT) / 100,
> +							   scaling_factor));
> +		smc_table->dpm2Params.PowerBoostLimit =
> +			cpu_to_be32(ni_scale_power_for_smc(power_boost_limit, scaling_factor));
> +
> +		ret = rv770_copy_bytes_to_smc(rdev,
> +					      (u16)(pi->state_table_start + offsetof(NISLANDS_SMC_STATETABLE, dpm2Params) +
> +						    offsetof(PP_NIslands_DPM2Parameters, TDPLimit)),
> +					      (u8 *)(&smc_table->dpm2Params.TDPLimit),
> +					      sizeof(u32) * 4, pi->sram_end);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int ni_copy_and_switch_arb_sets(struct radeon_device *rdev,
> +				       u32 arb_freq_src, u32 arb_freq_dest)
> +{
> +	u32 mc_arb_dram_timing;
> +	u32 mc_arb_dram_timing2;
> +	u32 burst_time;
> +	u32 mc_cg_config;
> +
> +	switch (arb_freq_src) {
> +        case MC_CG_ARB_FREQ_F0:
> +		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING);
> +		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
> +		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE0_MASK) >> STATE0_SHIFT;
> +		break;
> +        case MC_CG_ARB_FREQ_F1:
> +		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_1);
> +		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_1);
> +		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE1_MASK) >> STATE1_SHIFT;
> +		break;
> +        case MC_CG_ARB_FREQ_F2:
> +		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_2);
> +		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_2);
> +		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE2_MASK) >> STATE2_SHIFT;
> +		break;
> +        case MC_CG_ARB_FREQ_F3:
> +		mc_arb_dram_timing  = RREG32(MC_ARB_DRAM_TIMING_3);
> +		mc_arb_dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2_3);
> +		burst_time = (RREG32(MC_ARB_BURST_TIME) & STATE3_MASK) >> STATE3_SHIFT;
> +		break;
> +        default:
> +		return -EINVAL;
> +	}
> +
> +	switch (arb_freq_dest) {
> +        case MC_CG_ARB_FREQ_F0:
> +		WREG32(MC_ARB_DRAM_TIMING, mc_arb_dram_timing);
> +		WREG32(MC_ARB_DRAM_TIMING2, mc_arb_dram_timing2);
> +		WREG32_P(MC_ARB_BURST_TIME, STATE0(burst_time), ~STATE0_MASK);
> +		break;
> +        case MC_CG_ARB_FREQ_F1:
> +		WREG32(MC_ARB_DRAM_TIMING_1, mc_arb_dram_timing);
> +		WREG32(MC_ARB_DRAM_TIMING2_1, mc_arb_dram_timing2);
> +		WREG32_P(MC_ARB_BURST_TIME, STATE1(burst_time), ~STATE1_MASK);
> +		break;
> +        case MC_CG_ARB_FREQ_F2:
> +		WREG32(MC_ARB_DRAM_TIMING_2, mc_arb_dram_timing);
> +		WREG32(MC_ARB_DRAM_TIMING2_2, mc_arb_dram_timing2);
> +		WREG32_P(MC_ARB_BURST_TIME, STATE2(burst_time), ~STATE2_MASK);
> +		break;
> +        case MC_CG_ARB_FREQ_F3:
^
Broken indentation.
> +		WREG32(MC_ARB_DRAM_TIMING_3, mc_arb_dram_timing);
> +		WREG32(MC_ARB_DRAM_TIMING2_3, mc_arb_dram_timing2);
> +		WREG32_P(MC_ARB_BURST_TIME, STATE3(burst_time), ~STATE3_MASK);
> +		break;
> +        default:
^
Broken indentation.
> +		return -EINVAL;
> +	}
> +
> +	mc_cg_config = RREG32(MC_CG_CONFIG) | 0x0000000F;
> +	WREG32(MC_CG_CONFIG, mc_cg_config);
> +	WREG32_P(MC_ARB_CG, CG_ARB_REQ(arb_freq_dest), ~CG_ARB_REQ_MASK);
> +
> +	return 0;
> +}
> +
> +static int ni_init_arb_table_index(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 tmp;
> +	int ret;
> +
> +	ret = rv770_read_smc_sram_dword(rdev, ni_pi->arb_table_start,
> +					&tmp, pi->sram_end);
> +	if (ret)
> +		return ret;
> +
> +	tmp &= 0x00FFFFFF;
> +	tmp |= ((u32)MC_CG_ARB_FREQ_F1) << 24;
> +
> +	return rv770_write_smc_sram_dword(rdev, ni_pi->arb_table_start,
> +					  tmp, pi->sram_end);
> +}
> +
> +static int ni_initial_switch_from_arb_f0_to_f1(struct radeon_device *rdev)
> +{
> +	return ni_copy_and_switch_arb_sets(rdev, MC_CG_ARB_FREQ_F0, MC_CG_ARB_FREQ_F1);
> +}
> +
> +static int ni_force_switch_to_arb_f0(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 tmp;
> +	int ret;
> +
> +	ret = rv770_read_smc_sram_dword(rdev, ni_pi->arb_table_start,
> +					&tmp, pi->sram_end);
> +	if (ret)
> +		return ret;
> +
> +	tmp = (tmp >> 24) & 0xff;
> +
> +	if (tmp == MC_CG_ARB_FREQ_F0)
> +		return 0;
> +
> +	return ni_copy_and_switch_arb_sets(rdev, tmp, MC_CG_ARB_FREQ_F0);
> +}
> +
> +static int ni_populate_memory_timing_parameters(struct radeon_device *rdev,
> +						struct rv7xx_pl *pl,
> +						SMC_NIslands_MCArbDramTimingRegisterSet *arb_regs)
> +{
> +	u32 dram_timing;
> +	u32 dram_timing2;
> +
> +	arb_regs->mc_arb_rfsh_rate =
> +		(u8)rv770_calculate_memory_refresh_rate(rdev, pl->sclk);
> +
> +
> +	radeon_atom_set_engine_dram_timings(rdev,
> +                                            pl->sclk,
> +                                            pl->mclk);
> +
> +	dram_timing = RREG32(MC_ARB_DRAM_TIMING);
> +	dram_timing2 = RREG32(MC_ARB_DRAM_TIMING2);
> +
> +	arb_regs->mc_arb_dram_timing  = cpu_to_be32(dram_timing);
> +	arb_regs->mc_arb_dram_timing2 = cpu_to_be32(dram_timing2);
> +
> +	return 0;
> +}
> +
> +static int ni_do_program_memory_timing_parameters(struct radeon_device *rdev,
> +						  struct radeon_ps *radeon_state,
> +						  unsigned int first_arb_set)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	struct ni_ps *state = ni_get_ps(radeon_state);
> +	SMC_NIslands_MCArbDramTimingRegisterSet arb_regs = { 0 };
> +	int i, ret = 0;
> +
> +	for (i = 0; i < state->performance_level_count; i++) {
> +		ret = ni_populate_memory_timing_parameters(rdev, &state->performance_levels[i], &arb_regs);
> +		if (ret)
> +			break;
> +
> +		ret = rv770_copy_bytes_to_smc(rdev,
> +					      (u16)(ni_pi->arb_table_start +
> +						    offsetof(SMC_NIslands_MCArbDramTimingRegisters, data) +
> +						    sizeof(SMC_NIslands_MCArbDramTimingRegisterSet) * (first_arb_set + i)),
> +					      (u8 *)&arb_regs,
> +					      (u16)sizeof(SMC_NIslands_MCArbDramTimingRegisterSet),
> +					      pi->sram_end);
> +		if (ret)
> +			break;
> +	}
> +	return ret;
> +}
> +
> +static int ni_program_memory_timing_parameters(struct radeon_device *rdev)
> +{
> +	struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
> +
> +	return ni_do_program_memory_timing_parameters(rdev, radeon_new_state,
> +						      NISLANDS_DRIVER_STATE_ARB_INDEX);
> +}
> +
> +static void ni_populate_initial_mvdd_value(struct radeon_device *rdev,
> +					   struct NISLANDS_SMC_VOLTAGE_VALUE *voltage)
> +{
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +
> +	voltage->index = eg_pi->mvdd_high_index;
> +	voltage->value = cpu_to_be16(MVDD_HIGH_VALUE);
> +}
> +
> +static int ni_populate_smc_initial_state(struct radeon_device *rdev,
> +					 struct radeon_ps *radeon_initial_state,
> +					 NISLANDS_SMC_STATETABLE *table)
> +{
> +	struct ni_ps *initial_state = ni_get_ps(radeon_initial_state);
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 reg;
> +	int ret;
> +
> +	table->initialState.levels[0].mclk.vMPLL_AD_FUNC_CNTL =
> +		cpu_to_be32(ni_pi->clock_registers.mpll_ad_func_cntl);
> +	table->initialState.levels[0].mclk.vMPLL_AD_FUNC_CNTL_2 =
> +		cpu_to_be32(ni_pi->clock_registers.mpll_ad_func_cntl_2);
> +	table->initialState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL =
> +		cpu_to_be32(ni_pi->clock_registers.mpll_dq_func_cntl);
> +	table->initialState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL_2 =
> +		cpu_to_be32(ni_pi->clock_registers.mpll_dq_func_cntl_2);
> +	table->initialState.levels[0].mclk.vMCLK_PWRMGT_CNTL =
> +		cpu_to_be32(ni_pi->clock_registers.mclk_pwrmgt_cntl);
> +	table->initialState.levels[0].mclk.vDLL_CNTL =
> +		cpu_to_be32(ni_pi->clock_registers.dll_cntl);
> +	table->initialState.levels[0].mclk.vMPLL_SS =
> +		cpu_to_be32(ni_pi->clock_registers.mpll_ss1);
> +	table->initialState.levels[0].mclk.vMPLL_SS2 =
> +		cpu_to_be32(ni_pi->clock_registers.mpll_ss2);
> +	table->initialState.levels[0].mclk.mclk_value =
> +		cpu_to_be32(initial_state->performance_levels[0].mclk);
> +
> +	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL =
> +		cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl);
> +	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 =
> +		cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_2);
> +	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 =
> +		cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_3);
> +	table->initialState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_4 =
> +		cpu_to_be32(ni_pi->clock_registers.cg_spll_func_cntl_4);
> +	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM =
> +		cpu_to_be32(ni_pi->clock_registers.cg_spll_spread_spectrum);
> +	table->initialState.levels[0].sclk.vCG_SPLL_SPREAD_SPECTRUM_2 =
> +		cpu_to_be32(ni_pi->clock_registers.cg_spll_spread_spectrum_2);
> +	table->initialState.levels[0].sclk.sclk_value =
> +		cpu_to_be32(initial_state->performance_levels[0].sclk);
> +	table->initialState.levels[0].arbRefreshState =
> +		NISLANDS_INITIAL_STATE_ARB_INDEX;
> +
> +	table->initialState.levels[0].ACIndex = 0;
> +
> +	ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
> +					initial_state->performance_levels[0].vddc,
> +					&table->initialState.levels[0].vddc);
> +	if (!ret) {
> +		u16 std_vddc;
> +
> +		ret = ni_get_std_voltage_value(rdev,
> +					       &table->initialState.levels[0].vddc,
> +					       &std_vddc);
> +		if (!ret)
> +			ni_populate_std_voltage_value(rdev, std_vddc,
> +						      table->initialState.levels[0].vddc.index,
> +						      &table->initialState.levels[0].std_vddc);
> +	}
> +
> +	if (eg_pi->vddci_control)
> +		ni_populate_voltage_value(rdev,
> +					  &eg_pi->vddci_voltage_table,
> +					  initial_state->performance_levels[0].vddci,
> +					  &table->initialState.levels[0].vddci);
> +
> +	ni_populate_initial_mvdd_value(rdev, &table->initialState.levels[0].mvdd);
> +
> +	reg = CG_R(0xffff) | CG_L(0);
> +	table->initialState.levels[0].aT = cpu_to_be32(reg);
> +
> +	table->initialState.levels[0].bSP = cpu_to_be32(pi->dsp);
> +
> +	if (pi->boot_in_gen2)
> +		table->initialState.levels[0].gen2PCIE = 1;
> +	else
> +		table->initialState.levels[0].gen2PCIE = 0;
> +
> +	if (pi->mem_gddr5) {
> +		table->initialState.levels[0].strobeMode =
> +			cypress_get_strobe_mode_settings(rdev,
> +							 initial_state->performance_levels[0].mclk);
> +
> +		if (initial_state->performance_levels[0].mclk > pi->mclk_edc_enable_threshold)
> +			table->initialState.levels[0].mcFlags = NISLANDS_SMC_MC_EDC_RD_FLAG | NISLANDS_SMC_MC_EDC_WR_FLAG;
> +		else
> +			table->initialState.levels[0].mcFlags =  0;
> +	}
> +
> +	table->initialState.levelCount = 1;
> +
> +	table->initialState.flags |= PPSMC_SWSTATE_FLAG_DC;
> +
> +	table->initialState.levels[0].dpm2.MaxPS = 0;
> +	table->initialState.levels[0].dpm2.NearTDPDec = 0;
> +	table->initialState.levels[0].dpm2.AboveSafeInc = 0;
> +	table->initialState.levels[0].dpm2.BelowSafeInc = 0;
> +
> +	reg = MIN_POWER_MASK | MAX_POWER_MASK;
> +	table->initialState.levels[0].SQPowerThrottle = cpu_to_be32(reg);
> +
> +	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
> +	table->initialState.levels[0].SQPowerThrottle_2 = cpu_to_be32(reg);
> +
> +	return 0;
> +}
> +
> +static int ni_populate_smc_acpi_state(struct radeon_device *rdev,
> +				      NISLANDS_SMC_STATETABLE *table)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 mpll_ad_func_cntl   = ni_pi->clock_registers.mpll_ad_func_cntl;
> +	u32 mpll_ad_func_cntl_2 = ni_pi->clock_registers.mpll_ad_func_cntl_2;
> +	u32 mpll_dq_func_cntl   = ni_pi->clock_registers.mpll_dq_func_cntl;
> +	u32 mpll_dq_func_cntl_2 = ni_pi->clock_registers.mpll_dq_func_cntl_2;
> +	u32 spll_func_cntl      = ni_pi->clock_registers.cg_spll_func_cntl;
> +	u32 spll_func_cntl_2    = ni_pi->clock_registers.cg_spll_func_cntl_2;
> +	u32 spll_func_cntl_3    = ni_pi->clock_registers.cg_spll_func_cntl_3;
> +	u32 spll_func_cntl_4    = ni_pi->clock_registers.cg_spll_func_cntl_4;
> +	u32 mclk_pwrmgt_cntl    = ni_pi->clock_registers.mclk_pwrmgt_cntl;
> +	u32 dll_cntl            = ni_pi->clock_registers.dll_cntl;
> +	u32 reg;
> +	int ret;
> +
> +	table->ACPIState = table->initialState;
> +
> +	table->ACPIState.flags &= ~PPSMC_SWSTATE_FLAG_DC;
> +
> +	if (pi->acpi_vddc) {
> +		ret = ni_populate_voltage_value(rdev,
> +						&eg_pi->vddc_voltage_table,
> +						pi->acpi_vddc, &table->ACPIState.levels[0].vddc);
> +		if (!ret) {
> +			u16 std_vddc;
> +
> +			ret = ni_get_std_voltage_value(rdev,
> +						       &table->ACPIState.levels[0].vddc, &std_vddc);
> +			if (!ret)
> +				ni_populate_std_voltage_value(rdev, std_vddc,
> +							      table->ACPIState.levels[0].vddc.index,
> +							      &table->ACPIState.levels[0].std_vddc);
> +		}
> +
> +		if (pi->pcie_gen2) {
> +			if (pi->acpi_pcie_gen2)
> +				table->ACPIState.levels[0].gen2PCIE = 1;
> +			else
> +				table->ACPIState.levels[0].gen2PCIE = 0;
> +		} else {
> +			table->ACPIState.levels[0].gen2PCIE = 0;
> +		}
> +	} else {
> +		ret = ni_populate_voltage_value(rdev,
> +						&eg_pi->vddc_voltage_table,
> +						pi->min_vddc_in_table,
> +						&table->ACPIState.levels[0].vddc);
> +		if (!ret) {
> +			u16 std_vddc;
> +
> +			ret = ni_get_std_voltage_value(rdev,
> +						       &table->ACPIState.levels[0].vddc,
> +						       &std_vddc);
> +			if (!ret)
> +				ni_populate_std_voltage_value(rdev, std_vddc,
> +							      table->ACPIState.levels[0].vddc.index,
> +							      &table->ACPIState.levels[0].std_vddc);
> +		}
> +		table->ACPIState.levels[0].gen2PCIE = 0;
> +	}
> +
> +	if (eg_pi->acpi_vddci) {
> +		if (eg_pi->vddci_control)
> +			ni_populate_voltage_value(rdev,
> +						  &eg_pi->vddci_voltage_table,
> +						  eg_pi->acpi_vddci,
> +						  &table->ACPIState.levels[0].vddci);
> +	}
> +
> +
> +	mpll_ad_func_cntl &= ~PDNB;
> +
> +	mpll_ad_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN;
> +
> +        if (pi->mem_gddr5)
> +                mpll_dq_func_cntl &= ~PDNB;
> +        mpll_dq_func_cntl_2 |= BIAS_GEN_PDNB | RESET_EN | BYPASS;
> +
> +
> +        mclk_pwrmgt_cntl |= (MRDCKA0_RESET |
> +                             MRDCKA1_RESET |
> +                             MRDCKB0_RESET |
> +                             MRDCKB1_RESET |
> +                             MRDCKC0_RESET |
> +                             MRDCKC1_RESET |
> +                             MRDCKD0_RESET |
> +                             MRDCKD1_RESET);
^
Broken indentation.
> +
> +        mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB |
> +                              MRDCKA1_PDNB |
> +			      MRDCKB0_PDNB |
> +                              MRDCKB1_PDNB |
> +			      MRDCKC0_PDNB |
> +                              MRDCKC1_PDNB |
> +                              MRDCKD0_PDNB |
> +                              MRDCKD1_PDNB);
> +
> +	dll_cntl |= (MRDCKA0_BYPASS |
> +                     MRDCKA1_BYPASS |
> +                     MRDCKB0_BYPASS |
> +                     MRDCKB1_BYPASS |
> +                     MRDCKC0_BYPASS |
> +                     MRDCKC1_BYPASS |
> +                     MRDCKD0_BYPASS |
> +                     MRDCKD1_BYPASS);
^
Broken indentation.
> +
> +        spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
> +	spll_func_cntl_2 |= SCLK_MUX_SEL(4);
> +
> +	table->ACPIState.levels[0].mclk.vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
> +	table->ACPIState.levels[0].mclk.vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
> +	table->ACPIState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
> +	table->ACPIState.levels[0].mclk.vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
> +	table->ACPIState.levels[0].mclk.vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
> +	table->ACPIState.levels[0].mclk.vDLL_CNTL = cpu_to_be32(dll_cntl);
> +
> +	table->ACPIState.levels[0].mclk.mclk_value = 0;
> +
> +	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL = cpu_to_be32(spll_func_cntl);
> +	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(spll_func_cntl_2);
> +	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(spll_func_cntl_3);
> +	table->ACPIState.levels[0].sclk.vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(spll_func_cntl_4);
> +
> +	table->ACPIState.levels[0].sclk.sclk_value = 0;
> +
> +	ni_populate_mvdd_value(rdev, 0, &table->ACPIState.levels[0].mvdd);
> +
> +	if (eg_pi->dynamic_ac_timing)
> +		table->ACPIState.levels[0].ACIndex = 1;
> +
> +	table->ACPIState.levels[0].dpm2.MaxPS = 0;
> +	table->ACPIState.levels[0].dpm2.NearTDPDec = 0;
> +	table->ACPIState.levels[0].dpm2.AboveSafeInc = 0;
> +	table->ACPIState.levels[0].dpm2.BelowSafeInc = 0;
> +
> +	reg = MIN_POWER_MASK | MAX_POWER_MASK;
> +	table->ACPIState.levels[0].SQPowerThrottle = cpu_to_be32(reg);
> +
> +	reg = MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
> +	table->ACPIState.levels[0].SQPowerThrottle_2 = cpu_to_be32(reg);
> +
> +	return 0;
> +}
> +
> +static int ni_init_smc_table(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	int ret;
> +	struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
> +	NISLANDS_SMC_STATETABLE *table = &ni_pi->smc_statetable;
> +
> +	memset(table, 0, sizeof(NISLANDS_SMC_STATETABLE));
> +
> +	ni_populate_smc_voltage_tables(rdev, table);
> +
> +        switch (rdev->pm.int_thermal_type) {
> +        case THERMAL_TYPE_NI:
> +        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;
^
Broken indentation.
> +		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 = ni_populate_smc_initial_state(rdev, radeon_boot_state, table);
> +	if (ret)
> +		return ret;
> +
> +	ret = ni_populate_smc_acpi_state(rdev, table);
> +	if (ret)
> +		return ret;
> +
> +	table->driverState = table->initialState;
> +
> +	table->ULVState = table->initialState;
> +
> +	ret = ni_do_program_memory_timing_parameters(rdev, radeon_boot_state,
> +						     NISLANDS_INITIAL_STATE_ARB_INDEX);
> +	if (ret)
> +		return ret;
> +
> +	return rv770_copy_bytes_to_smc(rdev, pi->state_table_start, (u8 *)table,
> +				       sizeof(NISLANDS_SMC_STATETABLE), pi->sram_end);
> +}
> +
> +static int ni_calculate_sclk_params(struct radeon_device *rdev,
> +				    u32 engine_clock,
> +				    NISLANDS_SMC_SCLK_VALUE *sclk)
> +{
> +        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
^
Broken indentation.
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	struct atom_clock_dividers dividers;
> +	u32 spll_func_cntl = ni_pi->clock_registers.cg_spll_func_cntl;
> +	u32 spll_func_cntl_2 = ni_pi->clock_registers.cg_spll_func_cntl_2;
> +	u32 spll_func_cntl_3 = ni_pi->clock_registers.cg_spll_func_cntl_3;
> +	u32 spll_func_cntl_4 = ni_pi->clock_registers.cg_spll_func_cntl_4;
> +	u32 cg_spll_spread_spectrum = ni_pi->clock_registers.cg_spll_spread_spectrum;
> +	u32 cg_spll_spread_spectrum_2 = ni_pi->clock_registers.cg_spll_spread_spectrum_2;
> +	u64 tmp;
> +	u32 reference_clock = rdev->clock.spll.reference_freq;
> +	u32 reference_divider;
> +	u32 fbdiv;
> +	int ret;
> +
> +        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
> +                                             engine_clock, false, &dividers);
> +	if (ret)
> +		return ret;
> +
> +	reference_divider = 1 + dividers.ref_div;
> +
> +	tmp = (u64) engine_clock * reference_divider * dividers.post_div;
> +
> +	fbdiv = (u32) ((16384 * tmp) / reference_clock);
> +
> +        spll_func_cntl &= ~(SPLL_PDIV_A_MASK | SPLL_REF_DIV_MASK);
> +        spll_func_cntl |= SPLL_REF_DIV(dividers.ref_div);
> +        spll_func_cntl |= SPLL_PDIV_A(dividers.post_div);
> +
> +        spll_func_cntl_2 &= ~SCLK_MUX_SEL_MASK;
> +        spll_func_cntl_2 |= SCLK_MUX_SEL(2);
^
Broken indentation.
> +
> +	spll_func_cntl_3 &= ~SPLL_FB_DIV_MASK;
> +        spll_func_cntl_3 |= SPLL_FB_DIV(fbdiv);
> +        spll_func_cntl_3 |= SPLL_DITHEN;
> +
> +	if (pi->sclk_ss) {
> +                struct radeon_atom_ss ss;
> +                u32 vco_freq = engine_clock * dividers.post_div;
> +
> +                if (radeon_atombios_get_asic_ss_info(rdev, &ss,
> +                                                     ASIC_INTERNAL_ENGINE_SS, vco_freq)) {
> +                        u32 clk_s = reference_clock * 5 / (reference_divider * ss.rate);
> +                        u32 clk_v = 4 * ss.percentage * fbdiv / (clk_s * 10000);
> +
> +                        cg_spll_spread_spectrum &= ~CLK_S_MASK;
> +			cg_spll_spread_spectrum |= CLK_S(clk_s);
> +                        cg_spll_spread_spectrum |= SSEN;
> +
> +                        cg_spll_spread_spectrum_2 &= ~CLK_V_MASK;
> +                        cg_spll_spread_spectrum_2 |= CLK_V(clk_v);
^
Broken indentation.
> +		}
> +	}
> +
> +	sclk->sclk_value = engine_clock;
> +	sclk->vCG_SPLL_FUNC_CNTL = spll_func_cntl;
> +	sclk->vCG_SPLL_FUNC_CNTL_2 = spll_func_cntl_2;
> +	sclk->vCG_SPLL_FUNC_CNTL_3 = spll_func_cntl_3;
> +	sclk->vCG_SPLL_FUNC_CNTL_4 = spll_func_cntl_4;
> +	sclk->vCG_SPLL_SPREAD_SPECTRUM = cg_spll_spread_spectrum;
> +	sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cg_spll_spread_spectrum_2;
> +
> +	return 0;
> +}
> +
> +static int ni_populate_sclk_value(struct radeon_device *rdev,
> +				  u32 engine_clock,
> +				  NISLANDS_SMC_SCLK_VALUE *sclk)
> +{
> +	NISLANDS_SMC_SCLK_VALUE sclk_tmp;
> +	int ret;
> +
> +	ret = ni_calculate_sclk_params(rdev, engine_clock, &sclk_tmp);
> +	if (!ret) {
> +		sclk->sclk_value = cpu_to_be32(sclk_tmp.sclk_value);
> +		sclk->vCG_SPLL_FUNC_CNTL = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL);
> +		sclk->vCG_SPLL_FUNC_CNTL_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_2);
> +		sclk->vCG_SPLL_FUNC_CNTL_3 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_3);
> +		sclk->vCG_SPLL_FUNC_CNTL_4 = cpu_to_be32(sclk_tmp.vCG_SPLL_FUNC_CNTL_4);
> +		sclk->vCG_SPLL_SPREAD_SPECTRUM = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM);
> +		sclk->vCG_SPLL_SPREAD_SPECTRUM_2 = cpu_to_be32(sclk_tmp.vCG_SPLL_SPREAD_SPECTRUM_2);
> +	}
> +
> +	return ret;
> +}
> +
> +static int ni_init_smc_spll_table(struct radeon_device *rdev)
> +{
> +        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	SMC_NISLANDS_SPLL_DIV_TABLE *spll_table;
> +	NISLANDS_SMC_SCLK_VALUE sclk_params;
> +	u32 fb_div;
> +	u32 p_div;
> +	u32 clk_s;
> +	u32 clk_v;
> +	u32 sclk = 0;
> +	int i, ret;
> +	u32 tmp;
> +
> +	if (ni_pi->spll_table_start == 0)
> +		return -EINVAL;
> +
> +	spll_table = kzalloc(sizeof(SMC_NISLANDS_SPLL_DIV_TABLE), GFP_KERNEL);
> +	if (spll_table == NULL)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < 256; i++) {
> +		ret = ni_calculate_sclk_params(rdev, sclk, &sclk_params);
> +		if (ret)
> +			break;
> +
> +		p_div = (sclk_params.vCG_SPLL_FUNC_CNTL & SPLL_PDIV_A_MASK) >> SPLL_PDIV_A_SHIFT;
> +		fb_div = (sclk_params.vCG_SPLL_FUNC_CNTL_3 & SPLL_FB_DIV_MASK) >> SPLL_FB_DIV_SHIFT;
> +		clk_s = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM & CLK_S_MASK) >> CLK_S_SHIFT;
> +		clk_v = (sclk_params.vCG_SPLL_SPREAD_SPECTRUM_2 & CLK_V_MASK) >> CLK_V_SHIFT;
> +
> +		fb_div &= ~0x00001FFF;
> +		fb_div >>= 1;
> +		clk_v >>= 6;
> +
> +		if (p_div & ~(SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT))
> +			ret = -EINVAL;
> +
> +		if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
> +			ret = -EINVAL;
> +
> +		if (clk_s & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT))
> +			ret = -EINVAL;
> +
> +		if (clk_v & ~(SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK >> SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT))
> +			ret = -EINVAL;
> +
> +		if (ret)
> +			break;
> +
> +		tmp = ((fb_div << SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK) |
> +			((p_div << SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK);
> +		spll_table->freq[i] = cpu_to_be32(tmp);
> +
> +		tmp = ((clk_v << SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK) |
> +			((clk_s << SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT) & SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK);
> +		spll_table->ss[i] = cpu_to_be32(tmp);
> +
> +		sclk += 512;
> +	}
> +
> +	if (!ret)
> +		ret = rv770_copy_bytes_to_smc(rdev, ni_pi->spll_table_start, (u8 *)spll_table,
> +					      sizeof(SMC_NISLANDS_SPLL_DIV_TABLE), pi->sram_end);
> +
> +	kfree(spll_table);
> +
> +	return ret;
> +}
> +
> +static int ni_populate_mclk_value(struct radeon_device *rdev,
> +				  u32 engine_clock,
> +				  u32 memory_clock,
> +				  NISLANDS_SMC_MCLK_VALUE *mclk,
> +				  bool strobe_mode,
> +				  bool dll_state_on)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 mpll_ad_func_cntl = ni_pi->clock_registers.mpll_ad_func_cntl;
> +	u32 mpll_ad_func_cntl_2 = ni_pi->clock_registers.mpll_ad_func_cntl_2;
> +	u32 mpll_dq_func_cntl = ni_pi->clock_registers.mpll_dq_func_cntl;
> +	u32 mpll_dq_func_cntl_2 = ni_pi->clock_registers.mpll_dq_func_cntl_2;
> +	u32 mclk_pwrmgt_cntl = ni_pi->clock_registers.mclk_pwrmgt_cntl;
> +	u32 dll_cntl = ni_pi->clock_registers.dll_cntl;
> +	u32 mpll_ss1 = ni_pi->clock_registers.mpll_ss1;
> +	u32 mpll_ss2 = ni_pi->clock_registers.mpll_ss2;
> +	struct atom_clock_dividers dividers;
> +	u32 ibias;
> +	u32 dll_speed;
> +	int ret;
> +	u32 mc_seq_misc7;
> +
> +        ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_MEMORY_PLL_PARAM,
> +                                             memory_clock, strobe_mode, &dividers);
^
Broken indentation.
> +	if (ret)
> +		return ret;
> +
> +	if (!strobe_mode) {
> +		mc_seq_misc7 = RREG32(MC_SEQ_MISC7);
> +
> +		if (mc_seq_misc7 & 0x8000000)
> +			dividers.post_div = 1;
> +	}
> +
> +	ibias = cypress_map_clkf_to_ibias(rdev, dividers.whole_fb_div);
> +
> +        mpll_ad_func_cntl &= ~(CLKR_MASK |
> +                               YCLK_POST_DIV_MASK |
> +                               CLKF_MASK |
> +                               CLKFRAC_MASK |
> +                               IBIAS_MASK);
> +        mpll_ad_func_cntl |= CLKR(dividers.ref_div);
> +        mpll_ad_func_cntl |= YCLK_POST_DIV(dividers.post_div);
> +        mpll_ad_func_cntl |= CLKF(dividers.whole_fb_div);
> +        mpll_ad_func_cntl |= CLKFRAC(dividers.frac_fb_div);
^
Broken indentation.
> +	mpll_ad_func_cntl |= IBIAS(ibias);
> +
> +        if (dividers.vco_mode)
^
Broken indentation.
> +		mpll_ad_func_cntl_2 |= VCO_MODE;
> +	else
> +		mpll_ad_func_cntl_2 &= ~VCO_MODE;
> +
> +	if (pi->mem_gddr5) {
> +                mpll_dq_func_cntl &= ~(CLKR_MASK |
> +                                       YCLK_POST_DIV_MASK |
> +                                       CLKF_MASK |
> +                                       CLKFRAC_MASK |
> +                                       IBIAS_MASK);
> +                mpll_dq_func_cntl |= CLKR(dividers.ref_div);
> +                mpll_dq_func_cntl |= YCLK_POST_DIV(dividers.post_div);
> +                mpll_dq_func_cntl |= CLKF(dividers.whole_fb_div);
> +                mpll_dq_func_cntl |= CLKFRAC(dividers.frac_fb_div);
> +                mpll_dq_func_cntl |= IBIAS(ibias);
> +
> +		if (strobe_mode)
> +			mpll_dq_func_cntl &= ~PDNB;
> +                else
> +			mpll_dq_func_cntl |= PDNB;
> +
> +		if (dividers.vco_mode)
> +			mpll_dq_func_cntl_2 |= VCO_MODE;
> +		else
> +                        mpll_dq_func_cntl_2 &= ~VCO_MODE;
> +	}
> +
> +	if (pi->mclk_ss) {
> +                struct radeon_atom_ss ss;
> +                u32 vco_freq = memory_clock * dividers.post_div;
> +
> +                if (radeon_atombios_get_asic_ss_info(rdev, &ss,
> +						     ASIC_INTERNAL_MEMORY_SS, vco_freq)) {
> +			u32 reference_clock = rdev->clock.mpll.reference_freq;
> +                        u32 decoded_ref = rv740_get_decoded_reference_divider(dividers.ref_div);
> +			u32 clk_s = reference_clock * 5 / (decoded_ref * ss.rate);
> +                        u32 clk_v = ss.percentage *
> +                                (0x4000 * dividers.whole_fb_div + 0x800 * dividers.frac_fb_div) / (clk_s * 625);
> +
> +                        mpll_ss1 &= ~CLKV_MASK;
> +                        mpll_ss1 |= CLKV(clk_v);
> +
> +                        mpll_ss2 &= ~CLKS_MASK;
> +                        mpll_ss2 |= CLKS(clk_s);
> +		}
> +	}
> +
> +        dll_speed = rv740_get_dll_speed(pi->mem_gddr5,
> +                                        memory_clock);
> +
> +        mclk_pwrmgt_cntl &= ~DLL_SPEED_MASK;
> +        mclk_pwrmgt_cntl |= DLL_SPEED(dll_speed);
> +        if (dll_state_on)
> +                mclk_pwrmgt_cntl |= (MRDCKA0_PDNB |
> +                                     MRDCKA1_PDNB |
> +                                     MRDCKB0_PDNB |
> +                                     MRDCKB1_PDNB |
> +                                     MRDCKC0_PDNB |
> +                                     MRDCKC1_PDNB |
> +                                     MRDCKD0_PDNB |
> +                                     MRDCKD1_PDNB);
> +        else
> +                mclk_pwrmgt_cntl &= ~(MRDCKA0_PDNB |
> +                                      MRDCKA1_PDNB |
> +                                      MRDCKB0_PDNB |
> +                                      MRDCKB1_PDNB |
> +                                      MRDCKC0_PDNB |
> +                                      MRDCKC1_PDNB |
> +                                      MRDCKD0_PDNB |
> +                                      MRDCKD1_PDNB);
> +
> +
> +	mclk->mclk_value = cpu_to_be32(memory_clock);
> +	mclk->vMPLL_AD_FUNC_CNTL = cpu_to_be32(mpll_ad_func_cntl);
> +	mclk->vMPLL_AD_FUNC_CNTL_2 = cpu_to_be32(mpll_ad_func_cntl_2);
> +	mclk->vMPLL_DQ_FUNC_CNTL = cpu_to_be32(mpll_dq_func_cntl);
> +	mclk->vMPLL_DQ_FUNC_CNTL_2 = cpu_to_be32(mpll_dq_func_cntl_2);
> +	mclk->vMCLK_PWRMGT_CNTL = cpu_to_be32(mclk_pwrmgt_cntl);
> +	mclk->vDLL_CNTL = cpu_to_be32(dll_cntl);
> +	mclk->vMPLL_SS = cpu_to_be32(mpll_ss1);
> +	mclk->vMPLL_SS2 = cpu_to_be32(mpll_ss2);
> +
> +	return 0;
> +}
> +
> +static void ni_populate_smc_sp(struct radeon_device *rdev,
> +			       struct radeon_ps *radeon_state,
> +			       NISLANDS_SMC_SWSTATE *smc_state)
> +{
> +	struct ni_ps *ps = ni_get_ps(radeon_state);
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	int i;
> +
> +	for (i = 0; i < ps->performance_level_count - 1; i++)
> +		smc_state->levels[i].bSP = cpu_to_be32(pi->dsp);
> +
> +	smc_state->levels[ps->performance_level_count - 1].bSP =
> +		cpu_to_be32(pi->psp);
> +}
> +
> +static int ni_convert_power_level_to_smc(struct radeon_device *rdev,
> +					 struct rv7xx_pl *pl,
> +					 NISLANDS_SMC_HW_PERFORMANCE_LEVEL *level)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +        struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	int ret;
> +	bool dll_state_on;
> +	u16 std_vddc;
> +	u32 tmp = RREG32(DC_STUTTER_CNTL);
> +
> +	level->gen2PCIE = pi->pcie_gen2 ?
> +		((pl->flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2) ? 1 : 0) : 0;
> +
> +	ret = ni_populate_sclk_value(rdev, pl->sclk, &level->sclk);
> +	if (ret)
> +		return ret;
> +
> +	level->mcFlags =  0;
> +	if (pi->mclk_stutter_mode_threshold &&
> +	    (pl->mclk <= pi->mclk_stutter_mode_threshold) &&
> +	    !eg_pi->uvd_enabled &&
> +	    (tmp & DC_STUTTER_ENABLE_A) &&
> +	    (tmp & DC_STUTTER_ENABLE_B))
> +		level->mcFlags |= NISLANDS_SMC_MC_STUTTER_EN;
> +
> +	if (pi->mem_gddr5) {
> +		if (pl->mclk > pi->mclk_edc_enable_threshold)
> +			level->mcFlags |= NISLANDS_SMC_MC_EDC_RD_FLAG;
> +		if (pl->mclk > eg_pi->mclk_edc_wr_enable_threshold)
> +			level->mcFlags |= NISLANDS_SMC_MC_EDC_WR_FLAG;
> +
> +		level->strobeMode = cypress_get_strobe_mode_settings(rdev, pl->mclk);
> +
> +		if (level->strobeMode & NISLANDS_SMC_STROBE_ENABLE) {
> +			if (cypress_get_mclk_frequency_ratio(rdev, pl->mclk, true) >=
> +			    ((RREG32(MC_SEQ_MISC7) >> 16) & 0xf))
> +				dll_state_on = ((RREG32(MC_SEQ_MISC5) >> 1) & 0x1) ? true : false;
> +			else
> +				dll_state_on = ((RREG32(MC_SEQ_MISC6) >> 1) & 0x1) ? true : false;
> +		} else {
> +			dll_state_on = false;
> +			if (pl->mclk > ni_pi->mclk_rtt_mode_threshold)
> +				level->mcFlags |= NISLANDS_SMC_MC_RTT_ENABLE;
> +		}
> +
> +		ret = ni_populate_mclk_value(rdev, pl->sclk, pl->mclk,
> +					     &level->mclk,
> +					     (level->strobeMode & NISLANDS_SMC_STROBE_ENABLE) != 0,
> +					     dll_state_on);
> +	} else
> +		ret = ni_populate_mclk_value(rdev, pl->sclk, pl->mclk, &level->mclk, 1, 1);
> +
> +	if (ret)
> +		return ret;
> +
> +	ret = ni_populate_voltage_value(rdev, &eg_pi->vddc_voltage_table,
> +					pl->vddc, &level->vddc);
> +	if (ret)
> +		return ret;
> +
> +	ret = ni_get_std_voltage_value(rdev, &level->vddc, &std_vddc);
> +	if (ret)
> +		return ret;
> +
> +	ni_populate_std_voltage_value(rdev, std_vddc,
> +				      level->vddc.index, &level->std_vddc);
> +
> +	if (eg_pi->vddci_control) {
> +		ret = ni_populate_voltage_value(rdev, &eg_pi->vddci_voltage_table,
> +						pl->vddci, &level->vddci);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	ni_populate_mvdd_value(rdev, pl->mclk, &level->mvdd);
> +
> +	return ret;
> +}
> +
> +static int ni_populate_smc_t(struct radeon_device *rdev,
> +			     struct radeon_ps *radeon_state,
> +			     NISLANDS_SMC_SWSTATE *smc_state)
> +{
> +        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	struct ni_ps *state = ni_get_ps(radeon_state);
> +	u32 a_t;
> +	u32 t_l, t_h;
> +	u32 high_bsp;
> +	int i, ret;
> +
> +	if (state->performance_level_count >= 9)
> +		return -EINVAL;
> +
> +	if (state->performance_level_count < 2) {
> +		a_t = CG_R(0xffff) | CG_L(0);
> +		smc_state->levels[0].aT = cpu_to_be32(a_t);
> +		return 0;
> +	}
> +
> +	smc_state->levels[0].aT = cpu_to_be32(0);
> +
> +	for (i = 0; i <= state->performance_level_count - 2; i++) {
> +		if (eg_pi->uvd_enabled)
> +			ret = r600_calculate_at(
> +				1000 * (i * (eg_pi->smu_uvd_hs ? 2 : 8) + 2),
> +				100 * R600_AH_DFLT,
> +				state->performance_levels[i + 1].sclk,
> +				state->performance_levels[i].sclk,
> +				&t_l,
> +				&t_h);
> +		else
> +			ret = r600_calculate_at(
> +				1000 * (i + 1),
> +				100 * R600_AH_DFLT,
> +				state->performance_levels[i + 1].sclk,
> +				state->performance_levels[i].sclk,
> +				&t_l,
> +				&t_h);
> +
> +		if (ret) {
> +			t_h = (i + 1) * 1000 - 50 * R600_AH_DFLT;
> +			t_l = (i + 1) * 1000 + 50 * R600_AH_DFLT;
> +		}
> +
> +		a_t = be32_to_cpu(smc_state->levels[i].aT) & ~CG_R_MASK;
> +		a_t |= CG_R(t_l * pi->bsp / 20000);
> +		smc_state->levels[i].aT = cpu_to_be32(a_t);
> +
> +		high_bsp = (i == state->performance_level_count - 2) ?
> +			pi->pbsp : pi->bsp;
> +
> +		a_t = CG_R(0xffff) | CG_L(t_h * high_bsp / 20000);
> +		smc_state->levels[i + 1].aT = cpu_to_be32(a_t);
> +	}
> +
> +	return 0;
> +}
> +
> +static int ni_populate_power_containment_values(struct radeon_device *rdev,
> +						struct radeon_ps *radeon_state,
> +						NISLANDS_SMC_SWSTATE *smc_state)
> +{
> +        struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	struct ni_ps *state = ni_get_ps(radeon_state);
> +	u32 prev_sclk;
> +	u32 max_sclk;
> +	u32 min_sclk;
> +	int i, ret;
> +	u32 tdp_limit;
> +	u32 near_tdp_limit;
> +	u32 power_boost_limit;
> +	u8 max_ps_percent;
> +
> +	if (ni_pi->enable_power_containment == false)
> +		return 0;
> +
> +	if (state->performance_level_count == 0)
> +		return -EINVAL;
> +
> +	if (smc_state->levelCount != state->performance_level_count)
> +		return -EINVAL;
> +
> +	ret = ni_calculate_adjusted_tdp_limits(rdev,
> +					       false, /* ??? */
> +					       rdev->pm.dpm.tdp_adjustment,
> +					       &tdp_limit,
> +					       &near_tdp_limit);
> +	if (ret)
> +		return ret;
> +
> +	power_boost_limit = ni_calculate_power_boost_limit(rdev, radeon_state, near_tdp_limit);
> +
> +	ret = rv770_write_smc_sram_dword(rdev,
> +					 pi->state_table_start +
> +					 offsetof(NISLANDS_SMC_STATETABLE, dpm2Params) +
> +					 offsetof(PP_NIslands_DPM2Parameters, PowerBoostLimit),
> +					 ni_scale_power_for_smc(power_boost_limit, ni_get_smc_power_scaling_factor(rdev)),
> +					 pi->sram_end);
> +	if (ret)
> +		power_boost_limit = 0;
> +
> +	smc_state->levels[0].dpm2.MaxPS = 0;
> +	smc_state->levels[0].dpm2.NearTDPDec = 0;
> +	smc_state->levels[0].dpm2.AboveSafeInc = 0;
> +	smc_state->levels[0].dpm2.BelowSafeInc = 0;
> +	smc_state->levels[0].stateFlags |= power_boost_limit ? PPSMC_STATEFLAG_POWERBOOST : 0;
> +
> +	for (i = 1; i < state->performance_level_count; i++) {
> +		prev_sclk = state->performance_levels[i-1].sclk;
> +		max_sclk  = state->performance_levels[i].sclk;
> +		max_ps_percent = (i != (state->performance_level_count - 1)) ?
> +			NISLANDS_DPM2_MAXPS_PERCENT_M : NISLANDS_DPM2_MAXPS_PERCENT_H;
> +
> +		if (max_sclk < prev_sclk)
> +			return -EINVAL;
> +
> +		if ((max_ps_percent == 0) || (prev_sclk == max_sclk) || eg_pi->uvd_enabled)
> +			min_sclk = max_sclk;
> +		else if (1 == i)
> +			min_sclk = prev_sclk;
> +		else
> +			min_sclk = (prev_sclk * (u32)max_ps_percent) / 100;
> +
> +		if (min_sclk < state->performance_levels[0].sclk)
> +			min_sclk = state->performance_levels[0].sclk;
> +
> +		if (min_sclk == 0)
> +			return -EINVAL;
> +
> +		smc_state->levels[i].dpm2.MaxPS =
> +			(u8)((NISLANDS_DPM2_MAX_PULSE_SKIP * (max_sclk - min_sclk)) / max_sclk);
> +		smc_state->levels[i].dpm2.NearTDPDec = NISLANDS_DPM2_NEAR_TDP_DEC;
> +		smc_state->levels[i].dpm2.AboveSafeInc = NISLANDS_DPM2_ABOVE_SAFE_INC;
> +		smc_state->levels[i].dpm2.BelowSafeInc = NISLANDS_DPM2_BELOW_SAFE_INC;
> +		smc_state->levels[i].stateFlags |=
> +			((i != (state->performance_level_count - 1)) && power_boost_limit) ?
> +			PPSMC_STATEFLAG_POWERBOOST : 0;
> +	}
> +
> +	return 0;
> +}
> +
> +static int ni_populate_sq_ramping_values(struct radeon_device *rdev,
> +					 struct radeon_ps *radeon_state,
> +					 NISLANDS_SMC_SWSTATE *smc_state)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	struct ni_ps *state = ni_get_ps(radeon_state);
> +	u32 sq_power_throttle;
> +	u32 sq_power_throttle2;
> +	bool enable_sq_ramping = ni_pi->enable_sq_ramping;
> +	int i;
> +
> +	if (state->performance_level_count == 0)
> +		return -EINVAL;
> +
> +	if (smc_state->levelCount != state->performance_level_count)
> +		return -EINVAL;
> +
> +	if (rdev->pm.dpm.sq_ramping_threshold == 0)
> +		return -EINVAL;
> +
> +	if (NISLANDS_DPM2_SQ_RAMP_MAX_POWER > (MAX_POWER_MASK >> MAX_POWER_SHIFT))
> +		enable_sq_ramping = false;
> +
> +	if (NISLANDS_DPM2_SQ_RAMP_MIN_POWER > (MIN_POWER_MASK >> MIN_POWER_SHIFT))
> +		enable_sq_ramping = false;
> +
> +	if (NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA > (MAX_POWER_DELTA_MASK >> MAX_POWER_DELTA_SHIFT))
> +		enable_sq_ramping = false;
> +
> +	if (NISLANDS_DPM2_SQ_RAMP_STI_SIZE > (STI_SIZE_MASK >> STI_SIZE_SHIFT))
> +		enable_sq_ramping = false;
> +
> +	if (NISLANDS_DPM2_SQ_RAMP_LTI_RATIO <= (LTI_RATIO_MASK >> LTI_RATIO_SHIFT))
> +		enable_sq_ramping = false;
> +
> +	for (i = 0; i < state->performance_level_count; i++) {
> +		sq_power_throttle  = 0;
> +		sq_power_throttle2 = 0;
> +
> +		if ((state->performance_levels[i].sclk >= rdev->pm.dpm.sq_ramping_threshold) &&
> +		    enable_sq_ramping) {
> +			sq_power_throttle |= MAX_POWER(NISLANDS_DPM2_SQ_RAMP_MAX_POWER);
> +			sq_power_throttle |= MIN_POWER(NISLANDS_DPM2_SQ_RAMP_MIN_POWER);
> +			sq_power_throttle2 |= MAX_POWER_DELTA(NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA);
> +			sq_power_throttle2 |= STI_SIZE(NISLANDS_DPM2_SQ_RAMP_STI_SIZE);
> +			sq_power_throttle2 |= LTI_RATIO(NISLANDS_DPM2_SQ_RAMP_LTI_RATIO);
> +		} else {
> +			sq_power_throttle |= MAX_POWER_MASK | MIN_POWER_MASK;
> +			sq_power_throttle2 |= MAX_POWER_DELTA_MASK | STI_SIZE_MASK | LTI_RATIO_MASK;
> +		}
> +
> +		smc_state->levels[i].SQPowerThrottle   = cpu_to_be32(sq_power_throttle);
> +		smc_state->levels[i].SQPowerThrottle_2 = cpu_to_be32(sq_power_throttle2);
> +	}
> +
> +	return 0;
> +}
> +
> +static int ni_enable_power_containment(struct radeon_device *rdev, bool enable)
> +{
> +        struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	PPSMC_Result smc_result;
> +	int ret = 0;
> +
> +	if (ni_pi->enable_power_containment) {
> +		if (enable) {
> +			struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
> +
> +			if (!r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
> +				smc_result = rv770_send_msg_to_smc(rdev, PPSMC_TDPClampingActive);
> +				if (smc_result != PPSMC_Result_OK) {
> +					ret = -EINVAL;
> +					ni_pi->pc_enabled = false;
> +				} else {
> +					ni_pi->pc_enabled = true;
> +				}
> +			}
> +		} else {
> +			smc_result = rv770_send_msg_to_smc(rdev, PPSMC_TDPClampingInactive);
> +			if (smc_result != PPSMC_Result_OK)
> +				ret = -EINVAL;
> +			ni_pi->pc_enabled = false;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int ni_convert_power_state_to_smc(struct radeon_device *rdev,
> +					 struct radeon_ps *radeon_state,
> +					 NISLANDS_SMC_SWSTATE *smc_state)
> +{
> +        struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	struct ni_ps *state = ni_get_ps(radeon_state);
> +	int i, ret;
> +	u32 threshold = state->performance_levels[state->performance_level_count - 1].sclk * 100 / 100;
> +
> +	if (!(radeon_state->caps & ATOM_PPLIB_DISALLOW_ON_DC))
> +		smc_state->flags |= PPSMC_SWSTATE_FLAG_DC;
> +
> +	smc_state->levelCount = 0;
> +
> +	if (state->performance_level_count > NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE)
> +		return -EINVAL;
> +
> +	for (i = 0; i < state->performance_level_count; i++) {
> +		ret = ni_convert_power_level_to_smc(rdev, &state->performance_levels[i],
> +						    &smc_state->levels[i]);
> +		smc_state->levels[i].arbRefreshState =
> +			(u8)(NISLANDS_DRIVER_STATE_ARB_INDEX + i);
> +
> +		if (ret)
> +			return ret;
> +
> +		if (ni_pi->enable_power_containment)
> +			smc_state->levels[i].displayWatermark =
> +				(state->performance_levels[i].sclk < threshold) ?
> +				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
> +		else
> +			smc_state->levels[i].displayWatermark = (i < 2) ?
> +				PPSMC_DISPLAY_WATERMARK_LOW : PPSMC_DISPLAY_WATERMARK_HIGH;
> +
> +		if (eg_pi->dynamic_ac_timing)
> +			smc_state->levels[i].ACIndex = NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i;
> +		else
> +			smc_state->levels[i].ACIndex = 0;
> +
> +		smc_state->levelCount++;
> +	}
> +
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_watermark_threshold,
> +				      cpu_to_be32(threshold / 512));
> +
> +	ni_populate_smc_sp(rdev, radeon_state, smc_state);
> +
> +	ret = ni_populate_power_containment_values(rdev, radeon_state, smc_state);
> +	if (ret)
> +		ni_pi->enable_power_containment = false;
> +
> +	ret = ni_populate_sq_ramping_values(rdev, radeon_state, smc_state);
> +	if (ret)
> +		ni_pi->enable_sq_ramping = false;
> +
> +	return ni_populate_smc_t(rdev, radeon_state, smc_state);
> +}
> +
> +static int ni_upload_sw_state(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
> +	u16 address = pi->state_table_start +
> +		offsetof(NISLANDS_SMC_STATETABLE, driverState);
> +	u16 state_size = sizeof(NISLANDS_SMC_SWSTATE) +
> +		((NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1) * sizeof(NISLANDS_SMC_HW_PERFORMANCE_LEVEL));
> +	int ret;
> +	NISLANDS_SMC_SWSTATE *smc_state = kzalloc(state_size, GFP_KERNEL);
> +
> +	if (smc_state == NULL)
> +		return -ENOMEM;
> +
> +	ret = ni_convert_power_state_to_smc(rdev, radeon_new_state, smc_state);
> +	if (ret)
> +		goto done;
> +
> +	ret = rv770_copy_bytes_to_smc(rdev, address, (u8 *)smc_state, state_size, pi->sram_end);
> +
> +done:
> +	kfree(smc_state);
> +
> +	return ret;
> +}
> +
> +static int ni_set_mc_special_registers(struct radeon_device *rdev,
> +				       struct ni_mc_reg_table *table)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	u8 i, j, k;
> +	u32 temp_reg;
> +
> +	for (i = 0, j = table->last; i < table->last; i++) {
> +		switch (table->mc_reg_address[i].s1) {
> +		case MC_SEQ_MISC1 >> 2:
> +			if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
> +				return -EINVAL;
> +			temp_reg = 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] =
> +					((temp_reg & 0xffff0000)) |
> +					((table->mc_reg_table_entry[k].mc_data[i] & 0xffff0000) >> 16);
> +			j++;
> +			if (j >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
> +				return -EINVAL;
> +
> +			temp_reg = 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] =
> +					(temp_reg & 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_NISLANDS_MC_REGISTER_ARRAY_SIZE)
> +				return -EINVAL;
> +			break;
> +		case MC_SEQ_RESERVE_M >> 2:
> +			temp_reg = 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] =
> +					(temp_reg & 0xffff0000) |
> +					(table->mc_reg_table_entry[k].mc_data[i] & 0x0000ffff);
> +			j++;
> +			if (j > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
> +				return -EINVAL;
> +			break;
> +		default:
> +			break;
> +		}
> +	}
> +
> +	table->last = j;
> +
> +	return 0;
> +}
> +
> +static bool ni_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;
> +        case MC_SEQ_PMG_TIMING >> 2:
> +		*out_reg = MC_SEQ_PMG_TIMING_LP >> 2;
> +		break;
> +        case MC_PMG_CMD_MRS2 >> 2:
> +		*out_reg = MC_SEQ_PMG_CMD_MRS2_LP >> 2;
> +		break;
> +        default:
> +		result = false;
> +		break;
> +	}
> +
> +	return result;
> +}
> +
> +static void ni_set_valid_flag(struct ni_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 void ni_set_s0_mc_reg_index(struct ni_mc_reg_table *table)
> +{
> +	u32 i;
> +	u16 address;
> +
> +	for (i = 0; i < table->last; i++)
> +		table->mc_reg_address[i].s0 =
> +			ni_check_s0_mc_reg_index(table->mc_reg_address[i].s1, &address) ?
> +			address : table->mc_reg_address[i].s1;
> +}
> +
> +static int ni_copy_vbios_mc_reg_table(struct atom_mc_reg_table *table,
> +				      struct ni_mc_reg_table *ni_table)
> +{
> +	u8 i, j;
> +
> +	if (table->last > SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
> +		return -EINVAL;
> +	if (table->num_entries > MAX_AC_TIMING_ENTRIES)
> +		return -EINVAL;
> +
> +	for (i = 0; i < table->last; i++)
> +		ni_table->mc_reg_address[i].s1 = table->mc_reg_address[i].s1;
> +	ni_table->last = table->last;
> +
> +	for (i = 0; i < table->num_entries; i++) {
> +		ni_table->mc_reg_table_entry[i].mclk_max =
> +			table->mc_reg_table_entry[i].mclk_max;
> +		for (j = 0; j < table->last; j++)
> +			ni_table->mc_reg_table_entry[i].mc_data[j] =
> +				table->mc_reg_table_entry[i].mc_data[j];
> +	}
> +	ni_table->num_entries = table->num_entries;
> +
> +	return 0;
> +}
> +
> +static int ni_initialize_mc_reg_table(struct radeon_device *rdev)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	int ret;
> +	struct atom_mc_reg_table *table;
> +	struct ni_mc_reg_table *ni_table = &ni_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;
> +
> +	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_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));
> +	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_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_PMG_TIMING_LP, RREG32(MC_SEQ_PMG_TIMING));
> +	WREG32(MC_SEQ_PMG_CMD_MRS2_LP, RREG32(MC_PMG_CMD_MRS2));
> +
> +	ret = radeon_atom_init_mc_reg_table(rdev, module_index, table);
> +
> +        if (ret)
> +                goto init_mc_done;
> +
> +	ret = ni_copy_vbios_mc_reg_table(table, ni_table);
> +
> +        if (ret)
> +                goto init_mc_done;
> +
> +	ni_set_s0_mc_reg_index(ni_table);
> +
> +	ret = ni_set_mc_special_registers(rdev, ni_table);
> +
> +        if (ret)
> +                goto init_mc_done;
> +
> +	ni_set_valid_flag(ni_table);
> +
> +init_mc_done:
> +        kfree(table);
> +
> +	return ret;
> +}
> +
> +static void ni_populate_mc_reg_addresses(struct radeon_device *rdev,
> +					 SMC_NIslands_MCRegisters *mc_reg_table)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 i, j;
> +
> +	for (i = 0, j = 0; j < ni_pi->mc_reg_table.last; j++) {
> +		if (ni_pi->mc_reg_table.valid_flag & (1 << j)) {
> +			if (i >= SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE)
> +				break;
> +			mc_reg_table->address[i].s0 =
> +				cpu_to_be16(ni_pi->mc_reg_table.mc_reg_address[j].s0);
> +			mc_reg_table->address[i].s1 =
> +				cpu_to_be16(ni_pi->mc_reg_table.mc_reg_address[j].s1);
> +			i++;
> +		}
> +	}
> +	mc_reg_table->last = (u8)i;
> +}
> +
> +
> +static void ni_convert_mc_registers(struct ni_mc_reg_entry *entry,
> +				    SMC_NIslands_MCRegisterSet *data,
> +				    u32 num_entries, u32 valid_flag)
> +{
> +	u32 i, j;
> +
> +	for (i = 0, j = 0; j < num_entries; j++) {
> +		if (valid_flag & (1 << j)) {
> +			data->value[i] = cpu_to_be32(entry->mc_data[j]);
> +			i++;
> +		}
> +	}
> +}
> +
> +static void ni_convert_mc_reg_table_entry_to_smc(struct radeon_device *rdev,
> +						 struct rv7xx_pl *pl,
> +						 SMC_NIslands_MCRegisterSet *mc_reg_table_data)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 i = 0;
> +
> +	for (i = 0; i < ni_pi->mc_reg_table.num_entries; i++) {
> +		if (pl->mclk <= ni_pi->mc_reg_table.mc_reg_table_entry[i].mclk_max)
> +			break;
> +	}
> +
> +	if ((i == ni_pi->mc_reg_table.num_entries) && (i > 0))
> +		--i;
> +
> +	ni_convert_mc_registers(&ni_pi->mc_reg_table.mc_reg_table_entry[i],
> +				mc_reg_table_data,
> +				ni_pi->mc_reg_table.last,
> +				ni_pi->mc_reg_table.valid_flag);
> +}
> +
> +static void ni_convert_mc_reg_table_to_smc(struct radeon_device *rdev,
> +					   struct radeon_ps *radeon_state,
> +					   SMC_NIslands_MCRegisters *mc_reg_table)
> +{
> +	struct ni_ps *state = ni_get_ps(radeon_state);
> +	int i;
> +
> +	for (i = 0; i < state->performance_level_count; i++) {
> +		ni_convert_mc_reg_table_entry_to_smc(rdev,
> +						     &state->performance_levels[i],
> +						     &mc_reg_table->data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT + i]);
> +	}
> +}
> +
> +static int ni_populate_mc_reg_table(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +        struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +        struct radeon_ps *radeon_boot_state = rdev->pm.dpm.boot_ps;
> +	struct ni_ps *boot_state = ni_get_ps(radeon_boot_state);
> +	SMC_NIslands_MCRegisters *mc_reg_table = &ni_pi->smc_mc_reg_table;
> +
> +	memset(mc_reg_table, 0, sizeof(SMC_NIslands_MCRegisters));
> +
> +	rv770_write_smc_soft_register(rdev, NI_SMC_SOFT_REGISTER_seq_index, 1);
> +
> +	ni_populate_mc_reg_addresses(rdev, mc_reg_table);
> +
> +	ni_convert_mc_reg_table_entry_to_smc(rdev, &boot_state->performance_levels[0],
> +					     &mc_reg_table->data[0]);
> +
> +	ni_convert_mc_registers(&ni_pi->mc_reg_table.mc_reg_table_entry[0],
> +				&mc_reg_table->data[1],
> +				ni_pi->mc_reg_table.last,
> +				ni_pi->mc_reg_table.valid_flag);
> +
> +	ni_convert_mc_reg_table_to_smc(rdev, radeon_boot_state, mc_reg_table);
> +
> +	return rv770_copy_bytes_to_smc(rdev, eg_pi->mc_reg_table_start,
> +				       (u8 *)mc_reg_table,
> +				       sizeof(SMC_NIslands_MCRegisters),
> +				       pi->sram_end);
> +}
> +
> +static int ni_upload_mc_reg_table(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +        struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
> +	struct ni_ps *ni_new_state = ni_get_ps(radeon_new_state);
> +	SMC_NIslands_MCRegisters *mc_reg_table = &ni_pi->smc_mc_reg_table;
> +	u16 address;
> +
> +	memset(mc_reg_table, 0, sizeof(SMC_NIslands_MCRegisters));
> +
> +	ni_convert_mc_reg_table_to_smc(rdev, radeon_new_state, mc_reg_table);
> +
> +	address = eg_pi->mc_reg_table_start +
> +		(u16)offsetof(SMC_NIslands_MCRegisters, data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT]);
> +
> +	return rv770_copy_bytes_to_smc(rdev, address,
> +				       (u8 *)&mc_reg_table->data[NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT],
> +				       sizeof(SMC_NIslands_MCRegisterSet) * ni_new_state->performance_level_count,
> +				       pi->sram_end);
> +}
> +
> +static int ni_init_driver_calculated_leakage_table(struct radeon_device *rdev,
> +						   PP_NIslands_CACTABLES *cac_tables)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	u32 leakage = 0;
> +	unsigned int i, j, table_size;
> +	s32 t;
> +	u32 smc_leakage, max_leakage = 0;
> +	u32 scaling_factor;
> +
> +	table_size = eg_pi->vddc_voltage_table.count;
> +
> +	if (SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES < table_size)
> +		table_size = SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
> +
> +	scaling_factor = ni_get_smc_power_scaling_factor(rdev);
> +
> +	for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++) {
> +		for (j = 0; j < table_size; j++) {
> +			t = (1000 * ((i + 1) * 8));
> +
> +			if (t < ni_pi->cac_data.leakage_minimum_temperature)
> +				t = ni_pi->cac_data.leakage_minimum_temperature;
> +
> +			ni_calculate_leakage_for_v_and_t(rdev,
> +							 &ni_pi->cac_data.leakage_coefficients,
> +							 eg_pi->vddc_voltage_table.entries[j].value,
> +							 t,
> +							 ni_pi->cac_data.i_leakage,
> +							 &leakage);
> +
> +			smc_leakage = ni_scale_power_for_smc(leakage, scaling_factor) / 1000;
> +			if (smc_leakage > max_leakage)
> +				max_leakage = smc_leakage;
> +
> +			cac_tables->cac_lkge_lut[i][j] = cpu_to_be32(smc_leakage);
> +		}
> +	}
> +
> +	for (j = table_size; j < SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
> +		for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
> +			cac_tables->cac_lkge_lut[i][j] = cpu_to_be32(max_leakage);
> +	}
> +	return 0;
> +}
> +
> +static int ni_init_simplified_leakage_table(struct radeon_device *rdev,
> +					    PP_NIslands_CACTABLES *cac_tables)
> +{
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	struct radeon_cac_leakage_table *leakage_table =
> +		&rdev->pm.dpm.dyn_state.cac_leakage_table;
> +	u32 i, j, table_size;
> +	u32 smc_leakage, max_leakage = 0;
> +	u32 scaling_factor;
> +
> +	if (!leakage_table)
> +		return -EINVAL;
> +
> +	table_size = leakage_table->count;
> +
> +	if (eg_pi->vddc_voltage_table.count != table_size)
> +		table_size = (eg_pi->vddc_voltage_table.count < leakage_table->count) ?
> +			eg_pi->vddc_voltage_table.count : leakage_table->count;
> +
> +	if (SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES < table_size)
> +		table_size = SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES;
> +
> +	if (table_size == 0)
> +		return -EINVAL;
> +
> +	scaling_factor = ni_get_smc_power_scaling_factor(rdev);
> +
> +	for (j = 0; j < table_size; j++) {
> +		smc_leakage = leakage_table->entries[j].leakage;
> +
> +		if (smc_leakage > max_leakage)
> +			max_leakage = smc_leakage;
> +
> +		for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
> +			cac_tables->cac_lkge_lut[i][j] =
> +				cpu_to_be32(ni_scale_power_for_smc(smc_leakage, scaling_factor));
> +	}
> +
> +	for (j = table_size; j < SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES; j++) {
> +		for (i = 0; i < SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES; i++)
> +			cac_tables->cac_lkge_lut[i][j] =
> +				cpu_to_be32(ni_scale_power_for_smc(max_leakage, scaling_factor));
> +	}
> +	return 0;
> +}
> +
> +static int ni_initialize_smc_cac_tables(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	PP_NIslands_CACTABLES *cac_tables = NULL;
> +	int i, ret;
> +        u32 reg;
> +
> +	if (ni_pi->enable_cac == false)
> +		return 0;
> +
> +	cac_tables = kzalloc(sizeof(PP_NIslands_CACTABLES), GFP_KERNEL);
> +	if (!cac_tables)
> +		return -ENOMEM;
> +
> +	reg = RREG32(CG_CAC_CTRL) & ~(TID_CNT_MASK | TID_UNIT_MASK);
> +	reg |= (TID_CNT(ni_pi->cac_weights->tid_cnt) |
> +		TID_UNIT(ni_pi->cac_weights->tid_unit));
> +	WREG32(CG_CAC_CTRL, reg);
> +
> +	for (i = 0; i < NISLANDS_DCCAC_MAX_LEVELS; i++)
> +		ni_pi->dc_cac_table[i] = ni_pi->cac_weights->dc_cac[i];
> +
> +	for (i = 0; i < SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES; i++)
> +		cac_tables->cac_bif_lut[i] = ni_pi->cac_weights->pcie_cac[i];
> +
> +	ni_pi->cac_data.i_leakage = rdev->pm.dpm.cac_leakage;
> +	ni_pi->cac_data.pwr_const = 0;
> +	ni_pi->cac_data.dc_cac_value = ni_pi->dc_cac_table[NISLANDS_DCCAC_LEVEL_0];
> +	ni_pi->cac_data.bif_cac_value = 0;
> +	ni_pi->cac_data.mc_wr_weight = ni_pi->cac_weights->mc_write_weight;
> +	ni_pi->cac_data.mc_rd_weight = ni_pi->cac_weights->mc_read_weight;
> +	ni_pi->cac_data.allow_ovrflw = 0;
> +	ni_pi->cac_data.l2num_win_tdp = ni_pi->lta_window_size;
> +	ni_pi->cac_data.num_win_tdp = 0;
> +	ni_pi->cac_data.lts_truncate_n = ni_pi->lts_truncate;
> +
> +	if (ni_pi->driver_calculate_cac_leakage)
> +		ret = ni_init_driver_calculated_leakage_table(rdev, cac_tables);
> +	else
> +		ret = ni_init_simplified_leakage_table(rdev, cac_tables);
> +
> +	if (ret)
> +		goto done_free;
> +
> +	cac_tables->pwr_const      = cpu_to_be32(ni_pi->cac_data.pwr_const);
> +	cac_tables->dc_cacValue    = cpu_to_be32(ni_pi->cac_data.dc_cac_value);
> +	cac_tables->bif_cacValue   = cpu_to_be32(ni_pi->cac_data.bif_cac_value);
> +	cac_tables->AllowOvrflw    = ni_pi->cac_data.allow_ovrflw;
> +	cac_tables->MCWrWeight     = ni_pi->cac_data.mc_wr_weight;
> +	cac_tables->MCRdWeight     = ni_pi->cac_data.mc_rd_weight;
> +	cac_tables->numWin_TDP     = ni_pi->cac_data.num_win_tdp;
> +	cac_tables->l2numWin_TDP   = ni_pi->cac_data.l2num_win_tdp;
> +	cac_tables->lts_truncate_n = ni_pi->cac_data.lts_truncate_n;
> +
> +	ret = rv770_copy_bytes_to_smc(rdev, ni_pi->cac_table_start, (u8 *)cac_tables,
> +				      sizeof(PP_NIslands_CACTABLES), pi->sram_end);
> +
> +done_free:
> +	if (ret) {
> +		ni_pi->enable_cac = false;
> +		ni_pi->enable_power_containment = false;
> +	}
> +
> +	kfree(cac_tables);
> +
> +	return 0;
> +}
> +
> +static int ni_initialize_hardware_cac_manager(struct radeon_device *rdev)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	u32 reg;
> +
> +	if (!ni_pi->enable_cac ||
> +	    !ni_pi->cac_configuration_required)
> +		return 0;
> +
> +	if (ni_pi->cac_weights == NULL)
> +		return -EINVAL;
> +
> +	reg = RREG32_CG(CG_CAC_REGION_1_WEIGHT_0) & ~(WEIGHT_TCP_SIG0_MASK |
> +						      WEIGHT_TCP_SIG1_MASK |
> +						      WEIGHT_TA_SIG_MASK);
> +	reg |= (WEIGHT_TCP_SIG0(ni_pi->cac_weights->weight_tcp_sig0) |
> +		WEIGHT_TCP_SIG1(ni_pi->cac_weights->weight_tcp_sig1) |
> +		WEIGHT_TA_SIG(ni_pi->cac_weights->weight_ta_sig));
> +	WREG32_CG(CG_CAC_REGION_1_WEIGHT_0, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_1_WEIGHT_1) & ~(WEIGHT_TCC_EN0_MASK |
> +						      WEIGHT_TCC_EN1_MASK |
> +						      WEIGHT_TCC_EN2_MASK);
> +	reg |= (WEIGHT_TCC_EN0(ni_pi->cac_weights->weight_tcc_en0) |
> +		WEIGHT_TCC_EN1(ni_pi->cac_weights->weight_tcc_en1) |
> +		WEIGHT_TCC_EN2(ni_pi->cac_weights->weight_tcc_en2));
> +	WREG32_CG(CG_CAC_REGION_1_WEIGHT_1, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_0) & ~(WEIGHT_CB_EN0_MASK |
> +						      WEIGHT_CB_EN1_MASK |
> +						      WEIGHT_CB_EN2_MASK |
> +						      WEIGHT_CB_EN3_MASK);
> +	reg |= (WEIGHT_CB_EN0(ni_pi->cac_weights->weight_cb_en0) |
> +		WEIGHT_CB_EN1(ni_pi->cac_weights->weight_cb_en1) |
> +		WEIGHT_CB_EN2(ni_pi->cac_weights->weight_cb_en2) |
> +		WEIGHT_CB_EN3(ni_pi->cac_weights->weight_cb_en3));
> +	WREG32_CG(CG_CAC_REGION_2_WEIGHT_0, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_1) & ~(WEIGHT_DB_SIG0_MASK |
> +						      WEIGHT_DB_SIG1_MASK |
> +						      WEIGHT_DB_SIG2_MASK |
> +						      WEIGHT_DB_SIG3_MASK);
> +	reg |= (WEIGHT_DB_SIG0(ni_pi->cac_weights->weight_db_sig0) |
> +		WEIGHT_DB_SIG1(ni_pi->cac_weights->weight_db_sig1) |
> +		WEIGHT_DB_SIG2(ni_pi->cac_weights->weight_db_sig2) |
> +		WEIGHT_DB_SIG3(ni_pi->cac_weights->weight_db_sig3));
> +	WREG32_CG(CG_CAC_REGION_2_WEIGHT_1, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_2_WEIGHT_2) & ~(WEIGHT_SXM_SIG0_MASK |
> +						      WEIGHT_SXM_SIG1_MASK |
> +						      WEIGHT_SXM_SIG2_MASK |
> +						      WEIGHT_SXS_SIG0_MASK |
> +						      WEIGHT_SXS_SIG1_MASK);
> +	reg |= (WEIGHT_SXM_SIG0(ni_pi->cac_weights->weight_sxm_sig0) |
> +		WEIGHT_SXM_SIG1(ni_pi->cac_weights->weight_sxm_sig1) |
> +		WEIGHT_SXM_SIG2(ni_pi->cac_weights->weight_sxm_sig2) |
> +		WEIGHT_SXS_SIG0(ni_pi->cac_weights->weight_sxs_sig0) |
> +		WEIGHT_SXS_SIG1(ni_pi->cac_weights->weight_sxs_sig1));
> +	WREG32_CG(CG_CAC_REGION_2_WEIGHT_2, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_3_WEIGHT_0) & ~(WEIGHT_XBR_0_MASK |
> +						      WEIGHT_XBR_1_MASK |
> +						      WEIGHT_XBR_2_MASK |
> +						      WEIGHT_SPI_SIG0_MASK);
> +	reg |= (WEIGHT_XBR_0(ni_pi->cac_weights->weight_xbr_0) |
> +		WEIGHT_XBR_1(ni_pi->cac_weights->weight_xbr_1) |
> +		WEIGHT_XBR_2(ni_pi->cac_weights->weight_xbr_2) |
> +		WEIGHT_SPI_SIG0(ni_pi->cac_weights->weight_spi_sig0));
> +	WREG32_CG(CG_CAC_REGION_3_WEIGHT_0, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_3_WEIGHT_1) & ~(WEIGHT_SPI_SIG1_MASK |
> +						      WEIGHT_SPI_SIG2_MASK |
> +						      WEIGHT_SPI_SIG3_MASK |
> +						      WEIGHT_SPI_SIG4_MASK |
> +						      WEIGHT_SPI_SIG5_MASK);
> +	reg |= (WEIGHT_SPI_SIG1(ni_pi->cac_weights->weight_spi_sig1) |
> +		WEIGHT_SPI_SIG2(ni_pi->cac_weights->weight_spi_sig2) |
> +		WEIGHT_SPI_SIG3(ni_pi->cac_weights->weight_spi_sig3) |
> +		WEIGHT_SPI_SIG4(ni_pi->cac_weights->weight_spi_sig4) |
> +		WEIGHT_SPI_SIG5(ni_pi->cac_weights->weight_spi_sig5));
> +	WREG32_CG(CG_CAC_REGION_3_WEIGHT_1, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_0) & ~(WEIGHT_LDS_SIG0_MASK |
> +						      WEIGHT_LDS_SIG1_MASK |
> +						      WEIGHT_SC_MASK);
> +	reg |= (WEIGHT_LDS_SIG0(ni_pi->cac_weights->weight_lds_sig0) |
> +		WEIGHT_LDS_SIG1(ni_pi->cac_weights->weight_lds_sig1) |
> +		WEIGHT_SC(ni_pi->cac_weights->weight_sc));
> +	WREG32_CG(CG_CAC_REGION_4_WEIGHT_0, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_1) & ~(WEIGHT_BIF_MASK |
> +						      WEIGHT_CP_MASK |
> +						      WEIGHT_PA_SIG0_MASK |
> +						      WEIGHT_PA_SIG1_MASK |
> +						      WEIGHT_VGT_SIG0_MASK);
> +	reg |= (WEIGHT_BIF(ni_pi->cac_weights->weight_bif) |
> +		WEIGHT_CP(ni_pi->cac_weights->weight_cp) |
> +		WEIGHT_PA_SIG0(ni_pi->cac_weights->weight_pa_sig0) |
> +		WEIGHT_PA_SIG1(ni_pi->cac_weights->weight_pa_sig1) |
> +		WEIGHT_VGT_SIG0(ni_pi->cac_weights->weight_vgt_sig0));
> +	WREG32_CG(CG_CAC_REGION_4_WEIGHT_1, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_2) & ~(WEIGHT_VGT_SIG1_MASK |
> +						      WEIGHT_VGT_SIG2_MASK |
> +						      WEIGHT_DC_SIG0_MASK |
> +						      WEIGHT_DC_SIG1_MASK |
> +						      WEIGHT_DC_SIG2_MASK);
> +	reg |= (WEIGHT_VGT_SIG1(ni_pi->cac_weights->weight_vgt_sig1) |
> +		WEIGHT_VGT_SIG2(ni_pi->cac_weights->weight_vgt_sig2) |
> +		WEIGHT_DC_SIG0(ni_pi->cac_weights->weight_dc_sig0) |
> +		WEIGHT_DC_SIG1(ni_pi->cac_weights->weight_dc_sig1) |
> +		WEIGHT_DC_SIG2(ni_pi->cac_weights->weight_dc_sig2));
> +	WREG32_CG(CG_CAC_REGION_4_WEIGHT_2, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_4_WEIGHT_3) & ~(WEIGHT_DC_SIG3_MASK |
> +						      WEIGHT_UVD_SIG0_MASK |
> +						      WEIGHT_UVD_SIG1_MASK |
> +						      WEIGHT_SPARE0_MASK |
> +						      WEIGHT_SPARE1_MASK);
> +	reg |= (WEIGHT_DC_SIG3(ni_pi->cac_weights->weight_dc_sig3) |
> +		WEIGHT_UVD_SIG0(ni_pi->cac_weights->weight_uvd_sig0) |
> +		WEIGHT_UVD_SIG1(ni_pi->cac_weights->weight_uvd_sig1) |
> +		WEIGHT_SPARE0(ni_pi->cac_weights->weight_spare0) |
> +		WEIGHT_SPARE1(ni_pi->cac_weights->weight_spare1));
> +	WREG32_CG(CG_CAC_REGION_4_WEIGHT_3, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_5_WEIGHT_0) & ~(WEIGHT_SQ_VSP_MASK |
> +						      WEIGHT_SQ_VSP0_MASK);
> +	reg |= (WEIGHT_SQ_VSP(ni_pi->cac_weights->weight_sq_vsp) |
> +		WEIGHT_SQ_VSP0(ni_pi->cac_weights->weight_sq_vsp0));
> +	WREG32_CG(CG_CAC_REGION_5_WEIGHT_0, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_5_WEIGHT_1) & ~(WEIGHT_SQ_GPR_MASK);
> +	reg |= WEIGHT_SQ_GPR(ni_pi->cac_weights->weight_sq_gpr);
> +	WREG32_CG(CG_CAC_REGION_5_WEIGHT_1, reg);
> +
> +	reg = RREG32_CG(CG_CAC_REGION_4_OVERRIDE_4) & ~(OVR_MODE_SPARE_0_MASK |
> +							OVR_VAL_SPARE_0_MASK |
> +							OVR_MODE_SPARE_1_MASK |
> +							OVR_VAL_SPARE_1_MASK);
> +	reg |= (OVR_MODE_SPARE_0(ni_pi->cac_weights->ovr_mode_spare_0) |
> +		OVR_VAL_SPARE_0(ni_pi->cac_weights->ovr_val_spare_0) |
> +		OVR_MODE_SPARE_1(ni_pi->cac_weights->ovr_mode_spare_1) |
> +		OVR_VAL_SPARE_1(ni_pi->cac_weights->ovr_val_spare_1));
> +	WREG32_CG(CG_CAC_REGION_4_OVERRIDE_4, reg);
> +
> +	reg = RREG32(SQ_CAC_THRESHOLD) & ~(VSP_MASK |
> +					   VSP0_MASK |
> +					   GPR_MASK);
> +	reg |= (VSP(ni_pi->cac_weights->vsp) |
> +		VSP0(ni_pi->cac_weights->vsp0) |
> +		GPR(ni_pi->cac_weights->gpr));
> +	WREG32(SQ_CAC_THRESHOLD, reg);
> +
> +	reg = (MCDW_WR_ENABLE |
> +	       MCDX_WR_ENABLE |
> +	       MCDY_WR_ENABLE |
> +	       MCDZ_WR_ENABLE |
> +	       INDEX(0x09D4));
> +	WREG32(MC_CG_CONFIG, reg);
> +
> +	reg = (READ_WEIGHT(ni_pi->cac_weights->mc_read_weight) |
> +	       WRITE_WEIGHT(ni_pi->cac_weights->mc_write_weight) |
> +	       ALLOW_OVERFLOW);
> +	WREG32(MC_CG_DATAPORT, reg);
> +
> +	return 0;
> +}
> +
> +static int ni_enable_smc_cac(struct radeon_device *rdev, bool enable)
> +{
> +	struct ni_power_info *ni_pi = ni_get_pi(rdev);
> +	int ret = 0;
> +	PPSMC_Result smc_result;
> +
> +	if (ni_pi->enable_cac) {
> +		if (enable) {
> +			struct radeon_ps *radeon_new_state = rdev->pm.dpm.requested_ps;
> +
> +			if (!r600_is_uvd_state(radeon_new_state->class, radeon_new_state->class2)) {
> +				smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_CollectCAC_PowerCorreln);
> +
> +				if (ni_pi->support_cac_long_term_average) {
> +					smc_result = rv770_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgEnable);
> +					if (PPSMC_Result_OK != smc_result)
> +						ni_pi->support_cac_long_term_average = false;
> +				}
> +
> +				smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_EnableCac);
> +				if (PPSMC_Result_OK != smc_result)
> +					ret = -EINVAL;
> +
> +				ni_pi->cac_enabled = (PPSMC_Result_OK == smc_result) ? true : false;
> +			}
> +		} else if (ni_pi->cac_enabled) {
> +			smc_result = rv770_send_msg_to_smc(rdev, PPSMC_MSG_DisableCac);
> +
> +			ni_pi->cac_enabled = false;
> +
> +			if (ni_pi->support_cac_long_term_average) {
> +				smc_result = rv770_send_msg_to_smc(rdev, PPSMC_CACLongTermAvgDisable);
> +				if (PPSMC_Result_OK != smc_result)
> +					ni_pi->support_cac_long_term_average = false;
> +			}
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int ni_pcie_performance_request(struct radeon_device *rdev,
> +				       u8 perf_req, bool advertise)
> +{
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +
> +#if defined(CONFIG_ACPI)
> +	if ((perf_req == PCIE_PERF_REQ_PECI_GEN1) ||
> +            (perf_req == PCIE_PERF_REQ_PECI_GEN2)) {
> +		if (eg_pi->pcie_performance_request_registered == false)
> +			radeon_acpi_pcie_notify_device_ready(rdev);
> +		eg_pi->pcie_performance_request_registered = true;
> +		return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise);
> +	} else if ((perf_req == PCIE_PERF_REQ_REMOVE_REGISTRY) &&
> +                   eg_pi->pcie_performance_request_registered) {
> +		eg_pi->pcie_performance_request_registered = false;
> +		return radeon_acpi_pcie_performance_request(rdev, perf_req, advertise);
> +	}
> +#endif
> +	return 0;
> +}
> +
> +static int ni_advertise_gen2_capability(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	u32 tmp;
> +
> +        tmp = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
> +
> +        if ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
> +            (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2))
> +                pi->pcie_gen2 = true;
> +        else
> +		pi->pcie_gen2 = false;
> +
> +	if (!pi->pcie_gen2)
> +		ni_pcie_performance_request(rdev, PCIE_PERF_REQ_PECI_GEN2, true);
> +
> +	return 0;
> +}
> +
> +static void ni_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 ((tmp & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
> +	    (tmp & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
> +		if (enable) {
> +			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);
> +			udelay(10);
> +			tmp &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
> +			WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, tmp);
> +		} else {
> +			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 ni_enable_dynamic_pcie_gen2(struct radeon_device *rdev,
> +					bool enable)
> +{
> +	ni_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);
> +}
> +
> +void ni_dpm_setup_asic(struct radeon_device *rdev)
> +{
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +
> +	ni_read_clock_registers(rdev);
> +	btc_read_arb_registers(rdev);
> +	rv770_get_memory_type(rdev);
> +	if (eg_pi->pcie_performance_request)
> +		ni_advertise_gen2_capability(rdev);
> +	rv770_get_pcie_gen2_status(rdev);
> +	rv770_enable_acpi_pm(rdev);
> +}
> +
> +int ni_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);
> +
> +	if (pi->gfx_clock_gating)
> +		ni_cg_clockgating_default(rdev);
> +        if (btc_dpm_enabled(rdev))
> +                return -EINVAL;
> +	if (pi->mg_clock_gating)
> +		ni_mg_clockgating_default(rdev);
> +	if (eg_pi->ls_clock_gating)
> +		ni_ls_clockgating_default(rdev);
> +	if (pi->voltage_control) {
> +		rv770_enable_voltage_control(rdev, true);
> +		cypress_construct_voltage_tables(rdev);
> +	}
> +	if (eg_pi->dynamic_ac_timing)
> +		ni_initialize_mc_reg_table(rdev);
> +	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);
> +	cypress_enable_display_gap(rdev);
> +	rv770_program_vc(rdev);
> +	if (pi->dynamic_pcie_gen2)
> +		ni_enable_dynamic_pcie_gen2(rdev, true);
> +	if (rv770_upload_firmware(rdev))
> +		return -EINVAL;
> +	ni_process_firmware_header(rdev);
> +	ni_initial_switch_from_arb_f0_to_f1(rdev);
> +	ni_init_smc_table(rdev);
> +	ni_init_smc_spll_table(rdev);
> +	ni_init_arb_table_index(rdev);
> +	if (eg_pi->dynamic_ac_timing)
> +		ni_populate_mc_reg_table(rdev);
> +	ni_initialize_smc_cac_tables(rdev);
> +	ni_initialize_hardware_cac_manager(rdev);
> +	ni_populate_smc_tdp_limits(rdev);
> +	ni_program_response_times(rdev);
> +	r7xx_start_smc(rdev);
> +	cypress_notify_smc_display_change(rdev, false);
> +	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)
> +		ni_gfx_clockgating_enable(rdev, true);
> +	if (pi->mg_clock_gating)
> +		ni_mg_clockgating_enable(rdev, true);
> +	if (eg_pi->ls_clock_gating)
> +		ni_ls_clockgating_enable(rdev, true);
> +
> +	if (rdev->irq.installed &&
> +	    r600_is_internal_thermal_sensor(rdev->pm.int_thermal_type)) {
> +		PPSMC_Result result;
> +
> +		rv770_set_thermal_temperature_range(rdev, R600_TEMP_RANGE_MIN, 0xff * 1000);
> +		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);
> +
> +	return 0;
> +}
> +
> +void ni_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);
> +	ni_enable_power_containment(rdev, false);
> +	ni_enable_smc_cac(rdev, false);
> +	cypress_enable_spread_spectrum(rdev, false);
> +	rv770_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, false);
> +	if (pi->dynamic_pcie_gen2)
> +		ni_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)
> +		ni_gfx_clockgating_enable(rdev, false);
> +	if (pi->mg_clock_gating)
> +		ni_mg_clockgating_enable(rdev, false);
> +	if (eg_pi->ls_clock_gating)
> +		ni_ls_clockgating_enable(rdev, false);
> +	ni_stop_dpm(rdev);
> +	btc_reset_to_default(rdev);
> +	ni_stop_smc(rdev);
> +	ni_force_switch_to_arb_f0(rdev);
> +}
> +
> +int ni_power_control_set_level(struct radeon_device *rdev)
> +{
> +	ni_restrict_performance_levels_before_switch(rdev);
> +	rv770_halt_smc(rdev);
> +	ni_populate_smc_tdp_limits(rdev);
> +	rv770_resume_smc(rdev);
> +	rv770_set_sw_state(rdev);
> +
> +	return 0;
> +}
> +
> +int ni_dpm_set_power_state(struct radeon_device *rdev)
> +{
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	int ret;
> +
> +	ni_apply_state_adjust_rules(rdev);
> +
> +	ni_restrict_performance_levels_before_switch(rdev);
> +	ni_enable_power_containment(rdev, false);
> +	ni_enable_smc_cac(rdev, false);
> +	rv770_halt_smc(rdev);
> +	if (eg_pi->smu_uvd_hs)
> +		btc_notify_uvd_to_smc(rdev);
> +	ni_upload_sw_state(rdev);
> +	if (eg_pi->dynamic_ac_timing)
> +		ni_upload_mc_reg_table(rdev);
> +	ret = ni_program_memory_timing_parameters(rdev);
> +	if (ret)
> +		return ret;
> +	rv770_resume_smc(rdev);
> +	rv770_set_sw_state(rdev);
> +	ni_enable_smc_cac(rdev, true);
> +	ni_enable_power_containment(rdev, true);
> +
> +	return 0;
> +}
> +
> +void ni_dpm_reset_asic(struct radeon_device *rdev)
> +{
> +	ni_restrict_performance_levels_before_switch(rdev);
> +	rv770_set_boot_state(rdev);
> +}
> +
> +union power_info {
> +	struct _ATOM_POWERPLAY_INFO info;
> +	struct _ATOM_POWERPLAY_INFO_V2 info_2;
> +	struct _ATOM_POWERPLAY_INFO_V3 info_3;
> +	struct _ATOM_PPLIB_POWERPLAYTABLE pplib;
> +	struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2;
> +	struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3;
> +};
> +
> +union pplib_clock_info {
> +	struct _ATOM_PPLIB_R600_CLOCK_INFO r600;
> +	struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780;
> +	struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen;
> +	struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo;
> +};
> +
> +union pplib_power_state {
> +	struct _ATOM_PPLIB_STATE v1;
> +	struct _ATOM_PPLIB_STATE_V2 v2;
> +};
> +
> +static void ni_parse_pplib_non_clock_info(struct radeon_device *rdev,
> +					  struct radeon_ps *rps,
> +					  struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info,
> +					  u8 table_rev)
> +{
> +	rps->caps = le32_to_cpu(non_clock_info->ulCapsAndSettings);
> +	rps->class = le16_to_cpu(non_clock_info->usClassification);
> +	rps->class2 = le16_to_cpu(non_clock_info->usClassification2);
> +
> +	if (ATOM_PPLIB_NONCLOCKINFO_VER1 < table_rev) {
> +		rps->vclk = le32_to_cpu(non_clock_info->ulVCLK);
> +		rps->dclk = le32_to_cpu(non_clock_info->ulDCLK);
> +	} else if (r600_is_uvd_state(rps->class, rps->class2)) {
> +		rps->vclk = RV770_DEFAULT_VCLK_FREQ;
> +		rps->dclk = RV770_DEFAULT_DCLK_FREQ;
> +	} else {
> +		rps->vclk = 0;
> +		rps->dclk = 0;
> +	}
> +
> +	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT)
> +		rdev->pm.dpm.boot_ps = rps;
> +	if (rps->class & ATOM_PPLIB_CLASSIFICATION_UVDSTATE)
> +		rdev->pm.dpm.uvd_ps = rps;
> +}
> +
> +static void ni_parse_pplib_clock_info(struct radeon_device *rdev,
> +				      struct radeon_ps *rps, int index,
> +				      union pplib_clock_info *clock_info)
> +{
> +	struct rv7xx_power_info *pi = rv770_get_pi(rdev);
> +	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
> +	struct ni_ps *ps = ni_get_ps(rps);
> +	u16 vddc;
> +	struct rv7xx_pl *pl = &ps->performance_levels[index];
> +
> +	ps->performance_level_count = index + 1;
> +
> +	pl->sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow);
> +	pl->sclk |= clock_info->evergreen.ucEngineClockHigh << 16;
> +	pl->mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow);
> +	pl->mclk |= clock_info->evergreen.ucMemoryClockHigh << 16;
> +
> +	pl->vddc = le16_to_cpu(clock_info->evergreen.usVDDC);
> +	pl->vddci = le16_to_cpu(clock_info->evergreen.usVDDCI);
> +	pl->flags = le32_to_cpu(clock_info->evergreen.ulFlags);
> +
> +	/* patch up vddc if necessary */
> +	if (pl->vddc == 0xff01) {
> +		if (radeon_atom_get_max_vddc(rdev, 0, 0, &vddc) == 0)
> +			pl->vddc = vddc;
> +	}
> +
> +	if (rps->class & ATOM_PPLIB_CLASSIFICATION_ACPI) {
> +		pi->acpi_vddc = pl->vddc;
> +		eg_pi->acpi_vddci = pl->vddci;
> +		if (ps->performance_levels[0].flags & ATOM_PPLIB_R600_FLAGS_PCIEGEN2)
> +			pi->acpi_pcie_gen2 = true;
> +		else
> +			pi->acpi_pcie_gen2 = false;
> +	}
> +
> +	if (rps->class2 & ATOM_PPLIB_CLASSIFICATION2_ULV) {
> +		eg_pi->ulv.supported = true;
> +		eg_pi->ulv.pl = pl;
> +	}
> +
> +	if (pi->min_vddc_in_table > pl->vddc)
> +		pi->min_vddc_in_table = pl->vddc;
> +
> +	if (pi->max_vddc_in_table < pl->vddc)
> +		pi->max_vddc_in_table = pl->vddc;
> +
> +	/* patch up boot state */
> +	if (rps->class & ATOM_PPLIB_CLASSIFICATION_BOOT) {
> +		u16 vddc, vddci;
> +		radeon_atombios_get_default_voltages(rdev, &vddc, &vddci);
> +		pl->mclk = rdev->clock.default_mclk;
> +		pl->sclk = rdev->clock.default_sclk;
> +		pl->vddc = vddc;
> +		pl->vddci = vddci;
> +	}
> +
> +	if ((rps->class & ATOM_PPLIB_CLASSIFICATION_UI_MASK) ==
> +	    ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
> +		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.sclk = pl->sclk;
> +		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.mclk = pl->mclk;
> +		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddc = pl->vddc;
> +		rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac.vddci = pl->vddci;
> +	}
> +}
> +
> +static int ni_parse_power_table(struct radeon_device *rdev)
> +{
> +	struct radeon_mode_info *mode_info = &rdev->mode_info;
> +	struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info;
> +	union pplib_power_state *power_state;
> +	int i, j;
> +	union pplib_clock_info *clock_info;
> +	union power_info *power_info;
> +	int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo);
> +        u16 data_offset;
> +	u8 frev, crev;
> +	struct ni_ps *ps;
> +
> +	if (!atom_parse_data_header(mode_info->atom_context, index, NULL,
> +				   &frev, &crev, &data_offset))
> +		return -EINVAL;
> +	power_info = (union power_info *)(mode_info->atom_context->bios + data_offset);
> +
> +	rdev->pm.dpm.ps = kzalloc(sizeof(struct radeon_ps) *
> +				  power_info->pplib.ucNumStates, GFP_KERNEL);
> +	if (!rdev->pm.dpm.ps)
> +		return -ENOMEM;
> +	rdev->pm.dpm.platform_caps = le32_to_cpu(power_info->pplib.ulPlatformCaps);
> +	rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime);
> +	rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime);
> +
> +	for (i = 0; i < power_info->pplib.ucNumStates; i++) {
> +		power_state = (union pplib_power_state *)
> +			(mode_info->atom_context->bios + data_offset +
> +			 le16_to_cpu(power_info->pplib.usStateArrayOffset) +
> +			 i * power_info->pplib.ucStateEntrySize);
> +		non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *)
> +			(mode_info->atom_context->bios + data_offset +
> +			 le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) +
> +			 (power_state->v1.ucNonClockStateIndex *
> +			  power_info->pplib.ucNonClockSize));
> +		if (power_info->pplib.ucStateEntrySize - 1) {
> +			ps = kzalloc(sizeof(struct ni_ps), GFP_KERNEL);
> +			if (ps == NULL) {
> +				kfree(rdev->pm.dpm.ps);
> +				return -ENOMEM;
> +			}
> +			rdev->pm.dpm.ps[i].ps_priv = ps;
> +			ni_parse_pplib_non_clock_info(rdev, &rdev->pm.dpm.ps[i],
> +							 non_clock_info,
> +							 power_info->pplib.ucNonClockSize);
> +			for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) {
> +				clock_info = (union pplib_clock_info *)
> +					(mode_info->atom_context->bios + data_offset +
> +					 le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) +
> +					 (power_state->v1.ucClockStateIndices[j] *
> +					  power_info->pplib.ucClockInfoSize));
> +				ni_parse_pplib_clock_info(rdev,
> +							  &rdev->pm.dpm.ps[i], j,
> +							  clock_info);
> +			}
> +		}
> +	}
> +	rdev->pm.dpm.num_ps = power_info->pplib.ucNumStates;
> +	return 0;
> +}
> +
> +int ni_dpm_init(struct radeon_device *rdev)
> +{
> +	struct rv7xx_power_info *pi;
> +	struct evergreen_power_info *eg_pi;
> +	struct ni_power_info *ni_pi;
> +	int index = GetIndexIntoMasterTable(DATA, ASIC_InternalSS_Info);
> +	u16 data_offset, size;
> +	u8 frev, crev;
> +	struct atom_clock_dividers dividers;
> +	int ret;
> +
> +	ni_pi = kzalloc(sizeof(struct ni_power_info), GFP_KERNEL);
> +	if (ni_pi == NULL)
> +		return -ENOMEM;
> +	rdev->pm.dpm.priv = ni_pi;
> +	eg_pi = &ni_pi->eg;
> +	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 = ni_parse_power_table(rdev);
> +	if (ret)
> +		return ret;
> +	ret = r600_parse_extended_power_table(rdev);
> +	if (ret)
> +		return ret;
> +
> +	ni_patch_dependency_tables_based_on_leakage(rdev);
> +
> +	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->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;
> +
> +	if (rdev->pdev->device == 0x6707) {
> +		pi->mclk_strobe_mode_threshold = 55000;
> +		pi->mclk_edc_enable_threshold = 55000;
> +		eg_pi->mclk_edc_wr_enable_threshold = 55000;
> +	} else {
> +		pi->mclk_strobe_mode_threshold = 40000;
> +		pi->mclk_edc_enable_threshold = 40000;
> +		eg_pi->mclk_edc_wr_enable_threshold = 40000;
> +	}
> +	ni_pi->mclk_rtt_mode_threshold = eg_pi->mclk_edc_wr_enable_threshold;
> +
> +	pi->voltage_control =
> +		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDC);
> +
> +	pi->mvdd_control =
> +		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_MVDDC);
> +
> +	eg_pi->vddci_control =
> +		radeon_atom_is_voltage_gpio(rdev, SET_VOLTAGE_TYPE_ASIC_VDDCI);
> +
> +	if (atom_parse_data_header(rdev->mode_info.atom_context, index, &size,
> +                                   &frev, &crev, &data_offset)) {
> +		pi->sclk_ss = true;
> +		pi->mclk_ss = true;
> +		pi->dynamic_ss = true;
> +	} else {
> +		pi->sclk_ss = false;
> +		pi->mclk_ss = false;
> +		pi->dynamic_ss = true;
> +	}
> +
> +	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 (pi->gfx_clock_gating &&
> +	    (rdev->pm.int_thermal_type != THERMAL_TYPE_NONE))
> +		pi->thermal_protection = true;
> +	else
> +		pi->thermal_protection = false;
> +
> +	pi->display_gap = true;
> +
> +	pi->dcodt = true;
> +
> +	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
> +
> +	eg_pi->dll_default_on = false;
> +
> +	eg_pi->sclk_deep_sleep = false;
> +
> +	pi->mclk_stutter_mode_threshold = 0;
> +
> +	pi->sram_end = SMC_RAM_END;
> +
> +	rdev->pm.dpm.dyn_state.mclk_sclk_ratio = 3;
> +	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;
> +	rdev->pm.dpm.dyn_state.sclk_mclk_delta = 12500;
> +
> +	ni_pi->cac_data.leakage_coefficients.at = 516;
> +	ni_pi->cac_data.leakage_coefficients.bt = 18;
> +	ni_pi->cac_data.leakage_coefficients.av = 51;
> +	ni_pi->cac_data.leakage_coefficients.bv = 2957;
> +
> +	switch (rdev->pdev->device) {
> +	case 0x6700:
> +	case 0x6701:
> +	case 0x6702:
> +	case 0x6703:
> +	case 0x6718:
> +		ni_pi->cac_weights = &cac_weights_cayman_xt;
> +		break;
> +	case 0x6705:
> +	case 0x6719:
> +	case 0x671D:
> +	case 0x671C:
> +	default:
> +		ni_pi->cac_weights = &cac_weights_cayman_pro;
> +		break;
> +	case 0x6704:
> +	case 0x6706:
> +	case 0x6707:
> +	case 0x6708:
> +	case 0x6709:
> +		ni_pi->cac_weights = &cac_weights_cayman_le;
> +		break;
> +	}
> +
> +	if (ni_pi->cac_weights->enable_power_containment_by_default) {
> +		ni_pi->enable_power_containment = true;
> +		ni_pi->enable_cac = true;
> +		ni_pi->enable_sq_ramping = true;
> +	} else {
> +		ni_pi->enable_power_containment = false;
> +		ni_pi->enable_cac = false;
> +		ni_pi->enable_sq_ramping = false;
> +	}
> +
> +	ni_pi->driver_calculate_cac_leakage = false;
> +	ni_pi->cac_configuration_required = true;
> +
> +	if (ni_pi->cac_configuration_required) {
> +		ni_pi->support_cac_long_term_average = true;
> +		ni_pi->lta_window_size = ni_pi->cac_weights->l2_lta_window_size;
> +		ni_pi->lts_truncate = ni_pi->cac_weights->lts_truncate;
> +	} else {
> +		ni_pi->support_cac_long_term_average = false;
> +		ni_pi->lta_window_size = 0;
> +		ni_pi->lts_truncate = 0;
> +	}
> +
> +	ni_pi->use_power_boost_limit = true;
> +
> +	return 0;
> +}
> +
> +void ni_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);
> +	r600_free_extended_power_table(rdev);
> +}
> +
> +void ni_dpm_print_power_state(struct radeon_device *rdev,
> +			      struct radeon_ps *rps)
> +{
> +	struct ni_ps *ps = ni_get_ps(rps);
> +	struct rv7xx_pl *pl;
> +	int i;
> +
> +	r600_dpm_print_class_info(rps->class, rps->class2);
> +	r600_dpm_print_cap_info(rps->caps);
> +	printk("\tuvd    vclk: %d dclk: %d\n", rps->vclk, rps->dclk);
> +	for (i = 0; i < ps->performance_level_count; i++) {
> +		pl = &ps->performance_levels[i];
> +		printk("\t\tpower level 0    sclk: %u mclk: %u vddc: %u vddci: %u\n",
> +		       pl->sclk, pl->mclk, pl->vddc, pl->vddci);
> +	}
> +	r600_dpm_print_ps_status(rdev, rps);
> +}
> +
> +u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low)
> +{
> +	struct ni_ps *requested_state = ni_get_ps(rdev->pm.dpm.requested_ps);
> +
> +	if (low)
> +		return requested_state->performance_levels[0].sclk;
> +	else
> +		return requested_state->performance_levels[requested_state->performance_level_count - 1].sclk;
> +}
> +
> +u32 ni_dpm_get_mclk(struct radeon_device *rdev, bool low)
> +{
> +	struct ni_ps *requested_state = ni_get_ps(rdev->pm.dpm.requested_ps);
> +
> +	if (low)
> +		return requested_state->performance_levels[0].mclk;
> +	else
> +		return requested_state->performance_levels[requested_state->performance_level_count - 1].mclk;
> +}
> +
> diff --git a/drivers/gpu/drm/radeon/ni_dpm.h b/drivers/gpu/drm/radeon/ni_dpm.h
> new file mode 100644
> index 0000000..e10f747
> --- /dev/null
> +++ b/drivers/gpu/drm/radeon/ni_dpm.h
> @@ -0,0 +1,233 @@
> +/*
> + * 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.
> + *
> + */
> +#ifndef __NI_DPM_H__
> +#define __NI_DPM_H__
> +
> +#include "cypress_dpm.h"
> +#include "btc_dpm.h"
> +#include "nislands_smc.h"
> +
> +struct ni_clock_registers {
> +	u32 cg_spll_func_cntl;
> +	u32 cg_spll_func_cntl_2;
> +	u32 cg_spll_func_cntl_3;
> +	u32 cg_spll_func_cntl_4;
> +	u32 cg_spll_spread_spectrum;
> +	u32 cg_spll_spread_spectrum_2;
> +	u32 mclk_pwrmgt_cntl;
> +	u32 dll_cntl;
> +	u32 mpll_ad_func_cntl;
> +	u32 mpll_ad_func_cntl_2;
> +	u32 mpll_dq_func_cntl;
> +	u32 mpll_dq_func_cntl_2;
> +	u32 mpll_ss1;
> +	u32 mpll_ss2;
> +};
> +
> +struct ni_mc_reg_entry {
> +	u32 mclk_max;
> +	u32 mc_data[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
> +};
> +
> +struct ni_mc_reg_table {
> +	u8 last;
> +	u8 num_entries;
> +	u16 valid_flag;
> +	struct ni_mc_reg_entry mc_reg_table_entry[MAX_AC_TIMING_ENTRIES];
> +	SMC_NIslands_MCRegisterAddress mc_reg_address[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
> +};
> +
> +#define NISLANDS_MCREGISTERTABLE_FIRST_DRIVERSTATE_SLOT 2
> +
> +enum ni_dc_cac_level
> +{
> +	NISLANDS_DCCAC_LEVEL_0 = 0,
> +	NISLANDS_DCCAC_LEVEL_1,
> +	NISLANDS_DCCAC_LEVEL_2,
> +	NISLANDS_DCCAC_LEVEL_3,
> +	NISLANDS_DCCAC_LEVEL_4,
> +	NISLANDS_DCCAC_LEVEL_5,
> +	NISLANDS_DCCAC_LEVEL_6,
> +	NISLANDS_DCCAC_LEVEL_7,
> +	NISLANDS_DCCAC_MAX_LEVELS
> +};
> +
> +struct ni_leakage_coeffients
> +{
> +	u32 at;
> +	u32 bt;
> +	u32 av;
> +	u32 bv;
> +	s32 t_slope;
> +	s32 t_intercept;
> +	u32 t_ref;
> +};
> +
> +struct ni_cac_data
> +{
> +	struct ni_leakage_coeffients leakage_coefficients;
> +	u32 i_leakage;
> +	s32 leakage_minimum_temperature;
> +	u32 pwr_const;
> +	u32 dc_cac_value;
> +	u32 bif_cac_value;
> +	u32 lkge_pwr;
> +	u8 mc_wr_weight;
> +	u8 mc_rd_weight;
> +	u8 allow_ovrflw;
> +	u8 num_win_tdp;
> +	u8 l2num_win_tdp;
> +	u8 lts_truncate_n;
> +};
> +
> +struct ni_cac_weights
> +{
> +	u32 weight_tcp_sig0;
> +	u32 weight_tcp_sig1;
> +	u32 weight_ta_sig;
> +	u32 weight_tcc_en0;
> +	u32 weight_tcc_en1;
> +	u32 weight_tcc_en2;
> +	u32 weight_cb_en0;
> +	u32 weight_cb_en1;
> +	u32 weight_cb_en2;
> +	u32 weight_cb_en3;
> +	u32 weight_db_sig0;
> +	u32 weight_db_sig1;
> +	u32 weight_db_sig2;
> +	u32 weight_db_sig3;
> +	u32 weight_sxm_sig0;
> +	u32 weight_sxm_sig1;
> +	u32 weight_sxm_sig2;
> +	u32 weight_sxs_sig0;
> +	u32 weight_sxs_sig1;
> +	u32 weight_xbr_0;
> +	u32 weight_xbr_1;
> +	u32 weight_xbr_2;
> +	u32 weight_spi_sig0;
> +	u32 weight_spi_sig1;
> +	u32 weight_spi_sig2;
> +	u32 weight_spi_sig3;
> +	u32 weight_spi_sig4;
> +	u32 weight_spi_sig5;
> +	u32 weight_lds_sig0;
> +	u32 weight_lds_sig1;
> +	u32 weight_sc;
> +	u32 weight_bif;
> +	u32 weight_cp;
> +	u32 weight_pa_sig0;
> +	u32 weight_pa_sig1;
> +	u32 weight_vgt_sig0;
> +	u32 weight_vgt_sig1;
> +	u32 weight_vgt_sig2;
> +	u32 weight_dc_sig0;
> +	u32 weight_dc_sig1;
> +	u32 weight_dc_sig2;
> +	u32 weight_dc_sig3;
> +	u32 weight_uvd_sig0;
> +	u32 weight_uvd_sig1;
> +	u32 weight_spare0;
> +	u32 weight_spare1;
> +	u32 weight_sq_vsp;
> +	u32 weight_sq_vsp0;
> +	u32 weight_sq_gpr;
> +	u32 ovr_mode_spare_0;
> +	u32 ovr_val_spare_0;
> +	u32 ovr_mode_spare_1;
> +	u32 ovr_val_spare_1;
> +	u32 vsp;
> +	u32 vsp0;
> +	u32 gpr;
> +	u8 mc_read_weight;
> +	u8 mc_write_weight;
> +	u32 tid_cnt;
> +	u32 tid_unit;
> +	u32 l2_lta_window_size;
> +	u32 lts_truncate;
> +	u32 dc_cac[NISLANDS_DCCAC_MAX_LEVELS];
> +	u32 pcie_cac[SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES];
> +	bool enable_power_containment_by_default;
> +};
> +
> +struct ni_ps {
> +	u16 performance_level_count;
> +	bool dc_compatible;
> +	struct rv7xx_pl performance_levels[NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE];
> +};
> +
> +struct ni_power_info {
> +	/* must be first! */
> +	struct evergreen_power_info eg;
> +	struct ni_clock_registers clock_registers;
> +	struct ni_mc_reg_table mc_reg_table;
> +	u32 mclk_rtt_mode_threshold;
> +	/* flags */
> +	bool use_power_boost_limit;
> +	bool support_cac_long_term_average;
> +	bool cac_enabled;
> +	bool cac_configuration_required;
> +	bool driver_calculate_cac_leakage;
> +	bool pc_enabled;
> +	bool enable_power_containment;
> +	bool enable_cac;
> +	bool enable_sq_ramping;
> +	/* smc offsets */
> +	u16 arb_table_start;
> +	u16 fan_table_start;
> +	u16 cac_table_start;
> +	u16 spll_table_start;
> +	/* CAC stuff */
> +	struct ni_cac_data cac_data;
> +	u32 dc_cac_table[NISLANDS_DCCAC_MAX_LEVELS];
> +	const struct ni_cac_weights *cac_weights;
> +	u8 lta_window_size;
> +	u8 lts_truncate;
> +	struct ni_ps hw_ps;
> +	/* scratch structs */
> +	SMC_NIslands_MCRegisters smc_mc_reg_table;
> +	NISLANDS_SMC_STATETABLE smc_statetable;
> +};
> +
> +#define NISLANDS_INITIAL_STATE_ARB_INDEX    0
> +#define NISLANDS_ACPI_STATE_ARB_INDEX       1
> +#define NISLANDS_ULV_STATE_ARB_INDEX        2
> +#define NISLANDS_DRIVER_STATE_ARB_INDEX     3
> +
> +#define NISLANDS_DPM2_MAX_PULSE_SKIP        256
> +
> +#define NISLANDS_DPM2_NEAR_TDP_DEC          10
> +#define NISLANDS_DPM2_ABOVE_SAFE_INC        5
> +#define NISLANDS_DPM2_BELOW_SAFE_INC        20
> +
> +#define NISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT            80
> +
> +#define NISLANDS_DPM2_MAXPS_PERCENT_H                   90
> +#define NISLANDS_DPM2_MAXPS_PERCENT_M                   0
> +
> +#define NISLANDS_DPM2_SQ_RAMP_MAX_POWER                 0x3FFF
> +#define NISLANDS_DPM2_SQ_RAMP_MIN_POWER                 0x12
> +#define NISLANDS_DPM2_SQ_RAMP_MAX_POWER_DELTA           0x15
> +#define NISLANDS_DPM2_SQ_RAMP_STI_SIZE                  0x1E
> +#define NISLANDS_DPM2_SQ_RAMP_LTI_RATIO                 0xF
> +
> +#endif
> diff --git a/drivers/gpu/drm/radeon/nid.h b/drivers/gpu/drm/radeon/nid.h
> index 7b8da52..1775043 100644
> --- a/drivers/gpu/drm/radeon/nid.h
> +++ b/drivers/gpu/drm/radeon/nid.h
> @@ -492,6 +492,558 @@
>  /* TN SMU registers */
>  #define	TN_CURRENT_GNB_TEMP				0x1F390
>  
> +/* pm registers */
> +#define	SMC_MSG						0x20c
> +#define		HOST_SMC_MSG(x)				((x) << 0)
> +#define		HOST_SMC_MSG_MASK			(0xff << 0)
> +#define		HOST_SMC_MSG_SHIFT			0
> +#define		HOST_SMC_RESP(x)			((x) << 8)
> +#define		HOST_SMC_RESP_MASK			(0xff << 8)
> +#define		HOST_SMC_RESP_SHIFT			8
> +#define		SMC_HOST_MSG(x)				((x) << 16)
> +#define		SMC_HOST_MSG_MASK			(0xff << 16)
> +#define		SMC_HOST_MSG_SHIFT			16
> +#define		SMC_HOST_RESP(x)			((x) << 24)
> +#define		SMC_HOST_RESP_MASK			(0xff << 24)
> +#define		SMC_HOST_RESP_SHIFT			24
> +
> +#define	CG_SPLL_FUNC_CNTL				0x600
> +#define		SPLL_RESET				(1 << 0)
> +#define		SPLL_SLEEP				(1 << 1)
> +#define		SPLL_BYPASS_EN				(1 << 3)
> +#define		SPLL_REF_DIV(x)				((x) << 4)
> +#define		SPLL_REF_DIV_MASK			(0x3f << 4)
> +#define		SPLL_PDIV_A(x)				((x) << 20)
> +#define		SPLL_PDIV_A_MASK			(0x7f << 20)
> +#define		SPLL_PDIV_A_SHIFT			20
> +#define	CG_SPLL_FUNC_CNTL_2				0x604
> +#define		SCLK_MUX_SEL(x)				((x) << 0)
> +#define		SCLK_MUX_SEL_MASK			(0x1ff << 0)
> +#define	CG_SPLL_FUNC_CNTL_3				0x608
> +#define		SPLL_FB_DIV(x)				((x) << 0)
> +#define		SPLL_FB_DIV_MASK			(0x3ffffff << 0)
> +#define		SPLL_FB_DIV_SHIFT			0
> +#define		SPLL_DITHEN				(1 << 28)
> +
> +#define MPLL_CNTL_MODE                                  0x61c
> +#       define SS_SSEN                                  (1 << 24)
> +#       define SS_DSMODE_EN                             (1 << 25)
> +
> +#define	MPLL_AD_FUNC_CNTL				0x624
> +#define		CLKF(x)					((x) << 0)
> +#define		CLKF_MASK				(0x7f << 0)
> +#define		CLKR(x)					((x) << 7)
> +#define		CLKR_MASK				(0x1f << 7)
> +#define		CLKFRAC(x)				((x) << 12)
> +#define		CLKFRAC_MASK				(0x1f << 12)
> +#define		YCLK_POST_DIV(x)			((x) << 17)
> +#define		YCLK_POST_DIV_MASK			(3 << 17)
> +#define		IBIAS(x)				((x) << 20)
> +#define		IBIAS_MASK				(0x3ff << 20)
> +#define		RESET					(1 << 30)
> +#define		PDNB					(1 << 31)
> +#define	MPLL_AD_FUNC_CNTL_2				0x628
> +#define		BYPASS					(1 << 19)
> +#define		BIAS_GEN_PDNB				(1 << 24)
> +#define		RESET_EN				(1 << 25)
> +#define		VCO_MODE				(1 << 29)
> +#define	MPLL_DQ_FUNC_CNTL				0x62c
> +#define	MPLL_DQ_FUNC_CNTL_2				0x630
> +
> +#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 SCLK_PWRMGT_CNTL                                  0x644
> +#       define SCLK_PWRMGT_OFF                            (1 << 0)
> +#       define SCLK_LOW_D1                                (1 << 1)
> +#       define FIR_RESET                                  (1 << 4)
> +#       define FIR_FORCE_TREND_SEL                        (1 << 5)
> +#       define FIR_TREND_MODE                             (1 << 6)
> +#       define DYN_GFX_CLK_OFF_EN                         (1 << 7)
> +#       define GFX_CLK_FORCE_ON                           (1 << 8)
> +#       define GFX_CLK_REQUEST_OFF                        (1 << 9)
> +#       define GFX_CLK_FORCE_OFF                          (1 << 10)
> +#       define GFX_CLK_OFF_ACPI_D1                        (1 << 11)
> +#       define GFX_CLK_OFF_ACPI_D2                        (1 << 12)
> +#       define GFX_CLK_OFF_ACPI_D3                        (1 << 13)
> +#       define DYN_LIGHT_SLEEP_EN                         (1 << 14)
> +#define	MCLK_PWRMGT_CNTL				0x648
> +#       define DLL_SPEED(x)				((x) << 0)
> +#       define DLL_SPEED_MASK				(0x1f << 0)
> +#       define MPLL_PWRMGT_OFF                          (1 << 5)
> +#       define DLL_READY                                (1 << 6)
> +#       define MC_INT_CNTL                              (1 << 7)
> +#       define MRDCKA0_PDNB                             (1 << 8)
> +#       define MRDCKA1_PDNB                             (1 << 9)
> +#       define MRDCKB0_PDNB                             (1 << 10)
> +#       define MRDCKB1_PDNB                             (1 << 11)
> +#       define MRDCKC0_PDNB                             (1 << 12)
> +#       define MRDCKC1_PDNB                             (1 << 13)
> +#       define MRDCKD0_PDNB                             (1 << 14)
> +#       define MRDCKD1_PDNB                             (1 << 15)
> +#       define MRDCKA0_RESET                            (1 << 16)
> +#       define MRDCKA1_RESET                            (1 << 17)
> +#       define MRDCKB0_RESET                            (1 << 18)
> +#       define MRDCKB1_RESET                            (1 << 19)
> +#       define MRDCKC0_RESET                            (1 << 20)
> +#       define MRDCKC1_RESET                            (1 << 21)
> +#       define MRDCKD0_RESET                            (1 << 22)
> +#       define MRDCKD1_RESET                            (1 << 23)
> +#       define DLL_READY_READ                           (1 << 24)
> +#       define USE_DISPLAY_GAP                          (1 << 25)
> +#       define USE_DISPLAY_URGENT_NORMAL                (1 << 26)
> +#       define MPLL_TURNOFF_D2                          (1 << 28)
> +#define	DLL_CNTL					0x64c
> +#       define MRDCKA0_BYPASS                           (1 << 24)
> +#       define MRDCKA1_BYPASS                           (1 << 25)
> +#       define MRDCKB0_BYPASS                           (1 << 26)
> +#       define MRDCKB1_BYPASS                           (1 << 27)
> +#       define MRDCKC0_BYPASS                           (1 << 28)
> +#       define MRDCKC1_BYPASS                           (1 << 29)
> +#       define MRDCKD0_BYPASS                           (1 << 30)
> +#       define MRDCKD1_BYPASS                           (1 << 31)
> +
> +#define CG_AT                                           0x6d4
> +#       define CG_R(x)					((x) << 0)
> +#       define CG_R_MASK				(0xffff << 0)
> +#       define CG_L(x)					((x) << 16)
> +#       define CG_L_MASK				(0xffff << 16)
> +
> +#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	CG_SPLL_SPREAD_SPECTRUM				0x790
> +#define		SSEN					(1 << 0)
> +#define		CLK_S(x)				((x) << 4)
> +#define		CLK_S_MASK				(0xfff << 4)
> +#define		CLK_S_SHIFT				4
> +#define	CG_SPLL_SPREAD_SPECTRUM_2			0x794
> +#define		CLK_V(x)				((x) << 0)
> +#define		CLK_V_MASK				(0x3ffffff << 0)
> +#define		CLK_V_SHIFT				0
> +
> +#define SMC_SCRATCH0                                    0x81c
> +
> +#define	CG_SPLL_FUNC_CNTL_4				0x850
> +
> +#define	MPLL_SS1					0x85c
> +#define		CLKV(x)					((x) << 0)
> +#define		CLKV_MASK				(0x3ffffff << 0)
> +#define	MPLL_SS2					0x860
> +#define		CLKS(x)					((x) << 0)
> +#define		CLKS_MASK				(0xfff << 0)
> +
> +#define	CG_CAC_CTRL					0x88c
> +#define		TID_CNT(x)				((x) << 0)
> +#define		TID_CNT_MASK				(0x3fff << 0)
> +#define		TID_UNIT(x)				((x) << 14)
> +#define		TID_UNIT_MASK				(0xf << 14)
> +
> +#define MC_CG_CONFIG                                    0x25bc
> +#define         MCDW_WR_ENABLE                          (1 << 0)
> +#define         MCDX_WR_ENABLE                          (1 << 1)
> +#define         MCDY_WR_ENABLE                          (1 << 2)
> +#define         MCDZ_WR_ENABLE                          (1 << 3)
> +#define		MC_RD_ENABLE(x)				((x) << 4)
> +#define		MC_RD_ENABLE_MASK			(3 << 4)
> +#define		INDEX(x)				((x) << 6)
> +#define		INDEX_MASK				(0xfff << 6)
> +#define		INDEX_SHIFT				6
> +
> +#define	MC_ARB_CAC_CNTL					0x2750
> +#define         ENABLE                                  (1 << 0)
> +#define		READ_WEIGHT(x)				((x) << 1)
> +#define		READ_WEIGHT_MASK			(0x3f << 1)
> +#define		READ_WEIGHT_SHIFT			1
> +#define		WRITE_WEIGHT(x)				((x) << 7)
> +#define		WRITE_WEIGHT_MASK			(0x3f << 7)
> +#define		WRITE_WEIGHT_SHIFT			7
> +#define         ALLOW_OVERFLOW                          (1 << 13)
> +
> +#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_CG                                       0x27e8
> +#define		CG_ARB_REQ(x)				((x) << 0)
> +#define		CG_ARB_REQ_MASK				(0xff << 0)
> +#define		CG_ARB_REQ_SHIFT			0
> +#define		CG_ARB_RESP(x)				((x) << 8)
> +#define		CG_ARB_RESP_MASK			(0xff << 8)
> +#define		CG_ARB_RESP_SHIFT			8
> +#define		ARB_CG_REQ(x)				((x) << 16)
> +#define		ARB_CG_REQ_MASK				(0xff << 16)
> +#define		ARB_CG_REQ_SHIFT			16
> +#define		ARB_CG_RESP(x)				((x) << 24)
> +#define		ARB_CG_RESP_MASK			(0xff << 24)
> +#define		ARB_CG_RESP_SHIFT			24
> +
> +#define	MC_ARB_DRAM_TIMING_1				0x27f0
> +#define	MC_ARB_DRAM_TIMING_2				0x27f4
> +#define	MC_ARB_DRAM_TIMING_3				0x27f8
> +#define	MC_ARB_DRAM_TIMING2_1				0x27fc
> +#define	MC_ARB_DRAM_TIMING2_2				0x2800
> +#define	MC_ARB_DRAM_TIMING2_3				0x2804
> +#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_CG_DATAPORT                                  0x2884
> +
> +#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_PMG_TIMING                               0x28b0
> +#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_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_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 MC_SEQ_PMG_TIMING_LP                            0x2b4c
> +
> +#define MC_PMG_CMD_MRS2                                 0x2b5c
> +#define MC_SEQ_PMG_CMD_MRS2_LP                          0x2b60
> +
> +#define	LB_SYNC_RESET_SEL				0x6b28
> +#define		LB_SYNC_RESET_SEL_MASK			(3 << 0)
> +#define		LB_SYNC_RESET_SEL_SHIFT			0
> +
> +#define	DC_STUTTER_CNTL					0x6b30
> +#define		DC_STUTTER_ENABLE_A			(1 << 0)
> +#define		DC_STUTTER_ENABLE_B			(1 << 1)
> +
> +#define SQ_CAC_THRESHOLD                                0x8e4c
> +#define		VSP(x)					((x) << 0)
> +#define		VSP_MASK				(0xff << 0)
> +#define		VSP_SHIFT				0
> +#define		VSP0(x)					((x) << 8)
> +#define		VSP0_MASK				(0xff << 8)
> +#define		VSP0_SHIFT				8
> +#define		GPR(x)					((x) << 16)
> +#define		GPR_MASK				(0xff << 16)
> +#define		GPR_SHIFT				16
> +
> +#define SQ_POWER_THROTTLE                               0x8e58
> +#define		MIN_POWER(x)				((x) << 0)
> +#define		MIN_POWER_MASK				(0x3fff << 0)
> +#define		MIN_POWER_SHIFT				0
> +#define		MAX_POWER(x)				((x) << 16)
> +#define		MAX_POWER_MASK				(0x3fff << 16)
> +#define		MAX_POWER_SHIFT				0
> +#define SQ_POWER_THROTTLE2                              0x8e5c
> +#define		MAX_POWER_DELTA(x)			((x) << 0)
> +#define		MAX_POWER_DELTA_MASK			(0x3fff << 0)
> +#define		MAX_POWER_DELTA_SHIFT			0
> +#define		STI_SIZE(x)				((x) << 16)
> +#define		STI_SIZE_MASK				(0x3ff << 16)
> +#define		STI_SIZE_SHIFT				16
> +#define		LTI_RATIO(x)				((x) << 27)
> +#define		LTI_RATIO_MASK				(0xf << 27)
> +#define		LTI_RATIO_SHIFT				27
> +
> +/* CG indirect registers */
> +#define CG_CAC_REGION_1_WEIGHT_0                        0x83
> +#define		WEIGHT_TCP_SIG0(x)			((x) << 0)
> +#define		WEIGHT_TCP_SIG0_MASK			(0x3f << 0)
> +#define		WEIGHT_TCP_SIG0_SHIFT			0
> +#define		WEIGHT_TCP_SIG1(x)			((x) << 6)
> +#define		WEIGHT_TCP_SIG1_MASK			(0x3f << 6)
> +#define		WEIGHT_TCP_SIG1_SHIFT			6
> +#define		WEIGHT_TA_SIG(x)			((x) << 12)
> +#define		WEIGHT_TA_SIG_MASK			(0x3f << 12)
> +#define		WEIGHT_TA_SIG_SHIFT			12
> +#define CG_CAC_REGION_1_WEIGHT_1                        0x84
> +#define		WEIGHT_TCC_EN0(x)			((x) << 0)
> +#define		WEIGHT_TCC_EN0_MASK			(0x3f << 0)
> +#define		WEIGHT_TCC_EN0_SHIFT			0
> +#define		WEIGHT_TCC_EN1(x)			((x) << 6)
> +#define		WEIGHT_TCC_EN1_MASK			(0x3f << 6)
> +#define		WEIGHT_TCC_EN1_SHIFT			6
> +#define		WEIGHT_TCC_EN2(x)			((x) << 12)
> +#define		WEIGHT_TCC_EN2_MASK			(0x3f << 12)
> +#define		WEIGHT_TCC_EN2_SHIFT			12
> +#define		WEIGHT_TCC_EN3(x)			((x) << 18)
> +#define		WEIGHT_TCC_EN3_MASK			(0x3f << 18)
> +#define		WEIGHT_TCC_EN3_SHIFT			18
> +#define CG_CAC_REGION_2_WEIGHT_0                        0x85
> +#define		WEIGHT_CB_EN0(x)			((x) << 0)
> +#define		WEIGHT_CB_EN0_MASK			(0x3f << 0)
> +#define		WEIGHT_CB_EN0_SHIFT			0
> +#define		WEIGHT_CB_EN1(x)			((x) << 6)
> +#define		WEIGHT_CB_EN1_MASK			(0x3f << 6)
> +#define		WEIGHT_CB_EN1_SHIFT			6
> +#define		WEIGHT_CB_EN2(x)			((x) << 12)
> +#define		WEIGHT_CB_EN2_MASK			(0x3f << 12)
> +#define		WEIGHT_CB_EN2_SHIFT			12
> +#define		WEIGHT_CB_EN3(x)			((x) << 18)
> +#define		WEIGHT_CB_EN3_MASK			(0x3f << 18)
> +#define		WEIGHT_CB_EN3_SHIFT			18
> +#define CG_CAC_REGION_2_WEIGHT_1                        0x86
> +#define		WEIGHT_DB_SIG0(x)			((x) << 0)
> +#define		WEIGHT_DB_SIG0_MASK			(0x3f << 0)
> +#define		WEIGHT_DB_SIG0_SHIFT			0
> +#define		WEIGHT_DB_SIG1(x)			((x) << 6)
> +#define		WEIGHT_DB_SIG1_MASK			(0x3f << 6)
> +#define		WEIGHT_DB_SIG1_SHIFT			6
> +#define		WEIGHT_DB_SIG2(x)			((x) << 12)
> +#define		WEIGHT_DB_SIG2_MASK			(0x3f << 12)
> +#define		WEIGHT_DB_SIG2_SHIFT			12
> +#define		WEIGHT_DB_SIG3(x)			((x) << 18)
> +#define		WEIGHT_DB_SIG3_MASK			(0x3f << 18)
> +#define		WEIGHT_DB_SIG3_SHIFT			18
> +#define CG_CAC_REGION_2_WEIGHT_2                        0x87
> +#define		WEIGHT_SXM_SIG0(x)			((x) << 0)
> +#define		WEIGHT_SXM_SIG0_MASK			(0x3f << 0)
> +#define		WEIGHT_SXM_SIG0_SHIFT			0
> +#define		WEIGHT_SXM_SIG1(x)			((x) << 6)
> +#define		WEIGHT_SXM_SIG1_MASK			(0x3f << 6)
> +#define		WEIGHT_SXM_SIG1_SHIFT			6
> +#define		WEIGHT_SXM_SIG2(x)			((x) << 12)
> +#define		WEIGHT_SXM_SIG2_MASK			(0x3f << 12)
> +#define		WEIGHT_SXM_SIG2_SHIFT			12
> +#define		WEIGHT_SXS_SIG0(x)			((x) << 18)
> +#define		WEIGHT_SXS_SIG0_MASK			(0x3f << 18)
> +#define		WEIGHT_SXS_SIG0_SHIFT			18
> +#define		WEIGHT_SXS_SIG1(x)			((x) << 24)
> +#define		WEIGHT_SXS_SIG1_MASK			(0x3f << 24)
> +#define		WEIGHT_SXS_SIG1_SHIFT			24
> +#define CG_CAC_REGION_3_WEIGHT_0                        0x88
> +#define		WEIGHT_XBR_0(x)				((x) << 0)
> +#define		WEIGHT_XBR_0_MASK			(0x3f << 0)
> +#define		WEIGHT_XBR_0_SHIFT			0
> +#define		WEIGHT_XBR_1(x)				((x) << 6)
> +#define		WEIGHT_XBR_1_MASK			(0x3f << 6)
> +#define		WEIGHT_XBR_1_SHIFT			6
> +#define		WEIGHT_XBR_2(x)				((x) << 12)
> +#define		WEIGHT_XBR_2_MASK			(0x3f << 12)
> +#define		WEIGHT_XBR_2_SHIFT			12
> +#define		WEIGHT_SPI_SIG0(x)			((x) << 18)
> +#define		WEIGHT_SPI_SIG0_MASK			(0x3f << 18)
> +#define		WEIGHT_SPI_SIG0_SHIFT			18
> +#define CG_CAC_REGION_3_WEIGHT_1                        0x89
> +#define		WEIGHT_SPI_SIG1(x)			((x) << 0)
> +#define		WEIGHT_SPI_SIG1_MASK			(0x3f << 0)
> +#define		WEIGHT_SPI_SIG1_SHIFT			0
> +#define		WEIGHT_SPI_SIG2(x)			((x) << 6)
> +#define		WEIGHT_SPI_SIG2_MASK			(0x3f << 6)
> +#define		WEIGHT_SPI_SIG2_SHIFT			6
> +#define		WEIGHT_SPI_SIG3(x)			((x) << 12)
> +#define		WEIGHT_SPI_SIG3_MASK			(0x3f << 12)
> +#define		WEIGHT_SPI_SIG3_SHIFT			12
> +#define		WEIGHT_SPI_SIG4(x)			((x) << 18)
> +#define		WEIGHT_SPI_SIG4_MASK			(0x3f << 18)
> +#define		WEIGHT_SPI_SIG4_SHIFT			18
> +#define		WEIGHT_SPI_SIG5(x)			((x) << 24)
> +#define		WEIGHT_SPI_SIG5_MASK			(0x3f << 24)
> +#define		WEIGHT_SPI_SIG5_SHIFT			24
> +#define CG_CAC_REGION_4_WEIGHT_0                        0x8a
> +#define		WEIGHT_LDS_SIG0(x)			((x) << 0)
> +#define		WEIGHT_LDS_SIG0_MASK			(0x3f << 0)
> +#define		WEIGHT_LDS_SIG0_SHIFT			0
> +#define		WEIGHT_LDS_SIG1(x)			((x) << 6)
> +#define		WEIGHT_LDS_SIG1_MASK			(0x3f << 6)
> +#define		WEIGHT_LDS_SIG1_SHIFT			6
> +#define		WEIGHT_SC(x)				((x) << 24)
> +#define		WEIGHT_SC_MASK				(0x3f << 24)
> +#define		WEIGHT_SC_SHIFT				24
> +#define CG_CAC_REGION_4_WEIGHT_1                        0x8b
> +#define		WEIGHT_BIF(x)				((x) << 0)
> +#define		WEIGHT_BIF_MASK				(0x3f << 0)
> +#define		WEIGHT_BIF_SHIFT			0
> +#define		WEIGHT_CP(x)				((x) << 6)
> +#define		WEIGHT_CP_MASK				(0x3f << 6)
> +#define		WEIGHT_CP_SHIFT				6
> +#define		WEIGHT_PA_SIG0(x)			((x) << 12)
> +#define		WEIGHT_PA_SIG0_MASK			(0x3f << 12)
> +#define		WEIGHT_PA_SIG0_SHIFT			12
> +#define		WEIGHT_PA_SIG1(x)			((x) << 18)
> +#define		WEIGHT_PA_SIG1_MASK			(0x3f << 18)
> +#define		WEIGHT_PA_SIG1_SHIFT			18
> +#define		WEIGHT_VGT_SIG0(x)			((x) << 24)
> +#define		WEIGHT_VGT_SIG0_MASK			(0x3f << 24)
> +#define		WEIGHT_VGT_SIG0_SHIFT			24
> +#define CG_CAC_REGION_4_WEIGHT_2                        0x8c
> +#define		WEIGHT_VGT_SIG1(x)			((x) << 0)
> +#define		WEIGHT_VGT_SIG1_MASK			(0x3f << 0)
> +#define		WEIGHT_VGT_SIG1_SHIFT			0
> +#define		WEIGHT_VGT_SIG2(x)			((x) << 6)
> +#define		WEIGHT_VGT_SIG2_MASK			(0x3f << 6)
> +#define		WEIGHT_VGT_SIG2_SHIFT			6
> +#define		WEIGHT_DC_SIG0(x)			((x) << 12)
> +#define		WEIGHT_DC_SIG0_MASK			(0x3f << 12)
> +#define		WEIGHT_DC_SIG0_SHIFT			12
> +#define		WEIGHT_DC_SIG1(x)			((x) << 18)
> +#define		WEIGHT_DC_SIG1_MASK			(0x3f << 18)
> +#define		WEIGHT_DC_SIG1_SHIFT			18
> +#define		WEIGHT_DC_SIG2(x)			((x) << 24)
> +#define		WEIGHT_DC_SIG2_MASK			(0x3f << 24)
> +#define		WEIGHT_DC_SIG2_SHIFT			24
> +#define CG_CAC_REGION_4_WEIGHT_3                        0x8d
> +#define		WEIGHT_DC_SIG3(x)			((x) << 0)
> +#define		WEIGHT_DC_SIG3_MASK			(0x3f << 0)
> +#define		WEIGHT_DC_SIG3_SHIFT			0
> +#define		WEIGHT_UVD_SIG0(x)			((x) << 6)
> +#define		WEIGHT_UVD_SIG0_MASK			(0x3f << 6)
> +#define		WEIGHT_UVD_SIG0_SHIFT			6
> +#define		WEIGHT_UVD_SIG1(x)			((x) << 12)
> +#define		WEIGHT_UVD_SIG1_MASK			(0x3f << 12)
> +#define		WEIGHT_UVD_SIG1_SHIFT			12
> +#define		WEIGHT_SPARE0(x)			((x) << 18)
> +#define		WEIGHT_SPARE0_MASK			(0x3f << 18)
> +#define		WEIGHT_SPARE0_SHIFT			18
> +#define		WEIGHT_SPARE1(x)			((x) << 24)
> +#define		WEIGHT_SPARE1_MASK			(0x3f << 24)
> +#define		WEIGHT_SPARE1_SHIFT			24
> +#define CG_CAC_REGION_5_WEIGHT_0                        0x8e
> +#define		WEIGHT_SQ_VSP(x)			((x) << 0)
> +#define		WEIGHT_SQ_VSP_MASK			(0x3fff << 0)
> +#define		WEIGHT_SQ_VSP_SHIFT			0
> +#define		WEIGHT_SQ_VSP0(x)			((x) << 14)
> +#define		WEIGHT_SQ_VSP0_MASK			(0x3fff << 14)
> +#define		WEIGHT_SQ_VSP0_SHIFT			14
> +#define CG_CAC_REGION_4_OVERRIDE_4                      0xab
> +#define		OVR_MODE_SPARE_0(x)			((x) << 16)
> +#define		OVR_MODE_SPARE_0_MASK			(0x1 << 16)
> +#define		OVR_MODE_SPARE_0_SHIFT			16
> +#define		OVR_VAL_SPARE_0(x)			((x) << 17)
> +#define		OVR_VAL_SPARE_0_MASK			(0x1 << 17)
> +#define		OVR_VAL_SPARE_0_SHIFT			17
> +#define		OVR_MODE_SPARE_1(x)			((x) << 18)
> +#define		OVR_MODE_SPARE_1_MASK			(0x3f << 18)
> +#define		OVR_MODE_SPARE_1_SHIFT			18
> +#define		OVR_VAL_SPARE_1(x)			((x) << 19)
> +#define		OVR_VAL_SPARE_1_MASK			(0x3f << 19)
> +#define		OVR_VAL_SPARE_1_SHIFT			19
> +#define CG_CAC_REGION_5_WEIGHT_1                        0xb7
> +#define		WEIGHT_SQ_GPR(x)			((x) << 0)
> +#define		WEIGHT_SQ_GPR_MASK			(0x3fff << 0)
> +#define		WEIGHT_SQ_GPR_SHIFT			0
> +#define		WEIGHT_SQ_LDS(x)			((x) << 14)
> +#define		WEIGHT_SQ_LDS_MASK			(0x3fff << 14)
> +#define		WEIGHT_SQ_LDS_SHIFT			14
> +
> +/* PCIE link stuff */
> +#define PCIE_LC_TRAINING_CNTL                             0xa1 /* PCIE_P */
> +#define PCIE_LC_LINK_WIDTH_CNTL                           0xa2 /* PCIE_P */
> +#       define LC_LINK_WIDTH_SHIFT                        0
> +#       define LC_LINK_WIDTH_MASK                         0x7
> +#       define LC_LINK_WIDTH_X0                           0
> +#       define LC_LINK_WIDTH_X1                           1
> +#       define LC_LINK_WIDTH_X2                           2
> +#       define LC_LINK_WIDTH_X4                           3
> +#       define LC_LINK_WIDTH_X8                           4
> +#       define LC_LINK_WIDTH_X16                          6
> +#       define LC_LINK_WIDTH_RD_SHIFT                     4
> +#       define LC_LINK_WIDTH_RD_MASK                      0x70
> +#       define LC_RECONFIG_ARC_MISSING_ESCAPE             (1 << 7)
> +#       define LC_RECONFIG_NOW                            (1 << 8)
> +#       define LC_RENEGOTIATION_SUPPORT                   (1 << 9)
> +#       define LC_RENEGOTIATE_EN                          (1 << 10)
> +#       define LC_SHORT_RECONFIG_EN                       (1 << 11)
> +#       define LC_UPCONFIGURE_SUPPORT                     (1 << 12)
> +#       define LC_UPCONFIGURE_DIS                         (1 << 13)
> +#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)
> +#define MM_CFGREGS_CNTL                                   0x544c
> +#       define MM_WR_TO_CFG_EN                            (1 << 3)
> +#define LINK_CNTL2                                        0x88 /* F0 */
> +#       define TARGET_LINK_SPEED_MASK                     (0xf << 0)
> +#       define SELECTABLE_DEEMPHASIS                      (1 << 6)
> +
>  /*
>   * UVD
>   */
> diff --git a/drivers/gpu/drm/radeon/nislands_smc.h b/drivers/gpu/drm/radeon/nislands_smc.h
> new file mode 100644
> index 0000000..3cf8fc0
> --- /dev/null
> +++ b/drivers/gpu/drm/radeon/nislands_smc.h
> @@ -0,0 +1,329 @@
> +/*
> + * 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.
> + *
> + */
> +#ifndef __NISLANDS_SMC_H__
> +#define __NISLANDS_SMC_H__
> +
> +#pragma pack(push, 1)
> +
> +#define NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE 16
> +
> +struct PP_NIslands_Dpm2PerfLevel
> +{
> +    uint8_t     MaxPS;
> +    uint8_t     TgtAct;
> +    uint8_t     MaxPS_StepInc;
> +    uint8_t     MaxPS_StepDec;
> +    uint8_t     PSST;
> +    uint8_t     NearTDPDec;
> +    uint8_t     AboveSafeInc;
> +    uint8_t     BelowSafeInc;
> +    uint8_t     PSDeltaLimit;
> +    uint8_t     PSDeltaWin;
> +    uint8_t     Reserved[6];
> +};
> +
> +typedef struct PP_NIslands_Dpm2PerfLevel PP_NIslands_Dpm2PerfLevel;
> +
> +struct PP_NIslands_DPM2Parameters
> +{
> +    uint32_t    TDPLimit;
> +    uint32_t    NearTDPLimit;
> +    uint32_t    SafePowerLimit;
> +    uint32_t    PowerBoostLimit;
> +};
> +typedef struct PP_NIslands_DPM2Parameters PP_NIslands_DPM2Parameters;
> +
> +struct NISLANDS_SMC_SCLK_VALUE
> +{
> +    uint32_t        vCG_SPLL_FUNC_CNTL;
> +    uint32_t        vCG_SPLL_FUNC_CNTL_2;
> +    uint32_t        vCG_SPLL_FUNC_CNTL_3;
> +    uint32_t        vCG_SPLL_FUNC_CNTL_4;
> +    uint32_t        vCG_SPLL_SPREAD_SPECTRUM;
> +    uint32_t        vCG_SPLL_SPREAD_SPECTRUM_2;
> +    uint32_t        sclk_value;
> +};
> +
> +typedef struct NISLANDS_SMC_SCLK_VALUE NISLANDS_SMC_SCLK_VALUE;
> +
> +struct NISLANDS_SMC_MCLK_VALUE
> +{
> +    uint32_t        vMPLL_FUNC_CNTL;
> +    uint32_t        vMPLL_FUNC_CNTL_1;
> +    uint32_t        vMPLL_FUNC_CNTL_2;
> +    uint32_t        vMPLL_AD_FUNC_CNTL;
> +    uint32_t        vMPLL_AD_FUNC_CNTL_2;
> +    uint32_t        vMPLL_DQ_FUNC_CNTL;
> +    uint32_t        vMPLL_DQ_FUNC_CNTL_2;
> +    uint32_t        vMCLK_PWRMGT_CNTL;
> +    uint32_t        vDLL_CNTL;
> +    uint32_t        vMPLL_SS;
> +    uint32_t        vMPLL_SS2;
> +    uint32_t        mclk_value;
> +};
> +
> +typedef struct NISLANDS_SMC_MCLK_VALUE NISLANDS_SMC_MCLK_VALUE;
> +
> +struct NISLANDS_SMC_VOLTAGE_VALUE
> +{
> +    uint16_t             value;
> +    uint8_t              index;
> +    uint8_t              padding;
> +};
> +
> +typedef struct NISLANDS_SMC_VOLTAGE_VALUE NISLANDS_SMC_VOLTAGE_VALUE;
> +
> +struct NISLANDS_SMC_HW_PERFORMANCE_LEVEL
> +{
> +    uint8_t                     arbValue;
> +    uint8_t                     ACIndex;
> +    uint8_t                     displayWatermark;
> +    uint8_t                     gen2PCIE;
> +    uint8_t                     reserved1;
> +    uint8_t                     reserved2;
> +    uint8_t                     strobeMode;
> +    uint8_t                     mcFlags;
> +    uint32_t                    aT;
> +    uint32_t                    bSP;
> +    NISLANDS_SMC_SCLK_VALUE     sclk;
> +    NISLANDS_SMC_MCLK_VALUE     mclk;
> +    NISLANDS_SMC_VOLTAGE_VALUE  vddc;
> +    NISLANDS_SMC_VOLTAGE_VALUE  mvdd;
> +    NISLANDS_SMC_VOLTAGE_VALUE  vddci;
> +    NISLANDS_SMC_VOLTAGE_VALUE  std_vddc;
> +    uint32_t                    powergate_en;
> +    uint8_t                     hUp;
> +    uint8_t                     hDown;
> +    uint8_t                     stateFlags;
> +    uint8_t                     arbRefreshState;
> +    uint32_t                    SQPowerThrottle;
> +    uint32_t                    SQPowerThrottle_2;
> +    uint32_t                    reserved[2];
> +    PP_NIslands_Dpm2PerfLevel   dpm2;
> +};
> +
> +#define NISLANDS_SMC_STROBE_RATIO    0x0F
> +#define NISLANDS_SMC_STROBE_ENABLE   0x10
> +
> +#define NISLANDS_SMC_MC_EDC_RD_FLAG  0x01
> +#define NISLANDS_SMC_MC_EDC_WR_FLAG  0x02
> +#define NISLANDS_SMC_MC_RTT_ENABLE   0x04
> +#define NISLANDS_SMC_MC_STUTTER_EN   0x08
> +
> +typedef struct NISLANDS_SMC_HW_PERFORMANCE_LEVEL NISLANDS_SMC_HW_PERFORMANCE_LEVEL;
> +
> +struct NISLANDS_SMC_SWSTATE
> +{
> +    uint8_t                             flags;
> +    uint8_t                             levelCount;
> +    uint8_t                             padding2;
> +    uint8_t                             padding3;
> +    NISLANDS_SMC_HW_PERFORMANCE_LEVEL   levels[1];
> +};
> +
> +typedef struct NISLANDS_SMC_SWSTATE NISLANDS_SMC_SWSTATE;
> +
> +#define NISLANDS_SMC_VOLTAGEMASK_VDDC  0
> +#define NISLANDS_SMC_VOLTAGEMASK_MVDD  1
> +#define NISLANDS_SMC_VOLTAGEMASK_VDDCI 2
> +#define NISLANDS_SMC_VOLTAGEMASK_MAX   4
> +
> +struct NISLANDS_SMC_VOLTAGEMASKTABLE
> +{
> +    uint8_t  highMask[NISLANDS_SMC_VOLTAGEMASK_MAX];
> +    uint32_t lowMask[NISLANDS_SMC_VOLTAGEMASK_MAX];
> +};
> +
> +typedef struct NISLANDS_SMC_VOLTAGEMASKTABLE NISLANDS_SMC_VOLTAGEMASKTABLE;
> +
> +#define NISLANDS_MAX_NO_VREG_STEPS 32
> +
> +struct NISLANDS_SMC_STATETABLE
> +{
> +    uint8_t                             thermalProtectType;
> +    uint8_t                             systemFlags;
> +    uint8_t                             maxVDDCIndexInPPTable;
> +    uint8_t                             extraFlags;
> +    uint8_t                             highSMIO[NISLANDS_MAX_NO_VREG_STEPS];
> +    uint32_t                            lowSMIO[NISLANDS_MAX_NO_VREG_STEPS];
> +    NISLANDS_SMC_VOLTAGEMASKTABLE       voltageMaskTable;
> +    PP_NIslands_DPM2Parameters          dpm2Params;
> +    NISLANDS_SMC_SWSTATE                initialState;
> +    NISLANDS_SMC_SWSTATE                ACPIState;
> +    NISLANDS_SMC_SWSTATE                ULVState;
> +    NISLANDS_SMC_SWSTATE                driverState;
> +    NISLANDS_SMC_HW_PERFORMANCE_LEVEL   dpmLevels[NISLANDS_MAX_SMC_PERFORMANCE_LEVELS_PER_SWSTATE - 1];
> +};
> +
> +typedef struct NISLANDS_SMC_STATETABLE NISLANDS_SMC_STATETABLE;
> +
> +#define NI_SMC_SOFT_REGISTERS_START        0x108
> +
> +#define NI_SMC_SOFT_REGISTER_mclk_chg_timeout        0x0
> +#define NI_SMC_SOFT_REGISTER_delay_bbias             0xC
> +#define NI_SMC_SOFT_REGISTER_delay_vreg              0x10
> +#define NI_SMC_SOFT_REGISTER_delay_acpi              0x2C
> +#define NI_SMC_SOFT_REGISTER_seq_index               0x64
> +#define NI_SMC_SOFT_REGISTER_mvdd_chg_time           0x68
> +#define NI_SMC_SOFT_REGISTER_mclk_switch_lim         0x78
> +#define NI_SMC_SOFT_REGISTER_watermark_threshold     0x80
> +#define NI_SMC_SOFT_REGISTER_mc_block_delay          0x84
> +#define NI_SMC_SOFT_REGISTER_uvd_enabled             0x98
> +
> +#define SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES 16
> +#define SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES 16
> +#define SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES 16
> +#define SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES 4
> +
> +struct SMC_NISLANDS_MC_TPP_CAC_TABLE
> +{
> +    uint32_t    tpp[SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES];
> +    uint32_t    cacValue[SMC_NISLANDS_MC_TPP_CAC_NUM_OF_ENTRIES];
> +};
> +
> +typedef struct SMC_NISLANDS_MC_TPP_CAC_TABLE SMC_NISLANDS_MC_TPP_CAC_TABLE;
> +
> +
> +struct PP_NIslands_CACTABLES
> +{
> +    uint32_t                cac_bif_lut[SMC_NISLANDS_BIF_LUT_NUM_OF_ENTRIES];
> +    uint32_t                cac_lkge_lut[SMC_NISLANDS_LKGE_LUT_NUM_OF_TEMP_ENTRIES][SMC_NISLANDS_LKGE_LUT_NUM_OF_VOLT_ENTRIES];
> +
> +    uint32_t                pwr_const;
> +
> +    uint32_t                dc_cacValue;
> +    uint32_t                bif_cacValue;
> +    uint32_t                lkge_pwr;
> +
> +    uint8_t                 cac_width;
> +    uint8_t                 window_size_p2;
> +
> +    uint8_t                 num_drop_lsb;
> +    uint8_t                 padding_0;
> +
> +    uint32_t                last_power;
> +
> +    uint8_t                 AllowOvrflw;
> +    uint8_t                 MCWrWeight;
> +    uint8_t                 MCRdWeight;
> +    uint8_t                 padding_1[9];
> +
> +    uint8_t                 enableWinAvg;
> +    uint8_t                 numWin_TDP;
> +    uint8_t                 l2numWin_TDP;
> +    uint8_t                 WinIndex;
> +
> +    uint32_t                dynPwr_TDP[4];
> +    uint32_t                lkgePwr_TDP[4];
> +    uint32_t                power_TDP[4];
> +    uint32_t                avg_dynPwr_TDP;
> +    uint32_t                avg_lkgePwr_TDP;
> +    uint32_t                avg_power_TDP;
> +    uint32_t                lts_power_TDP;
> +    uint8_t                 lts_truncate_n;
> +    uint8_t                 padding_2[7];
> +};
> +
> +typedef struct PP_NIslands_CACTABLES PP_NIslands_CACTABLES;
> +
> +#define SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE 32
> +#define SMC_NISLANDS_MC_REGISTER_ARRAY_SET_COUNT 20
> +
> +struct SMC_NIslands_MCRegisterAddress
> +{
> +    uint16_t s0;
> +    uint16_t s1;
> +};
> +
> +typedef struct SMC_NIslands_MCRegisterAddress SMC_NIslands_MCRegisterAddress;
> +
> +
> +struct SMC_NIslands_MCRegisterSet
> +{
> +    uint32_t value[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
> +};
> +
> +typedef struct SMC_NIslands_MCRegisterSet SMC_NIslands_MCRegisterSet;
> +
> +struct SMC_NIslands_MCRegisters
> +{
> +    uint8_t                             last;
> +    uint8_t                             reserved[3];
> +    SMC_NIslands_MCRegisterAddress      address[SMC_NISLANDS_MC_REGISTER_ARRAY_SIZE];
> +    SMC_NIslands_MCRegisterSet          data[SMC_NISLANDS_MC_REGISTER_ARRAY_SET_COUNT];
> +};
> +
> +typedef struct SMC_NIslands_MCRegisters SMC_NIslands_MCRegisters;
> +
> +struct SMC_NIslands_MCArbDramTimingRegisterSet
> +{
> +    uint32_t mc_arb_dram_timing;
> +    uint32_t mc_arb_dram_timing2;
> +    uint8_t  mc_arb_rfsh_rate;
> +    uint8_t  padding[3];
> +};
> +
> +typedef struct SMC_NIslands_MCArbDramTimingRegisterSet SMC_NIslands_MCArbDramTimingRegisterSet;
> +
> +struct SMC_NIslands_MCArbDramTimingRegisters
> +{
> +    uint8_t                                     arb_current;
> +    uint8_t                                     reserved[3];
> +    SMC_NIslands_MCArbDramTimingRegisterSet     data[20];
> +};
> +
> +typedef struct SMC_NIslands_MCArbDramTimingRegisters SMC_NIslands_MCArbDramTimingRegisters;
> +
> +struct SMC_NISLANDS_SPLL_DIV_TABLE
> +{
> +    uint32_t    freq[256];
> +    uint32_t    ss[256];
> +};
> +
> +#define SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_MASK  0x01ffffff
> +#define SMC_NISLANDS_SPLL_DIV_TABLE_FBDIV_SHIFT 0
> +#define SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_MASK   0xfe000000
> +#define SMC_NISLANDS_SPLL_DIV_TABLE_PDIV_SHIFT  25
> +#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_MASK   0x000fffff
> +#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKV_SHIFT  0
> +#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_MASK   0xfff00000
> +#define SMC_NISLANDS_SPLL_DIV_TABLE_CLKS_SHIFT  20
> +
> +typedef struct SMC_NISLANDS_SPLL_DIV_TABLE SMC_NISLANDS_SPLL_DIV_TABLE;
> +
> +#define NISLANDS_SMC_FIRMWARE_HEADER_LOCATION 0x100
> +
> +#define NISLANDS_SMC_FIRMWARE_HEADER_version                   0x0
> +#define NISLANDS_SMC_FIRMWARE_HEADER_flags                     0x4
> +#define NISLANDS_SMC_FIRMWARE_HEADER_softRegisters             0x8
> +#define NISLANDS_SMC_FIRMWARE_HEADER_stateTable                0xC
> +#define NISLANDS_SMC_FIRMWARE_HEADER_fanTable                  0x10
> +#define NISLANDS_SMC_FIRMWARE_HEADER_cacTable                  0x14
> +#define NISLANDS_SMC_FIRMWARE_HEADER_mcRegisterTable           0x20
> +#define NISLANDS_SMC_FIRMWARE_HEADER_mcArbDramAutoRefreshTable 0x2C
> +#define NISLANDS_SMC_FIRMWARE_HEADER_spllTable                 0x30
> +
> +#pragma pack(pop)
> +
> +#endif
> +
> diff --git a/drivers/gpu/drm/radeon/ppsmc.h b/drivers/gpu/drm/radeon/ppsmc.h
> index 3d0786f..607982a 100644
> --- a/drivers/gpu/drm/radeon/ppsmc.h
> +++ b/drivers/gpu/drm/radeon/ppsmc.h
> @@ -46,6 +46,7 @@
>  #define PPSMC_DISPLAY_WATERMARK_HIGH                    1
>  
>  #define PPSMC_STATEFLAG_AUTO_PULSE_SKIP    0x01
> +#define PPSMC_STATEFLAG_POWERBOOST         0x02
>  
>  #define PPSMC_Result_OK             ((uint8_t)0x01)
>  #define PPSMC_Result_Failed         ((uint8_t)0xFF)
> @@ -56,17 +57,28 @@ typedef uint8_t PPSMC_Result;
>  #define PPSMC_MSG_Resume                    ((uint8_t)0x11)
>  #define PPSMC_MSG_TwoLevelsDisabled         ((uint8_t)0x15)
>  #define PPSMC_MSG_EnableThermalInterrupt    ((uint8_t)0x16)
> +#define PPSMC_MSG_RunningOnAC               ((uint8_t)0x17)
>  #define PPSMC_MSG_SwitchToSwState           ((uint8_t)0x20)
>  #define PPSMC_MSG_SwitchToInitialState      ((uint8_t)0x40)
>  #define PPSMC_MSG_NoForcedLevel             ((uint8_t)0x41)
>  #define PPSMC_MSG_SwitchToMinimumPower      ((uint8_t)0x51)
>  #define PPSMC_MSG_ResumeFromMinimumPower    ((uint8_t)0x52)
> +#define PPSMC_MSG_EnableCac                 ((uint8_t)0x53)
> +#define PPSMC_MSG_DisableCac                ((uint8_t)0x54)
> +#define PPSMC_TDPClampingActive             ((uint8_t)0x59)
> +#define PPSMC_TDPClampingInactive           ((uint8_t)0x5A)
>  #define PPSMC_MSG_NoDisplay                 ((uint8_t)0x5D)
>  #define PPSMC_MSG_HasDisplay                ((uint8_t)0x5E)
> +#define PPSMC_MSG_UVDPowerOFF               ((uint8_t)0x60)
> +#define PPSMC_MSG_UVDPowerON                ((uint8_t)0x61)
>  #define PPSMC_MSG_EnableULV                 ((uint8_t)0x62)
>  #define PPSMC_MSG_DisableULV                ((uint8_t)0x63)
>  #define PPSMC_MSG_EnterULV                  ((uint8_t)0x64)
>  #define PPSMC_MSG_ExitULV                   ((uint8_t)0x65)
> +#define PPSMC_CACLongTermAvgEnable          ((uint8_t)0x6E)
> +#define PPSMC_CACLongTermAvgDisable         ((uint8_t)0x6F)
> +#define PPSMC_MSG_CollectCAC_PowerCorreln   ((uint8_t)0x7A)
> +#define PPSMC_MSG_SetEnabledLevels          ((uint8_t)0x82)
>  #define PPSMC_MSG_ResetToDefaults           ((uint8_t)0x84)
>  
>  /* TN */
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c
> index 5dcbb28..e6703ef 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.c
> +++ b/drivers/gpu/drm/radeon/radeon_asic.c
> @@ -1804,6 +1804,18 @@ static struct radeon_asic cayman_asic = {
>  		.set_uvd_clocks = &evergreen_set_uvd_clocks,
>  		.get_temperature = &evergreen_get_temp,
>  	},
> +	.dpm = {
> +		.init = &ni_dpm_init,
> +		.setup_asic = &ni_dpm_setup_asic,
> +		.enable = &ni_dpm_enable,
> +		.disable = &ni_dpm_disable,
> +		.set_power_state = &ni_dpm_set_power_state,
> +		.display_configuration_changed = &cypress_dpm_display_configuration_changed,
> +		.fini = &ni_dpm_fini,
> +		.get_sclk = &ni_dpm_get_sclk,
> +		.get_mclk = &ni_dpm_get_mclk,
> +		.print_power_state = &ni_dpm_print_power_state,
> +	},
>  	.pflip = {
>  		.pre_page_flip = &evergreen_pre_page_flip,
>  		.page_flip = &evergreen_page_flip,
> diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
> index 4d3f93d..2fef64d 100644
> --- a/drivers/gpu/drm/radeon/radeon_asic.h
> +++ b/drivers/gpu/drm/radeon/radeon_asic.h
> @@ -581,6 +581,16 @@ bool cayman_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
>  bool cayman_dma_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring);
>  void cayman_dma_vm_flush(struct radeon_device *rdev, int ridx, struct radeon_vm *vm);
>  
> +int ni_dpm_init(struct radeon_device *rdev);
> +void ni_dpm_setup_asic(struct radeon_device *rdev);
> +int ni_dpm_enable(struct radeon_device *rdev);
> +void ni_dpm_disable(struct radeon_device *rdev);
> +int ni_dpm_set_power_state(struct radeon_device *rdev);
> +void ni_dpm_fini(struct radeon_device *rdev);
> +u32 ni_dpm_get_sclk(struct radeon_device *rdev, bool low);
> +u32 ni_dpm_get_mclk(struct radeon_device *rdev, bool low);
> +void ni_dpm_print_power_state(struct radeon_device *rdev,
> +			      struct radeon_ps *ps);
>  int trinity_dpm_init(struct radeon_device *rdev);
>  int trinity_dpm_enable(struct radeon_device *rdev);
>  void trinity_dpm_disable(struct radeon_device *rdev);
> diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
> index 2eb41be..01ff18b 100644
> --- a/drivers/gpu/drm/radeon/radeon_pm.c
> +++ b/drivers/gpu/drm/radeon/radeon_pm.c
> @@ -1100,6 +1100,7 @@ int radeon_pm_init(struct radeon_device *rdev)
>  	case CHIP_BARTS:
>  	case CHIP_TURKS:
>  	case CHIP_CAICOS:
> +	case CHIP_CAYMAN:
>  	case CHIP_ARUBA:
>  		if (radeon_dpm == 1)
>  			rdev->pm.pm_method = PM_METHOD_DPM;
> diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h
> index e592e27..51beb4c 100644
> --- a/drivers/gpu/drm/radeon/radeon_ucode.h
> +++ b/drivers/gpu/drm/radeon/radeon_ucode.h
> @@ -100,4 +100,9 @@
>  #define CAICOS_SMC_INT_VECTOR_START  0xffc0
>  #define CAICOS_SMC_INT_VECTOR_SIZE   0x0040
>  
> +#define CAYMAN_SMC_UCODE_START       0x0100
> +#define CAYMAN_SMC_UCODE_SIZE        0x79ec
> +#define CAYMAN_SMC_INT_VECTOR_START  0xffc0
> +#define CAYMAN_SMC_INT_VECTOR_SIZE   0x0040
> +
>  #endif
> diff --git a/drivers/gpu/drm/radeon/rv770_smc.c b/drivers/gpu/drm/radeon/rv770_smc.c
> index 0078c59..ab95da5 100644
> --- a/drivers/gpu/drm/radeon/rv770_smc.c
> +++ b/drivers/gpu/drm/radeon/rv770_smc.c
> @@ -254,6 +254,26 @@ static const u8 caicos_smc_int_vectors[] =
>  	0x05, 0x0A, 0x05, 0x0A
>  };
>  
> +static const u8 cayman_smc_int_vectors[] =
> +{
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x12, 0x05,
> +	0x12, 0x05, 0x18, 0xEA,
> +	0x12, 0x20, 0x1C, 0x34,
> +	0x1C, 0x34, 0x08, 0x72,
> +	0x08, 0x72, 0x08, 0x72
> +};
> +
>  int rv770_set_smc_sram_address(struct radeon_device *rdev,
>  			       u16 smc_address, u16 limit)
>  {
> @@ -544,6 +564,13 @@ int rv770_load_smc_ucode(struct radeon_device *rdev,
>  		int_vect_start_address = CAICOS_SMC_INT_VECTOR_START;
>  		int_vect_size = CAICOS_SMC_INT_VECTOR_SIZE;
>  		break;
> +	case CHIP_CAYMAN:
> +		ucode_start_address = CAYMAN_SMC_UCODE_START;
> +		ucode_size = CAYMAN_SMC_UCODE_SIZE;
> +		int_vect = (const u8 *)&cayman_smc_int_vectors;
> +		int_vect_start_address = CAYMAN_SMC_INT_VECTOR_START;
> +		int_vect_size = CAYMAN_SMC_INT_VECTOR_SIZE;
> +		break;
>  	default:
>  		DRM_ERROR("unknown asic in smc ucode loader\n");
>  		BUG();
> -- 
> 1.7.7.5
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2013-06-26 16:34 UTC|newest]

Thread overview: 142+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-26 13:21 [PATCH 000/165] radeon drm-next patches alexdeucher
2013-06-26 12:55 ` Jerome Glisse
2013-06-26 13:21 ` [PATCH 001/165] drm/radeon: fix AVI infoframe generation alexdeucher
2013-06-26 13:21 ` [PATCH 002/165] drm/radeon: add backlight quirk for hybrid mac alexdeucher
2013-06-26 13:21 ` [PATCH 003/165] drm/radeon: add a reset work handler alexdeucher
2013-06-26 13:21 ` [PATCH 004/165] drm/radeon: add CIK chip families alexdeucher
2013-06-26 13:21 ` [PATCH 005/165] drm/radeon: add DCE8 macro for CIK alexdeucher
2013-06-26 13:21 ` [PATCH 006/165] drm/radeon: adapt to PCI BAR changes on CIK alexdeucher
2013-06-26 13:21 ` [PATCH 007/165] drm/radeon: add gpu init support for CIK (v9) alexdeucher
2013-06-26 13:21 ` [PATCH 008/165] drm/radeon: Add support for CIK GPU reset (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 009/165] drm/radeon: add support for MC/VM setup on CIK (v6) alexdeucher
2013-06-26 13:21 ` [PATCH 010/165] drm/radeon/cik: stop page faults from hanging the system (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 011/165] drm/radeon: add initial ucode loading for CIK (v5) alexdeucher
2013-06-26 13:21 ` [PATCH 012/165] drm/radeon: add support mc ucode loading on CIK (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 013/165] drm/radeon: Add CP init for CIK (v7) alexdeucher
2013-06-26 13:21 ` [PATCH 014/165] drm/radeon: add IB and fence dispatch functions for CIK gfx (v7) alexdeucher
2013-06-26 13:21 ` [PATCH 015/165] drm/radeon: add ring and IB tests for CIK (v3) alexdeucher
2013-06-26 13:21 ` [PATCH 016/165] drm/radeon: implement async vm_flush for the CP (v7) alexdeucher
2013-06-26 13:21 ` [PATCH 017/165] drm/radeon: Add support for RLC init on CIK (v4) alexdeucher
2013-06-26 13:21 ` [PATCH 018/165] drm/radeon: add support for interrupts on CIK (v5) alexdeucher
2013-06-26 13:21 ` [PATCH 019/165] drm/radeon/cik: log and handle VM page fault interrupts alexdeucher
2013-06-26 13:21 ` [PATCH 020/165] drm/radeon/cik: add support for sDMA dma engines (v8) alexdeucher
2013-06-26 13:21 ` [PATCH 021/165] drm/radeon: implement async vm_flush for the sDMA (v6) alexdeucher
2013-06-26 13:21 ` [PATCH 022/165] drm/radeon/cik: add support for doing async VM pt updates (v5) alexdeucher
2013-06-26 13:21 ` [PATCH 023/165] drm/radeon/cik: fill in startup/shutdown callbacks (v4) alexdeucher
2013-06-26 15:03   ` Christian König
2013-06-26 13:21 ` [PATCH 024/165] drm/radeon: upstream ObjectID.h updates (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 025/165] drm/radeon: upstream atombios.h " alexdeucher
2013-06-26 13:21 ` [PATCH 026/165] drm/radeon: atombios power table " alexdeucher
2013-06-26 13:21 ` [PATCH 027/165] drm/radeon: handle the integrated thermal controller on CI alexdeucher
2013-06-26 13:21 ` [PATCH 028/165] drm/radeon: update power state parsing for CI alexdeucher
2013-06-26 13:21 ` [PATCH 029/165] drm/radeon/dce8: add support for display watermark setup alexdeucher
2013-06-26 13:21 ` [PATCH 030/165] drm/radeon/cik: add hw cursor support (v2) alexdeucher
2013-06-26 13:21 ` [PATCH 031/165] drm/radeon/dce8: properly handle interlaced timing alexdeucher
2013-06-26 13:21 ` [PATCH 032/165] drm/radeon/dce8: crtc_set_base updates alexdeucher
2013-06-26 13:21 ` [PATCH 033/165] drm/radeon/atom: add DCE8 encoder support alexdeucher
2013-06-26 13:21 ` [PATCH 034/165] drm/radeon/atom: add support for new DVO tables alexdeucher
2013-06-26 13:21 ` [PATCH 035/165] drm/radeon: update DISPCLK programming for DCE8 alexdeucher
2013-06-26 13:21 ` [PATCH 036/165] drm/radeon: add support pll selection for DCE8 (v4) alexdeucher
2013-06-26 13:21 ` [PATCH 037/165] drm/radeon: Handle PPLL0 powerdown on DCE8 alexdeucher
2013-06-26 13:21 ` [PATCH 038/165] drm/radeon: use frac fb div " alexdeucher
2013-06-26 13:21 ` [PATCH 039/165] drm/radeon: add SS override support for KB/KV alexdeucher
2013-06-26 13:22 ` [PATCH 040/165] drm/radeon: Update radeon_info_ioctl for CIK (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 041/165] drm/radeon: add get_gpu_clock_counter() callback for cik alexdeucher
2013-06-26 13:22 ` [PATCH 042/165] drm/radeon: update CIK soft reset alexdeucher
2013-06-26 13:22 ` [PATCH 043/165] drm/radeon: add indirect register accessors for SMC registers alexdeucher
2013-06-26 13:22 ` [PATCH 044/165] drm/radeon: add get_xclk() callback for CIK alexdeucher
2013-06-26 13:22 ` [PATCH 045/165] drm/radeon/cik: add pcie_port indirect register accessors alexdeucher
2013-06-26 13:22 ` [PATCH 046/165] drm/radeon: update radeon_atom_get_clock_dividers() for SI alexdeucher
2013-06-26 13:22 ` [PATCH 047/165] drm/radeon: update radeon_atom_get_clock_dividers for CIK alexdeucher
2013-06-26 13:22 ` [PATCH 048/165] drm/radeon: add UVD support for CIK (v3) alexdeucher
2013-06-26 13:22 ` [PATCH 049/165] drm/radeon/cik: add srbm_select function alexdeucher
2013-06-26 13:22 ` [PATCH 050/165] drm/radeon: use callbacks for ring pointer handling alexdeucher
2013-06-26 15:31   ` Christian König
2013-06-26 13:22 ` [PATCH 051/165] drm/radeon: implement simple doorbell page allocator alexdeucher
2013-06-26 12:57   ` Jerome Glisse
2013-06-26 18:38     ` Alex Deucher
2013-06-26 13:22 ` [PATCH 052/165] drm/radeon/cik: Add support for compute queues (v2) alexdeucher
2013-06-26 10:08   ` Jerome Glisse
2013-06-26 13:22 ` [PATCH 053/165] drm/radeon/cik: switch to type3 nop packet for compute rings alexdeucher
2013-06-26 10:10   ` Jerome Glisse
2013-06-26 13:22 ` [PATCH 054/165] drm/radeon: fix up ring functions " alexdeucher
2013-06-26 13:22 ` [PATCH 055/165] drm/radeon/cik: add support for compute interrupts alexdeucher
2013-06-26 13:22 ` [PATCH 056/165] drm/radeon/cik: add support for golden register init alexdeucher
2013-06-26 13:22 ` [PATCH 057/165] drm/radeon: add radeon_asic struct for CIK (v11) alexdeucher
2013-06-26 13:22 ` [PATCH 058/165] drm/radeon: add cik tile mode array query alexdeucher
2013-06-26 13:22 ` [PATCH 059/165] drm/radeon: add current Bonaire PCI ids alexdeucher
2013-06-26 13:22 ` [PATCH 060/165] drm/radeon: add current KB pci ids alexdeucher
2013-06-26 13:22 ` [PATCH 061/165] drm/radeon/kms: add accessors for RCU indirect space alexdeucher
2013-06-26 13:22 ` [PATCH 062/165] drm/radeon/evergreen: add indirect register accessors for CG registers alexdeucher
2013-06-26 13:22 ` [PATCH 063/165] drm/radeon: make get_temperature functions a callback alexdeucher
2013-06-26 13:22 ` [PATCH 064/165] drm/radeon: add support for thermal sensor on tn alexdeucher
2013-06-26 13:22 ` [PATCH 065/165] drm/radeon/kms: move ucode defines to a separate header alexdeucher
2013-06-26 13:22 ` [PATCH 066/165] drm/radeon: properly set up the RLC on ON/LN/TN (v3) alexdeucher
2013-06-26 13:22 ` [PATCH 067/165] drm/radeon/kms: add atom helper functions for dpm (v3) alexdeucher
2013-06-26 13:22 ` [PATCH 068/165] drm/radeon/kms: add new asic struct for rv6xx (v3) alexdeucher
2013-06-26 13:22 ` [PATCH 069/165] drm/radeon/kms: add common dpm infrastructure alexdeucher
2013-06-26 10:27   ` Jerome Glisse
2013-06-27 13:52   ` K. Schnass
2013-06-26 13:22 ` [PATCH 070/165] drm/radeon/kms: fix up rs780/rs880 display watermark calc for dpm alexdeucher
2013-06-26 13:22 ` [PATCH 071/165] drm/radeon/kms: fix up 6xx/7xx " alexdeucher
2013-06-26 13:22 ` [PATCH 072/165] drm/radeon/kms: fix up dce4/5 " alexdeucher
2013-06-26 13:22 ` [PATCH 073/165] drm/radeon/kms: fix up dce6 " alexdeucher
2013-06-26 13:22 ` [PATCH 074/165] drm/radeon/kms: add common r600 dpm functions alexdeucher
2013-06-26 13:22 ` [PATCH 075/165] drm/radeon/kms: add dpm support for rs780/rs880 alexdeucher
2013-06-26 10:46   ` Jerome Glisse
2013-06-26 18:19     ` Alex Deucher
2013-06-26 13:18       ` Jerome Glisse
2013-06-26 18:41         ` Alex Deucher
2013-06-26 13:22 ` [PATCH 076/165] drm/radeon/kms: add dpm support for rv6xx alexdeucher
2013-06-26 16:45   ` Christian König
2013-06-26 13:22 ` [PATCH 077/165] drm/radeon/kms: add dpm support for rv7xx (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 078/165] drm/radeon/kms: add dpm support for evergreen (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 079/165] drm/radeon/kms: add dpm support for btc (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 080/165] drm/radeon/kms: add dpm support for sumo asics alexdeucher
2013-06-26 11:19   ` Jerome Glisse
2013-06-26 13:22 ` [PATCH 081/165] drm/radeon/kms: add dpm support for trinity asics alexdeucher
2013-06-26 13:22 ` [PATCH 082/165] drm/radeon/dpm: let atom control display phy powergating alexdeucher
2013-06-26 13:22 ` [PATCH 083/165] drm/radeon: add dpm UVD handling for r7xx asics alexdeucher
2013-06-26 13:22 ` [PATCH 084/165] drm/radeon: add dpm UVD handling for evergreen/btc asics alexdeucher
2013-06-26 13:22 ` [PATCH 085/165] drm/radeon: add dpm UVD handling for sumo asics alexdeucher
2013-06-26 13:22 ` [PATCH 086/165] drm/radeon: add dpm UVD handling for TN asics (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 087/165] drm/radeon/kms: enable UVD as needed (v9) alexdeucher
2013-06-26 13:22 ` [PATCH 088/165] drm/radeon/dpm: add helpers for extended power tables (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 089/165] drm/radeon/dpm: track whether we are on AC or battery alexdeucher
2013-06-26 13:22 ` [PATCH 090/165] drm/radeon/dpm: fixup dynamic state adjust for sumo alexdeucher
2013-06-26 13:22 ` [PATCH 091/165] drm/radeon/dpm: fixup dynamic state adjust for TN alexdeucher
2013-06-26 13:22 ` [PATCH 092/165] drm/radeon/dpm: fixup dynamic state adjust for btc (v2) alexdeucher
2013-06-26 13:22 ` [PATCH 093/165] drm/radeon/kms: add dpm support for cayman alexdeucher
2013-06-26 11:29   ` Jerome Glisse [this message]
2013-06-26 13:22 ` [PATCH 094/165] drm/radeon/cayman: update tdp limits in set_power_state alexdeucher
2013-06-26 13:22 ` [PATCH 095/165] drm/radeon/dpm/rs780: restructure code alexdeucher
2013-06-26 13:22 ` [PATCH 096/165] drm/radeon/dpm/rv6xx: " alexdeucher
2013-06-26 13:22 ` [PATCH 097/165] drm/radeon/dpm/rv7xx: " alexdeucher
2013-06-26 13:22 ` [PATCH 098/165] drm/radeon/dpm/evergreen: " alexdeucher
2013-06-26 13:22 ` [PATCH 099/165] drm/radeon/dpm/btc: " alexdeucher
2013-06-26 13:23 ` [PATCH 100/165] drm/radeon/dpm/cayman: " alexdeucher
2013-06-26 13:23 ` [PATCH 101/165] drm/radeon/dpm/sumo: " alexdeucher
2013-06-26 13:23 ` [PATCH 102/165] drm/radeon/dpm/tn: " alexdeucher
2013-06-26 13:23 ` [PATCH 103/165] drm/radeon/dpm: add new pre/post_set_power_state callbacks alexdeucher
2013-06-26 13:23 ` [PATCH 104/165] drm/radeon/dpm: add pre/post_set_power_state callbacks (6xx-eg) alexdeucher
2013-06-26 13:23 ` [PATCH 105/165] drm/radeon/dpm: add pre/post_set_power_state callback (sumo) alexdeucher
2013-06-26 13:23 ` [PATCH 106/165] drm/radeon/dpm: add pre/post_set_power_state callback (TN) alexdeucher
2013-06-26 13:23 ` [PATCH 107/165] drm/radeon/dpm: add pre/post_set_power_state callback (BTC) alexdeucher
2013-06-26 13:23 ` [PATCH 108/165] drm/radeon/dpm: add pre/post_set_power_state callback (cayman) alexdeucher
2013-06-26 13:23 ` [PATCH 109/165] drm/radeon/dpm: remove broken dyn state remnants alexdeucher
2013-06-26 13:23 ` [PATCH 110/165] drm/radeon: add missing UVD clock set in cayman dpm code alexdeucher
2013-06-26 13:23 ` [PATCH 111/165] drm/radeon/dpm: remove local sumo_get_xclk() alexdeucher
2013-06-26 21:57 ` [PATCH 000/165] radeon drm-next patches Julian Wollrath
2013-06-26 22:51   ` Julian Wollrath
2013-06-27 14:21     ` Jerome Glisse
2013-06-27 21:26       ` Julian Wollrath
2013-06-29 17:37   ` Grigori Goronzy
2013-06-26 22:23 ` Alex Deucher
2013-06-27 13:12   ` Andy Furniss
2013-06-27 14:55     ` Alex Deucher
2013-06-27 22:19       ` James Cloos
2013-06-27 22:52         ` Jerome Glisse
2013-06-27 23:55     ` Alex Deucher
2013-06-28 13:00       ` Laurent Carlier
2013-06-29  9:28       ` Andy Furniss
2013-06-29 10:23         ` Ilyes Gouta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130626112928.GF2480@gmail.com \
    --to=j.glisse@gmail.com \
    --cc=alexander.deucher@amd.com \
    --cc=alexdeucher@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.