Commit 6c7bccea authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon/pm: move pm handling into the asic specific code



We need more control over the ordering of dpm init with
respect to the rest of the asic.  Specifically, the SMC
has to be initialized before the rlc and cg/pg.  The pm
code currently initializes late in the driver, but we need
it to happen much earlier so move pm handling into the asic
specific callbacks.

This makes dpm more reliable and makes clockgating work
properly on CIK parts and should help on SI parts as well.

Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e14cd2bb
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ 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);

extern int ni_mc_load_microcode(struct radeon_device *rdev);

//********* BARTS **************//
static const u32 barts_cgcg_cgls_default[] =
@@ -2561,7 +2562,11 @@ void btc_dpm_disable(struct radeon_device *rdev)
void btc_dpm_setup_asic(struct radeon_device *rdev)
{
	struct evergreen_power_info *eg_pi = evergreen_get_pi(rdev);
	int r;

	r = ni_mc_load_microcode(rdev);
	if (r)
		DRM_ERROR("Failed to load MC firmware!\n");
	rv770_get_memory_type(rdev);
	rv740_read_clock_registers(rdev);
	btc_read_arb_registers(rdev);
+6 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ extern void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev,
						     struct atom_voltage_table *voltage_table);
extern void cik_enter_rlc_safe_mode(struct radeon_device *rdev);
extern void cik_exit_rlc_safe_mode(struct radeon_device *rdev);
extern int ci_mc_load_microcode(struct radeon_device *rdev);

static int ci_get_std_voltage_value_sidd(struct radeon_device *rdev,
					 struct atom_voltage_table_entry *voltage_table,
@@ -4547,6 +4548,11 @@ void ci_dpm_post_set_power_state(struct radeon_device *rdev)

void ci_dpm_setup_asic(struct radeon_device *rdev)
{
	int r;

	r = ci_mc_load_microcode(rdev);
	if (r)
		DRM_ERROR("Failed to load MC firmware!\n");
	ci_read_clock_registers(rdev);
	ci_get_memory_type(rdev);
	ci_enable_acpi_power_management(rdev);
+9 −2
Original line number Diff line number Diff line
@@ -1697,7 +1697,7 @@ static void cik_srbm_select(struct radeon_device *rdev,
 * Load the GDDR MC ucode into the hw (CIK).
 * Returns 0 on success, error on failure.
 */
static int ci_mc_load_microcode(struct radeon_device *rdev)
int ci_mc_load_microcode(struct radeon_device *rdev)
{
	const __be32 *fw_data;
	u32 running, blackout = 0;
@@ -7501,7 +7501,7 @@ static int cik_startup(struct radeon_device *rdev)

	cik_mc_program(rdev);

	if (!(rdev->flags & RADEON_IS_IGP)) {
	if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
		r = ci_mc_load_microcode(rdev);
		if (r) {
			DRM_ERROR("Failed to load MC firmware!\n");
@@ -7710,6 +7710,8 @@ int cik_resume(struct radeon_device *rdev)
	/* init golden registers */
	cik_init_golden_registers(rdev);

	radeon_pm_resume(rdev);

	rdev->accel_working = true;
	r = cik_startup(rdev);
	if (r) {
@@ -7733,6 +7735,7 @@ int cik_resume(struct radeon_device *rdev)
 */
int cik_suspend(struct radeon_device *rdev)
{
	radeon_pm_suspend(rdev);
	dce6_audio_fini(rdev);
	radeon_vm_manager_fini(rdev);
	cik_cp_enable(rdev, false);
@@ -7835,6 +7838,9 @@ int cik_init(struct radeon_device *rdev)
		}
	}

	/* Initialize power management */
	radeon_pm_init(rdev);

	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
	ring->ring_obj = NULL;
	r600_ring_init(rdev, ring, 1024 * 1024);
@@ -7915,6 +7921,7 @@ int cik_init(struct radeon_device *rdev)
 */
void cik_fini(struct radeon_device *rdev)
{
	radeon_pm_fini(rdev);
	cik_cp_fini(rdev);
	cik_sdma_fini(rdev);
	cik_fini_pg(rdev);
+8 −1
Original line number Diff line number Diff line
@@ -5109,7 +5109,7 @@ static int evergreen_startup(struct radeon_device *rdev)

	evergreen_mc_program(rdev);

	if (ASIC_IS_DCE5(rdev)) {
	if (ASIC_IS_DCE5(rdev) && !rdev->pm.dpm_enabled) {
		r = ni_mc_load_microcode(rdev);
		if (r) {
			DRM_ERROR("Failed to load MC firmware!\n");
@@ -5252,6 +5252,8 @@ int evergreen_resume(struct radeon_device *rdev)
	/* init golden registers */
	evergreen_init_golden_registers(rdev);

	radeon_pm_resume(rdev);

	rdev->accel_working = true;
	r = evergreen_startup(rdev);
	if (r) {
@@ -5266,6 +5268,7 @@ int evergreen_resume(struct radeon_device *rdev)

int evergreen_suspend(struct radeon_device *rdev)
{
	radeon_pm_suspend(rdev);
	r600_audio_fini(rdev);
	uvd_v1_0_fini(rdev);
	radeon_uvd_suspend(rdev);
@@ -5360,6 +5363,9 @@ int evergreen_init(struct radeon_device *rdev)
		}
	}

	/* Initialize power management */
	radeon_pm_init(rdev);

	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);

@@ -5412,6 +5418,7 @@ int evergreen_init(struct radeon_device *rdev)

void evergreen_fini(struct radeon_device *rdev)
{
	radeon_pm_fini(rdev);
	r600_audio_fini(rdev);
	r700_cp_fini(rdev);
	r600_dma_fini(rdev);
+8 −1
Original line number Diff line number Diff line
@@ -1866,7 +1866,7 @@ static int cayman_startup(struct radeon_device *rdev)

	evergreen_mc_program(rdev);

	if (!(rdev->flags & RADEON_IS_IGP)) {
	if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) {
		r = ni_mc_load_microcode(rdev);
		if (r) {
			DRM_ERROR("Failed to load MC firmware!\n");
@@ -2035,6 +2035,8 @@ int cayman_resume(struct radeon_device *rdev)
	/* init golden registers */
	ni_init_golden_registers(rdev);

	radeon_pm_resume(rdev);

	rdev->accel_working = true;
	r = cayman_startup(rdev);
	if (r) {
@@ -2047,6 +2049,7 @@ int cayman_resume(struct radeon_device *rdev)

int cayman_suspend(struct radeon_device *rdev)
{
	radeon_pm_suspend(rdev);
	if (ASIC_IS_DCE6(rdev))
		dce6_audio_fini(rdev);
	else
@@ -2135,6 +2138,9 @@ int cayman_init(struct radeon_device *rdev)
		}
	}

	/* Initialize power management */
	radeon_pm_init(rdev);

	ring->ring_obj = NULL;
	r600_ring_init(rdev, ring, 1024 * 1024);

@@ -2194,6 +2200,7 @@ int cayman_init(struct radeon_device *rdev)

void cayman_fini(struct radeon_device *rdev)
{
	radeon_pm_fini(rdev);
	cayman_cp_fini(rdev);
	cayman_dma_fini(rdev);
	r600_irq_fini(rdev);
Loading