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

Commit 5615f890 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/radeon: add si dpm quirk list

This adds a quirks list to fix stability problems with
certain SI boards.

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=76490



Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent ad1a6222
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -2908,6 +2908,22 @@ static int si_init_smc_spll_table(struct radeon_device *rdev)
	return ret;
}

struct si_dpm_quirk {
	u32 chip_vendor;
	u32 chip_device;
	u32 subsys_vendor;
	u32 subsys_device;
	u32 max_sclk;
	u32 max_mclk;
};

/* cards with dpm stability problems */
static struct si_dpm_quirk si_dpm_quirk_list[] = {
	/* PITCAIRN - https://bugs.freedesktop.org/show_bug.cgi?id=76490 */
	{ PCI_VENDOR_ID_ATI, 0x6810, 0x1462, 0x3036, 0, 120000 },
	{ 0, 0, 0, 0 },
};

static void si_apply_state_adjust_rules(struct radeon_device *rdev,
					struct radeon_ps *rps)
{
@@ -2918,7 +2934,22 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
	u32 mclk, sclk;
	u16 vddc, vddci;
	u32 max_sclk_vddc, max_mclk_vddci, max_mclk_vddc;
	u32 max_sclk = 0, max_mclk = 0;
	int i;
	struct si_dpm_quirk *p = si_dpm_quirk_list;

	/* Apply dpm quirks */
	while (p && p->chip_device != 0) {
		if (rdev->pdev->vendor == p->chip_vendor &&
		    rdev->pdev->device == p->chip_device &&
		    rdev->pdev->subsystem_vendor == p->subsys_vendor &&
		    rdev->pdev->subsystem_device == p->subsys_device) {
			max_sclk = p->max_sclk;
			max_mclk = p->max_mclk;
			break;
		}
		++p;
	}

	if ((rdev->pm.dpm.new_active_crtc_count > 1) ||
	    ni_dpm_vblank_too_short(rdev))
@@ -2972,6 +3003,14 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
			if (ps->performance_levels[i].mclk > max_mclk_vddc)
				ps->performance_levels[i].mclk = max_mclk_vddc;
		}
		if (max_mclk) {
			if (ps->performance_levels[i].mclk > max_mclk)
				ps->performance_levels[i].mclk = max_mclk;
		}
		if (max_sclk) {
			if (ps->performance_levels[i].sclk > max_sclk)
				ps->performance_levels[i].sclk = max_sclk;
		}
	}

	/* XXX validate the min clocks required for display */