Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69e0b57a authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon/kms: add dpm support for cayman (v5)



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.

v2: fold in tdp fix
v3: fix indentation
v4: fix 64 bit div
v5: attempt to fix state enable

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reviewed-by: default avatarJerome Glisse <jglisse@redhat.com>
parent d22b7e40
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+18 −18
Original line number Diff line number Diff line
@@ -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,7 +1168,7 @@ 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,
void btc_apply_voltage_dependency_rules(struct radeon_clock_voltage_dependency_table *table,
					u32 clock, u16 max_voltage, u16 *voltage)
{
	u32 i;
@@ -1219,7 +1219,7 @@ static u32 btc_get_valid_sclk(struct radeon_device *rdev,
				    max_sclk, requested_sclk);
}

static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
void btc_skip_blacklist_clocks(struct radeon_device *rdev,
			       const u32 max_sclk, const u32 max_mclk,
			       u32 *sclk, u32 *mclk)
{
@@ -1246,7 +1246,7 @@ static void btc_skip_blacklist_clocks(struct radeon_device *rdev,
	}
}

static void btc_adjust_clock_combinations(struct radeon_device *rdev,
void btc_adjust_clock_combinations(struct radeon_device *rdev,
				   const struct radeon_clock_and_voltage_limits *max_limits,
				   struct rv7xx_pl *pl)
{
@@ -1285,7 +1285,7 @@ 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,
void btc_apply_voltage_delta_rules(struct radeon_device *rdev,
				   u16 max_vddc, u16 max_vddci,
				   u16 *vddc, u16 *vddci)
{
@@ -1417,7 +1417,7 @@ static int btc_populate_smc_acpi_state(struct radeon_device *rdev,
	return ret;
}

static void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
void btc_program_mgcg_hw_sequence(struct radeon_device *rdev,
				  const u32 *sequence, u32 count)
{
	u32 i, length = count * 3;
@@ -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 =
+19 −1
Original line number Diff line number Diff line
@@ -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
+4 −7
Original line number Diff line number Diff line
@@ -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,7 +600,7 @@ static int cypress_populate_mclk_value(struct radeon_device *rdev,
	return 0;
}

static u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
u8 cypress_get_mclk_frequency_ratio(struct radeon_device *rdev,
				    u32 memory_clock, bool strobe_mode)
{
	u8 mc_para_index;
+4 −0
Original line number Diff line number Diff line
@@ -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
Loading