Skip to content

Commit f7be2c2

Browse files
committed
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 <[email protected]> Signed-off-by: Ville Syrjälä <[email protected]> Link: http://patchwork.freedesktop.org/patch/msgid/[email protected] Reviewed-by: Paulo Zanoni <[email protected]>
1 parent e7674b8 commit f7be2c2

File tree

2 files changed

+67
-2
lines changed

2 files changed

+67
-2
lines changed

drivers/gpu/drm/i915/i915_reg.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7327,13 +7327,15 @@ enum skl_disp_power_wells {
73277327
#define SBI_READY (0x0<<0)
73287328

73297329
/* SBI offsets */
7330+
#define SBI_SSCDIVINTPHASE 0x0200
73307331
#define SBI_SSCDIVINTPHASE6 0x0600
73317332
#define SBI_SSCDIVINTPHASE_DIVSEL_MASK ((0x7f)<<1)
73327333
#define SBI_SSCDIVINTPHASE_DIVSEL(x) ((x)<<1)
73337334
#define SBI_SSCDIVINTPHASE_INCVAL_MASK ((0x7f)<<8)
73347335
#define SBI_SSCDIVINTPHASE_INCVAL(x) ((x)<<8)
73357336
#define SBI_SSCDIVINTPHASE_DIR(x) ((x)<<15)
73367337
#define SBI_SSCDIVINTPHASE_PROPAGATE (1<<0)
7338+
#define SBI_SSCDITHPHASE 0x0204
73377339
#define SBI_SSCCTL 0x020c
73387340
#define SBI_SSCCTL6 0x060C
73397341
#define SBI_SSCCTL_PATHALT (1<<3)

drivers/gpu/drm/i915/intel_display.c

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8562,6 +8562,67 @@ static void lpt_disable_clkout_dp(struct drm_device *dev)
85628562
mutex_unlock(&dev_priv->sb_lock);
85638563
}
85648564

8565+
#define BEND_IDX(steps) ((50 + (steps)) / 5)
8566+
8567+
static const uint16_t sscdivintphase[] = {
8568+
[BEND_IDX( 50)] = 0x3B23,
8569+
[BEND_IDX( 45)] = 0x3B23,
8570+
[BEND_IDX( 40)] = 0x3C23,
8571+
[BEND_IDX( 35)] = 0x3C23,
8572+
[BEND_IDX( 30)] = 0x3D23,
8573+
[BEND_IDX( 25)] = 0x3D23,
8574+
[BEND_IDX( 20)] = 0x3E23,
8575+
[BEND_IDX( 15)] = 0x3E23,
8576+
[BEND_IDX( 10)] = 0x3F23,
8577+
[BEND_IDX( 5)] = 0x3F23,
8578+
[BEND_IDX( 0)] = 0x0025,
8579+
[BEND_IDX( -5)] = 0x0025,
8580+
[BEND_IDX(-10)] = 0x0125,
8581+
[BEND_IDX(-15)] = 0x0125,
8582+
[BEND_IDX(-20)] = 0x0225,
8583+
[BEND_IDX(-25)] = 0x0225,
8584+
[BEND_IDX(-30)] = 0x0325,
8585+
[BEND_IDX(-35)] = 0x0325,
8586+
[BEND_IDX(-40)] = 0x0425,
8587+
[BEND_IDX(-45)] = 0x0425,
8588+
[BEND_IDX(-50)] = 0x0525,
8589+
};
8590+
8591+
/*
8592+
* Bend CLKOUT_DP
8593+
* steps -50 to 50 inclusive, in steps of 5
8594+
* < 0 slow down the clock, > 0 speed up the clock, 0 == no bend (135MHz)
8595+
* change in clock period = -(steps / 10) * 5.787 ps
8596+
*/
8597+
static void lpt_bend_clkout_dp(struct drm_i915_private *dev_priv, int steps)
8598+
{
8599+
uint32_t tmp;
8600+
int idx = BEND_IDX(steps);
8601+
8602+
if (WARN_ON(steps % 5 != 0))
8603+
return;
8604+
8605+
if (WARN_ON(idx >= ARRAY_SIZE(sscdivintphase)))
8606+
return;
8607+
8608+
mutex_lock(&dev_priv->sb_lock);
8609+
8610+
if (steps % 10 != 0)
8611+
tmp = 0xAAAAAAAB;
8612+
else
8613+
tmp = 0x00000000;
8614+
intel_sbi_write(dev_priv, SBI_SSCDITHPHASE, tmp, SBI_ICLK);
8615+
8616+
tmp = intel_sbi_read(dev_priv, SBI_SSCDIVINTPHASE, SBI_ICLK);
8617+
tmp &= 0xffff0000;
8618+
tmp |= sscdivintphase[idx];
8619+
intel_sbi_write(dev_priv, SBI_SSCDIVINTPHASE, tmp, SBI_ICLK);
8620+
8621+
mutex_unlock(&dev_priv->sb_lock);
8622+
}
8623+
8624+
#undef BEND_IDX
8625+
85658626
static void lpt_init_pch_refclk(struct drm_device *dev)
85668627
{
85678628
struct intel_encoder *encoder;
@@ -8577,10 +8638,12 @@ static void lpt_init_pch_refclk(struct drm_device *dev)
85778638
}
85788639
}
85798640

8580-
if (has_vga)
8641+
if (has_vga) {
8642+
lpt_bend_clkout_dp(to_i915(dev), 0);
85818643
lpt_enable_clkout_dp(dev, true, true);
8582-
else
8644+
} else {
85838645
lpt_disable_clkout_dp(dev);
8646+
}
85848647
}
85858648

85868649
/*

0 commit comments

Comments
 (0)