mirror of https://gitee.com/openkylin/linux.git
drm/radeon: handle ss percentage divider properly
It's either 100 or 1000 depending on the flags in the table. Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
f5f1f897c8
commit
18f8f52b9a
|
@ -1042,15 +1042,17 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode
|
||||||
/* calculate ss amount and step size */
|
/* calculate ss amount and step size */
|
||||||
if (ASIC_IS_DCE4(rdev)) {
|
if (ASIC_IS_DCE4(rdev)) {
|
||||||
u32 step_size;
|
u32 step_size;
|
||||||
u32 amount = (((fb_div * 10) + frac_fb_div) * radeon_crtc->ss.percentage) / 10000;
|
u32 amount = (((fb_div * 10) + frac_fb_div) *
|
||||||
|
(u32)radeon_crtc->ss.percentage) /
|
||||||
|
(100 * (u32)radeon_crtc->ss.percentage_divider);
|
||||||
radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
|
radeon_crtc->ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
|
||||||
radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
|
radeon_crtc->ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
|
||||||
ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
|
ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
|
||||||
if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
|
if (radeon_crtc->ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
|
||||||
step_size = (4 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) /
|
step_size = (4 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) /
|
||||||
(125 * 25 * pll->reference_freq / 100);
|
(125 * 25 * pll->reference_freq / 100);
|
||||||
else
|
else
|
||||||
step_size = (2 * amount * ref_div * (radeon_crtc->ss.rate * 2048)) /
|
step_size = (2 * amount * ref_div * ((u32)radeon_crtc->ss.rate * 2048)) /
|
||||||
(125 * 25 * pll->reference_freq / 100);
|
(125 * 25 * pll->reference_freq / 100);
|
||||||
radeon_crtc->ss.step = step_size;
|
radeon_crtc->ss.step = step_size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1511,6 +1511,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
|
||||||
le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage);
|
le16_to_cpu(ss_assign->v1.usSpreadSpectrumPercentage);
|
||||||
ss->type = ss_assign->v1.ucSpreadSpectrumMode;
|
ss->type = ss_assign->v1.ucSpreadSpectrumMode;
|
||||||
ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz);
|
ss->rate = le16_to_cpu(ss_assign->v1.usSpreadRateInKhz);
|
||||||
|
ss->percentage_divider = 100;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ss_assign = (union asic_ss_assignment *)
|
ss_assign = (union asic_ss_assignment *)
|
||||||
|
@ -1528,6 +1529,7 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
|
||||||
le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage);
|
le16_to_cpu(ss_assign->v2.usSpreadSpectrumPercentage);
|
||||||
ss->type = ss_assign->v2.ucSpreadSpectrumMode;
|
ss->type = ss_assign->v2.ucSpreadSpectrumMode;
|
||||||
ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz);
|
ss->rate = le16_to_cpu(ss_assign->v2.usSpreadRateIn10Hz);
|
||||||
|
ss->percentage_divider = 100;
|
||||||
if ((crev == 2) &&
|
if ((crev == 2) &&
|
||||||
((id == ASIC_INTERNAL_ENGINE_SS) ||
|
((id == ASIC_INTERNAL_ENGINE_SS) ||
|
||||||
(id == ASIC_INTERNAL_MEMORY_SS)))
|
(id == ASIC_INTERNAL_MEMORY_SS)))
|
||||||
|
@ -1549,6 +1551,11 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev,
|
||||||
le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage);
|
le16_to_cpu(ss_assign->v3.usSpreadSpectrumPercentage);
|
||||||
ss->type = ss_assign->v3.ucSpreadSpectrumMode;
|
ss->type = ss_assign->v3.ucSpreadSpectrumMode;
|
||||||
ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz);
|
ss->rate = le16_to_cpu(ss_assign->v3.usSpreadRateIn10Hz);
|
||||||
|
if (ss_assign->v3.ucSpreadSpectrumMode &
|
||||||
|
SS_MODE_V3_PERCENTAGE_DIV_BY_1000_MASK)
|
||||||
|
ss->percentage_divider = 1000;
|
||||||
|
else
|
||||||
|
ss->percentage_divider = 100;
|
||||||
if ((id == ASIC_INTERNAL_ENGINE_SS) ||
|
if ((id == ASIC_INTERNAL_ENGINE_SS) ||
|
||||||
(id == ASIC_INTERNAL_MEMORY_SS))
|
(id == ASIC_INTERNAL_MEMORY_SS))
|
||||||
ss->rate /= 100;
|
ss->rate /= 100;
|
||||||
|
|
|
@ -291,6 +291,7 @@ struct radeon_tv_regs {
|
||||||
|
|
||||||
struct radeon_atom_ss {
|
struct radeon_atom_ss {
|
||||||
uint16_t percentage;
|
uint16_t percentage;
|
||||||
|
uint16_t percentage_divider;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
uint16_t step;
|
uint16_t step;
|
||||||
uint8_t delay;
|
uint8_t delay;
|
||||||
|
|
Loading…
Reference in New Issue