mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 02:34:23 +08:00
drm/i915: Disable CLKOUT_DP bending on LPT/WPT as needed
When we want to use SPLL for FDI we want SSC, which means we have to disable clock bending for the PCH SSC reference (bend and spread are mutually exclusive). So let's turn off bending when we want spread. In case the BIOS enabled clock bending for some reason we'll just turn it off and enable the spread mode instead. Not sure what happens if the BIOS is actually using the bend source for HDMI at this time, but I suppose it should be no worse than what already happens when we simply turn on the spread. We don't currently use the bend source for anything, and only use the PCH SSC reference for the SPLL to drive FDI (always with spread). v2: Fix the %5 vs %10 fumble for SSCDITHPHASE (Paulo) Add 'WARN_ON(steps % 5 != 0)' sanity check (Paulo) Fix typos in commit message (Paulo) Cc: Paulo Zanoni <przanoni@gmail.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1449260379-14093-1-git-send-email-ville.syrjala@linux.intel.com Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
This commit is contained in:
parent
e7674b8c31
commit
f7be2c2150
@ -7327,6 +7327,7 @@ enum skl_disp_power_wells {
|
||||
#define SBI_READY (0x0<<0)
|
||||
|
||||
/* SBI offsets */
|
||||
#define SBI_SSCDIVINTPHASE 0x0200
|
||||
#define SBI_SSCDIVINTPHASE6 0x0600
|
||||
#define SBI_SSCDIVINTPHASE_DIVSEL_MASK ((0x7f)<<1)
|
||||
#define SBI_SSCDIVINTPHASE_DIVSEL(x) ((x)<<1)
|
||||
@ -7334,6 +7335,7 @@ enum skl_disp_power_wells {
|
||||
#define SBI_SSCDIVINTPHASE_INCVAL(x) ((x)<<8)
|
||||
#define SBI_SSCDIVINTPHASE_DIR(x) ((x)<<15)
|
||||
#define SBI_SSCDIVINTPHASE_PROPAGATE (1<<0)
|
||||
#define SBI_SSCDITHPHASE 0x0204
|
||||
#define SBI_SSCCTL 0x020c
|
||||
#define SBI_SSCCTL6 0x060C
|
||||
#define SBI_SSCCTL_PATHALT (1<<3)
|
||||
|
@ -8562,6 +8562,67 @@ static void lpt_disable_clkout_dp(struct drm_device *dev)
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
}
|
||||
|
||||
#define BEND_IDX(steps) ((50 + (steps)) / 5)
|
||||
|
||||
static const uint16_t sscdivintphase[] = {
|
||||
[BEND_IDX( 50)] = 0x3B23,
|
||||
[BEND_IDX( 45)] = 0x3B23,
|
||||
[BEND_IDX( 40)] = 0x3C23,
|
||||
[BEND_IDX( 35)] = 0x3C23,
|
||||
[BEND_IDX( 30)] = 0x3D23,
|
||||
[BEND_IDX( 25)] = 0x3D23,
|
||||
[BEND_IDX( 20)] = 0x3E23,
|
||||
[BEND_IDX( 15)] = 0x3E23,
|
||||
[BEND_IDX( 10)] = 0x3F23,
|
||||
[BEND_IDX( 5)] = 0x3F23,
|
||||
[BEND_IDX( 0)] = 0x0025,
|
||||
[BEND_IDX( -5)] = 0x0025,
|
||||
[BEND_IDX(-10)] = 0x0125,
|
||||
[BEND_IDX(-15)] = 0x0125,
|
||||
[BEND_IDX(-20)] = 0x0225,
|
||||
[BEND_IDX(-25)] = 0x0225,
|
||||
[BEND_IDX(-30)] = 0x0325,
|
||||
[BEND_IDX(-35)] = 0x0325,
|
||||
[BEND_IDX(-40)] = 0x0425,
|
||||
[BEND_IDX(-45)] = 0x0425,
|
||||
[BEND_IDX(-50)] = 0x0525,
|
||||
};
|
||||
|
||||
/*
|
||||
* Bend CLKOUT_DP
|
||||
* steps -50 to 50 inclusive, in steps of 5
|
||||
* < 0 slow down the clock, > 0 speed up the clock, 0 == no bend (135MHz)
|
||||
* change in clock period = -(steps / 10) * 5.787 ps
|
||||
*/
|
||||
static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int idx = BEND_IDX(steps);
|
||||
|
||||
if (WARN_ON(steps % 5 != 0))
|
||||
return;
|
||||
|
||||
if (WARN_ON(idx >= ARRAY_SIZE(sscdivintphase)))
|
||||
return;
|
||||
|
||||
mutex_lock(&dev_priv->sb_lock);
|
||||
|
||||
if (steps % 10 != 0)
|
||||
tmp = 0xAAAAAAAB;
|
||||
else
|
||||
tmp = 0x00000000;
|
||||
intel_sbi_write(dev_priv, SBI_SSCDITHPHASE, tmp, SBI_ICLK);
|
||||
|
||||
tmp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE, SBI_ICLK);
|
||||
tmp &= 0xffff0000;
|
||||
tmp |= sscdivintphase[idx];
|
||||
intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE, tmp, SBI_ICLK);
|
||||
|
||||
mutex_unlock(&dev_priv->sb_lock);
|
||||
}
|
||||
|
||||
#undef BEND_IDX
|
||||
|
||||
static void lpt_init_pch_refclk(struct drm_device *dev)
|
||||
{
|
||||
struct intel_encoder *encoder;
|
||||
@ -8577,10 +8638,12 @@ static void lpt_init_pch_refclk(struct drm_device *dev)
|
||||
}
|
||||
}
|
||||
|
||||
if (has_vga)
|
||||
if (has_vga) {
|
||||
lpt_bend_clkout_dp(to_i915(dev), 0);
|
||||
lpt_enable_clkout_dp(dev, true, true);
|
||||
else
|
||||
} else {
|
||||
lpt_disable_clkout_dp(dev);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user