提交 b792210e 编写于 作者: A Alex Deucher 提交者: Dave Airlie

drm/radeon/kms/atom: spread spectrum fix

The atom spread spectrum table does not always
disable ss.  Explicitly disable it and then use
the atom table to enable later if needed (currently
only used for LVDS).

Fixes display issues on some systems.
Signed-off-by: NAlex Deucher <alexdeucher@gmail.com>
Cc: stable@kernel.org
Signed-off-by: NDave Airlie <airlied@redhat.com>
上级 c21b0fe6
...@@ -353,12 +353,55 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc, ...@@ -353,12 +353,55 @@ static void atombios_crtc_set_timing(struct drm_crtc *crtc,
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
} }
static void atombios_disable_ss(struct drm_crtc *crtc)
{
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev;
struct radeon_device *rdev = dev->dev_private;
u32 ss_cntl;
if (ASIC_IS_DCE4(rdev)) {
switch (radeon_crtc->pll_id) {
case ATOM_PPLL1:
ss_cntl = RREG32(EVERGREEN_P1PLL_SS_CNTL);
ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
WREG32(EVERGREEN_P1PLL_SS_CNTL, ss_cntl);
break;
case ATOM_PPLL2:
ss_cntl = RREG32(EVERGREEN_P2PLL_SS_CNTL);
ss_cntl &= ~EVERGREEN_PxPLL_SS_EN;
WREG32(EVERGREEN_P2PLL_SS_CNTL, ss_cntl);
break;
case ATOM_DCPLL:
case ATOM_PPLL_INVALID:
return;
}
} else if (ASIC_IS_AVIVO(rdev)) {
switch (radeon_crtc->pll_id) {
case ATOM_PPLL1:
ss_cntl = RREG32(AVIVO_P1PLL_INT_SS_CNTL);
ss_cntl &= ~1;
WREG32(AVIVO_P1PLL_INT_SS_CNTL, ss_cntl);
break;
case ATOM_PPLL2:
ss_cntl = RREG32(AVIVO_P2PLL_INT_SS_CNTL);
ss_cntl &= ~1;
WREG32(AVIVO_P2PLL_INT_SS_CNTL, ss_cntl);
break;
case ATOM_DCPLL:
case ATOM_PPLL_INVALID:
return;
}
}
}
union atom_enable_ss { union atom_enable_ss {
ENABLE_LVDS_SS_PARAMETERS legacy; ENABLE_LVDS_SS_PARAMETERS legacy;
ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1; ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION v1;
}; };
static void atombios_set_ss(struct drm_crtc *crtc, int enable) static void atombios_enable_ss(struct drm_crtc *crtc)
{ {
struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
struct drm_device *dev = crtc->dev; struct drm_device *dev = crtc->dev;
...@@ -387,9 +430,9 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) ...@@ -387,9 +430,9 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
step = dig->ss->step; step = dig->ss->step;
delay = dig->ss->delay; delay = dig->ss->delay;
range = dig->ss->range; range = dig->ss->range;
} else if (enable) } else
return; return;
} else if (enable) } else
return; return;
break; break;
} }
...@@ -406,13 +449,13 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable) ...@@ -406,13 +449,13 @@ static void atombios_set_ss(struct drm_crtc *crtc, int enable)
args.v1.ucSpreadSpectrumDelay = delay; args.v1.ucSpreadSpectrumDelay = delay;
args.v1.ucSpreadSpectrumRange = range; args.v1.ucSpreadSpectrumRange = range;
args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1; args.v1.ucPpll = radeon_crtc->crtc_id ? ATOM_PPLL2 : ATOM_PPLL1;
args.v1.ucEnable = enable; args.v1.ucEnable = ATOM_ENABLE;
} else { } else {
args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage); args.legacy.usSpreadSpectrumPercentage = cpu_to_le16(percentage);
args.legacy.ucSpreadSpectrumType = type; args.legacy.ucSpreadSpectrumType = type;
args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2; args.legacy.ucSpreadSpectrumStepSize_Delay = (step & 3) << 2;
args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4; args.legacy.ucSpreadSpectrumStepSize_Delay |= (delay & 7) << 4;
args.legacy.ucEnable = enable; args.legacy.ucEnable = ATOM_ENABLE;
} }
atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
} }
...@@ -1086,12 +1129,12 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, ...@@ -1086,12 +1129,12 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc,
/* pick pll */ /* pick pll */
radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); radeon_crtc->pll_id = radeon_atom_pick_pll(crtc);
atombios_set_ss(crtc, 0); atombios_disable_ss(crtc);
/* always set DCPLL */ /* always set DCPLL */
if (ASIC_IS_DCE4(rdev)) if (ASIC_IS_DCE4(rdev))
atombios_crtc_set_dcpll(crtc); atombios_crtc_set_dcpll(crtc);
atombios_crtc_set_pll(crtc, adjusted_mode); atombios_crtc_set_pll(crtc, adjusted_mode);
atombios_set_ss(crtc, 1); atombios_enable_ss(crtc);
if (ASIC_IS_DCE4(rdev)) if (ASIC_IS_DCE4(rdev))
atombios_set_crtc_dtd_timing(crtc, adjusted_mode); atombios_set_crtc_dtd_timing(crtc, adjusted_mode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册