Message ID | 1364489747-2050-3-git-send-email-jbarnes@virtuousgeek.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Mar 28, 2013 at 09:55:39AM -0700, Jesse Barnes wrote: > In Valleyview voltage swing, pre-emphasis and lane control registers can > be programmed only through the h/w side band fabric. Update > vlv_update_pll, i9xx_crtc_enable, and intel_enable_pll with the > appropriate programming. > > We need to make sure that the tx lane reset occurs in both the full mode > set and DPMS paths, so factor things out to allow that. > > v2: use different DPIO_DIVISOR values for VGA and DisplayPort > v3: Fix update pll logic to use same DPIO_DIVISOR & DPIO_REFSFR values > for all display interfaces > v4: collapse with various updates > v5: squash with crtc enable/pll enable bits > v6: split out DP code (jbarnes) > put phyready check under IS_VALLEYVIEW (jbarnes) > remove unneeded check in 9xx pll div update (Jani) > wrap VLV pll update call in IS_VALLEYVIEW (Jani) > move port enable back to end of crtc enable (jbarnes) > put phyready check under IS_VALLEYVIEW (jbarnes) > v7: fix up conflicts against latest drm-intel-next-queued > v8: use DPIO reg names, fix pipes (Jani) > from mPhy_registers_VLV2_ww20p5 doc > > Signed-off-by: Pallavi G <pallavi.g@intel.com> > Signed-off-by: Vijay Purushothaman <vijay.a.purushothaman@intel.com> > Signed-off-by: Gajanan Bhat <gajanan.bhat@intel.com> > Signed-off-by: Ben Widawsky <benjamin.widawsky@intel.com> Imo this is still a bit too horrible to live. Iirc I've had a massive bikeshed review, but then noticed that I don't understand at all what this code does and so dropped it. A few random things I've remembered: - There's lots of magic pipe checks, imo if (pipe == PIPE_B) reads better than if (pipe). Especially since we also have now platforms with more than just 2 pipes. Also s/1/PIPE_B/ at some places. - This patch does too much, e.g. vlv_init_dpio seems to now be used as a generic reset function in crtc_disable, but is still called _init. Also looks like an orthogonal patch to me. - Some of the #defines are seriously misguided as to whether they're dealing with a pipe or a port. Last time I've check some #defines weren't used, but I didn't bother this time around with checking them all again. - Some of the intel_has_type checks look fishy and would look better when replaced with a port enum or something like that. Others look like they hardcode pll selections in strange ways (I have no clue with all that magic). - intel_mode_get_pixel_multiplier is gone, so this doesn't apply on latest dinq. - Some function extraction looks easily doable, e.g. extracting the "port ready" wait in mode_set and crtc_enable - I still suspect that some of these checks/hacks predate the modeset rework since stuff is seemingly duplicated at a bunch of places ... I think some gentle patch splitting, slight refactoring and liberal sprinklig of FIXME comments should get this one here into shape. Especially if we know that a given piece of code here is just pre-silicon hacks or hard-wired to the sdv board layout. Cheers, Daniel > --- > drivers/gpu/drm/i915/i915_reg.h | 107 ++++++++++++- > drivers/gpu/drm/i915/intel_display.c | 274 ++++++++++++++++++++++++++-------- > 2 files changed, 320 insertions(+), 61 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index d0f7cb9..858a712 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -362,6 +362,11 @@ > #define DPIO_SFR_BYPASS (1<<1) > #define DPIO_RESET (1<<0) > > +#define _DPIO_TX3_SWING_CTL4_A 0x690 > +#define _DPIO_TX3_SWING_CTL4_B 0x2a90 > +#define DPIO_TX3_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL4_A, \ > + _DPIO_TX3_SWING_CTL4_B) > + > #define _DPIO_DIV_A 0x800c > #define DPIO_POST_DIV_SHIFT (28) /* 3 bits */ > #define DPIO_K_SHIFT (24) /* 4 bits */ > @@ -389,14 +394,109 @@ > #define _DPIO_CORE_CLK_B 0x803c > #define DPIO_CORE_CLK(pipe) _PIPE(pipe, _DPIO_CORE_CLK_A, _DPIO_CORE_CLK_B) > > +#define _DPIO_IREF_CTL_A 0x8040 > +#define _DPIO_IREF_CTL_B 0x8060 > +#define DPIO_IREF_CTL(pipe) _PIPE(pipe, _DPIO_IREF_CTL_A, _DPIO_IREF_CTL_B) > + > +#define DPIO_IREF_BCAST 0xc044 > +#define _DPIO_IREF_A 0x8044 > +#define _DPIO_IREF_B 0x8064 > +#define DPIO_IREF(pipe) _PIPE(pipe, _DPIO_IREF_A, _DPIO_IREF_B) > + > +#define _DPIO_PLL_CML_A 0x804c > +#define _DPIO_PLL_CML_B 0x806c > +#define DPIO_PLL_CML(pipe) _PIPE(pipe, _DPIO_PLL_CML_A, _DPIO_PLL_CML_B) > + > #define _DPIO_LFP_COEFF_A 0x8048 > #define _DPIO_LFP_COEFF_B 0x8068 > #define DPIO_LFP_COEFF(pipe) _PIPE(pipe, _DPIO_LFP_COEFF_A, _DPIO_LFP_COEFF_B) > > +#define DPIO_CALIBRATION 0x80ac > + > #define DPIO_FASTCLK_DISABLE 0x8100 > > -#define DPIO_DATA_CHANNEL1 0x8220 > -#define DPIO_DATA_CHANNEL2 0x8420 > +#define _DPIO_PCS_TX_0 0x8200 > +#define _DPIO_PCS_TX_1 0x8400 > +#define DPIO_PCS_TX_LANE2_RESET (1<<16) > +#define DPIO_PCS_TX_LANE1_RESET (1<<7) > +#define DPIO_PCS_TX(pipe) _PIPE(pipe, _DPIO_PCS_TX_0, _DPIO_PCS_TX_1) > + > +#define _DPIO_PCS_CLK_0 0x8204 > +#define _DPIO_PCS_CLK_1 0x8404 > +#define DPIO_PCS_CLK_CRI_RXEB_EIOS_EN (1<<22) > +#define DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN (1<<21) > +#define DPIO_PCS_CLK_DATAWIDTH_SHIFT (6) > +#define DPIO_PCS_CLK_SOFT_RESET (1<<5) > +#define DPIO_PCS_CLK(pipe) _PIPE(pipe, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1) > + > +#define _DPIO_PCS_CTL_OVR1_A 0x8224 > +#define _DPIO_PCS_CTL_OVR1_B 0x8424 > +#define DPIO_PCS_CTL_OVER1(pipe) _PIPE(pipe, _DPIO_PCS_CTL_OVR1_A, \ > + _DPIO_PCS_CTL_OVR1_B) > + > +#define _DPIO_PCS_STAGGER0_A 0x822c > +#define _DPIO_PCS_STAGGER0_B 0x842c > +#define DPIO_PCS_STAGGER0(pipe) _PIPE(pipe, _DPIO_PCS_STAGGER0_A, \ > + _DPIO_PCS_STAGGER0_B) > + > +#define _DPIO_PCS_STAGGER1_A 0x8230 > +#define _DPIO_PCS_STAGGER1_B 0x8430 > +#define DPIO_PCS_STAGGER1(pipe) _PIPE(pipe, _DPIO_PCS_STAGGER1_A, \ > + _DPIO_PCS_STAGGER1_B) > + > +#define _DPIO_PCS_CLOCKBUF0_A 0x8238 > +#define _DPIO_PCS_CLOCKBUF0_B 0x8438 > +#define DPIO_PCS_CLOCKBUF0(pipe) _PIPE(pipe, _DPIO_PCS_CLOCKBUF0_A, \ > + _DPIO_PCS_CLOCKBUF0_B) > + > +#define _DPIO_PCS_CLOCKBUF8_A 0x825c > +#define _DPIO_PCS_CLOCKBUF8_B 0x845c > +#define DPIO_PCS_CLOCKBUF8(pipe) _PIPE(pipe, _DPIO_PCS_CLOCKBUF8_A, \ > + _DPIO_PCS_CLOCKBUF8_B) > + > +#define _DPIO_TX_SWING_CTL2_A 0x8288 > +#define _DPIO_TX_SWING_CTL2_B 0x8488 > +#define DPIO_TX_SWING_CTL2(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL2_A, \ > + _DPIO_TX_SWING_CTL2_B) > + > +#define _DPIO_TX_SWING_CTL3_A 0x828c > +#define _DPIO_TX_SWING_CTL3_B 0x848c > +#define DPIO_TX_SWING_CTL3(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL3_A, \ > + _DPIO_TX_SWING_CTL3_B) > + > +#define _DPIO_TX_SWING_CTL4_A 0x8290 > +#define _DPIO_TX_SWING_CTL4_B 0x8490 > +#define DPIO_TX_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL4_A, \ > + _DPIO_TX_SWING_CTL4_B) > + > +#define _DPIO_TX_OCALINIT_0 0x8294 > +#define _DPIO_TX_OCALINIT_1 0x8494 > +#define DPIO_TX_OCALINIT_EN (1<<31) > +#define DPIO_TX_OCALINIT(pipe) _PIPE(pipe, _DPIO_TX_OCALINIT_0, \ > + _DPIO_TX_OCALINIT_1) > + > +#define _DPIO_TX_CTL_0 0x82ac > +#define _DPIO_TX_CTL_1 0x84ac > +#define DPIO_TX_CTL(pipe) _PIPE(pipe, _DPIO_TX_CTL_0, _DPIO_TX_CTL_1) > + > +#define _DPIO_TX_LANE_0 0x82b8 > +#define _DPIO_TX_LANE_1 0x84b8 > +#define DPIO_TX_LANE(pipe) _PIPE(pipe, _DPIO_TX_LANE_0, _DPIO_TX_LANE_1) > + > +#define _DPIO_DATA_CHANNEL1 0x8220 > +#define _DPIO_DATA_CHANNEL2 0x8420 > +#define DPIO_DATA_CHANNEL(pipe) _PIPE(pipe, _DPIO_DATA_CHANNEL1, _DPIO_DATA_CHANNEL2) > + > +#define _DPIO_DATA_LANE0 0x0220 > +#define _DPIO_DATA_LANE1 0x0420 > +#define _DPIO_DATA_LANE2 0x2620 > +#define _DPIO_DATA_LANE3 0x2820 > +#define DPIO_DATA_LANE_A(pipe) _PIPE(pipe, _DPIO_DATA_LANE0, _DPIO_DATA_LANE2) > +#define DPIO_DATA_LANE_B(pipe) _PIPE(pipe, _DPIO_DATA_LANE1, _DPIO_DATA_LANE3) > +#define DPIO_DATA_CHANNEL1 0x8220 > +#define DPIO_DATA_CHANNEL2 0x8420 > + > +#define DPIO_TX_BROADCAST 0xc044 > > /* > * Fence registers > @@ -957,7 +1057,10 @@ > #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ > #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ > #define DPLL_LOCK_VLV (1<<15) > +#define DPLL_INTEGRATED_CRI_CLK_VLV (1<<14) > #define DPLL_INTEGRATED_CLOCK_VLV (1<<13) > +#define DPLL_PORTC_READY_MASK (0xf << 4) > +#define DPLL_PORTB_READY_MASK (0xf) > > #define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 > /* > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 58e3a7c..9cb0b53 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3696,6 +3696,72 @@ g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe) > } > } > > +static void vlv_pll_enable_reset(struct drm_crtc *crtc) > +{ > + struct drm_device *dev = crtc->dev; > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); > + int pipe = intel_crtc->pipe; > + > + WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); > + > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { > + u32 val; > + val = intel_dpio_read(dev_priv, _DPIO_DATA_LANE0); > + if (pipe) > + val |= (1<<21); > + val |= (1<<20); > + intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL1, val); > + > + intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(pipe), > + 0x00760018); > + intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(pipe), > + 0x00400888); > + > + intel_dpio_write(dev_priv, DPIO_PCS_TX(pipe), > + DPIO_PCS_TX_LANE2_RESET | > + DPIO_PCS_TX_LANE1_RESET); > + intel_dpio_write(dev_priv, DPIO_PCS_CLK(pipe), > + DPIO_PCS_CLK_CRI_RXEB_EIOS_EN | > + DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN | > + (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) | > + DPIO_PCS_CLK_SOFT_RESET); > + > + intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(pipe), 0); > + intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(pipe), > + 0x2b245f5f); > + intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(pipe), > + 0x5578b83a); > + intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(pipe), > + 0x0c782040); > + intel_dpio_write(dev_priv, DPIO_TX3_SWING_CTL4(pipe), > + 0x2b247878); > + intel_dpio_write(dev_priv, DPIO_PCS_STAGGER0(pipe), 0x00030000); > + intel_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(pipe), > + 0x00002000); > + intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(pipe), > + DPIO_TX_OCALINIT_EN); > + > + } > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || > + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { > + u32 val; > + val = intel_dpio_read(dev_priv, _DPIO_DATA_LANE2); > + if (pipe) > + val |= (1<<21); > + val |= (1<<20); > + intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL2, val); > + > + intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(pipe), > + 0x00760018); > + intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(pipe), > + 0x00400888); > + > + intel_dpio_write(dev_priv, DPIO_PCS_TX(pipe), 0x10080); > + intel_dpio_write(dev_priv, DPIO_PCS_CLK(pipe), 0x00600060); > + } > +} > + > static void i9xx_crtc_enable(struct drm_crtc *crtc) > { > struct drm_device *dev = crtc->dev; > @@ -3704,6 +3770,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) > struct intel_encoder *encoder; > int pipe = intel_crtc->pipe; > int plane = intel_crtc->plane; > + u32 port_mask; > > WARN_ON(!crtc->enabled); > > @@ -3715,10 +3782,27 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) > > intel_enable_pll(dev_priv, pipe); > > + if (IS_VALLEYVIEW(dev)) { > + mutex_lock(&dev_priv->dpio_lock); > + vlv_pll_enable_reset(crtc); > + mutex_unlock(&dev_priv->dpio_lock); > + } > + > for_each_encoder_on_crtc(dev, crtc, encoder) > if (encoder->pre_enable) > encoder->pre_enable(encoder); > > + if (IS_VALLEYVIEW(dev)) { > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || > + intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) > + port_mask = DPLL_PORTB_READY_MASK; > + else > + port_mask = DPLL_PORTC_READY_MASK; /* eDP on port C */ > + > + if (wait_for((I915_READ(DPLL(0)) & port_mask) == 0, 100)) > + DRM_ERROR("timed out waiting for port ready\n"); > + } > + > intel_enable_pipe(dev_priv, pipe, false); > intel_enable_plane(dev_priv, plane, pipe); > if (IS_G4X(dev)) > @@ -3770,6 +3854,21 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) > ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe) > I915_WRITE(PFIT_CONTROL, 0); > > + for_each_encoder_on_crtc(dev, crtc, encoder) > + if (encoder->post_disable) > + encoder->post_disable(encoder); > + > + /* Reset lane for VLV platform*/ > + if (IS_VALLEYVIEW(dev)) { > + mutex_lock(&dev_priv->dpio_lock); > + intel_dpio_write(dev_priv, DPIO_PCS_TX(pipe), 0x00000000); > + intel_dpio_write(dev_priv, DPIO_PCS_CLK(pipe), 0x00e00060); > + > + if (pipe) > + vlv_init_dpio(dev); > + mutex_unlock(&dev_priv->dpio_lock); > + } > + > intel_disable_pll(dev_priv, pipe); > > intel_crtc->active = false; > @@ -4338,6 +4437,31 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc, > } > } > > +static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv) > +{ > + u32 reg_val; > + > + /* > + * PLLB opamp always calibrates to max value of 0x3f, force enable it > + * and set it to a reasonable value instead. > + */ > + reg_val = intel_dpio_read(dev_priv, DPIO_IREF(1)); > + reg_val &= 0xffffff30; > + intel_dpio_write(dev_priv, DPIO_IREF(1), reg_val); > + > + reg_val = intel_dpio_read(dev_priv, DPIO_CALIBRATION); > + reg_val &= 0x8cffffff; > + intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, DPIO_IREF(1)); > + reg_val &= 0xffffff00; > + intel_dpio_write(dev_priv, DPIO_IREF(1), reg_val); > + > + reg_val = intel_dpio_read(dev_priv, DPIO_CALIBRATION); > + reg_val &= 0xb0ffffff; > + intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); > +} > + > static void vlv_update_pll(struct drm_crtc *crtc, > struct drm_display_mode *mode, > struct drm_display_mode *adjusted_mode, > @@ -4348,23 +4472,14 @@ static void vlv_update_pll(struct drm_crtc *crtc, > struct drm_i915_private *dev_priv = dev->dev_private; > struct intel_crtc *intel_crtc = to_intel_crtc(crtc); > int pipe = intel_crtc->pipe; > - u32 dpll, mdiv, pdiv; > + u32 dpll, mdiv; > u32 bestn, bestm1, bestm2, bestp1, bestp2; > - bool is_sdvo; > - u32 temp; > + bool is_hdmi; > + u32 coreclk, reg_val; > > mutex_lock(&dev_priv->dpio_lock); > > - is_sdvo = intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) || > - intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); > - > - dpll = DPLL_VGA_MODE_DIS; > - dpll |= DPLL_EXT_BUFFER_ENABLE_VLV; > - dpll |= DPLL_REFA_CLK_ENABLE_VLV; > - dpll |= DPLL_INTEGRATED_CLOCK_VLV; > - > - I915_WRITE(DPLL(pipe), dpll); > - POSTING_READ(DPLL(pipe)); > + is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); > > bestn = clock->n; > bestm1 = clock->m1; > @@ -4372,71 +4487,99 @@ static void vlv_update_pll(struct drm_crtc *crtc, > bestp1 = clock->p1; > bestp2 = clock->p2; > > - /* > - * In Valleyview PLL and program lane counter registers are exposed > - * through DPIO interface > - */ > + /* See eDP HDMI DPIO driver vbios notes doc */ > + > + /* PLL B needs special handling */ > + if (pipe) > + vlv_pllb_recal_opamp(dev_priv); > + > + /* Set up Tx target for periodic Rcomp update */ > + intel_dpio_write(dev_priv, DPIO_IREF_BCAST, 0x0100000f); > + > + /* Disable target IRef on PLL */ > + reg_val = intel_dpio_read(dev_priv, DPIO_IREF_CTL(pipe)); > + reg_val &= 0x00ffffff; > + intel_dpio_write(dev_priv, DPIO_IREF_CTL(pipe), reg_val); > + > + intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x610); > + > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || > + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { > + if (adjusted_mode->clock == 162000) > + intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), > + 0x009f0003); > + else > + intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), > + 0x00d0000f); > + > + } else > + intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), > + 0x009f0003); > + > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || > + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { > + if (!pipe) > + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), > + 0x0df40000); > + else > + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), > + 0x0df70000); > + } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { > + if (!pipe) > + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), > + 0x0df70000); > + else > + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), > + 0x0df40000); > + } > + > mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK)); > mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT)); > mdiv |= ((bestn << DPIO_N_SHIFT)); > mdiv |= (1 << DPIO_POST_DIV_SHIFT); > mdiv |= (1 << DPIO_K_SHIFT); > + intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); > + > mdiv |= DPIO_ENABLE_CALIBRATION; > intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); > > - intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000); > + coreclk = intel_dpio_read(dev_priv, DPIO_CORE_CLK(pipe)); > + coreclk = (coreclk & 0x0000ff00) | 0x01c00000; > + intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), coreclk); > > - pdiv = (1 << DPIO_REFSEL_OVERRIDE) | (5 << DPIO_PLL_MODESEL_SHIFT) | > - (3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) | > - (7 << DPIO_PLL_REFCLK_SEL_SHIFT) | (8 << DPIO_DRIVER_CTL_SHIFT) | > - (5 << DPIO_CLK_BIAS_CTL_SHIFT); > - intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv); > + intel_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000); > > - intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x005f003b); > + /* Enable DPIO clock input */ > + dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV | > + DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV; > + if (pipe) > + dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; > > dpll |= DPLL_VCO_ENABLE; > I915_WRITE(DPLL(pipe), dpll); > POSTING_READ(DPLL(pipe)); > + udelay(150); > + > if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) > DRM_ERROR("DPLL %d failed to lock\n", pipe); > > - intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x620); > - > - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) > - intel_dp_set_m_n(crtc, mode, adjusted_mode); > - > - I915_WRITE(DPLL(pipe), dpll); > - > - /* Wait for the clocks to stabilize. */ > - POSTING_READ(DPLL(pipe)); > - udelay(150); > + if (is_hdmi) { > + u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); > > - temp = 0; > - if (is_sdvo) { > - temp = intel_mode_get_pixel_multiplier(adjusted_mode); > if (temp > 1) > temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; > else > temp = 0; > - } > - I915_WRITE(DPLL_MD(pipe), temp); > - POSTING_READ(DPLL_MD(pipe)); > > - /* Now program lane control registers */ > - if(intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) > - || intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) > - { > - temp = 0x1000C4; > - if(pipe == 1) > - temp |= (1 << 21); > - intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL1, temp); > + I915_WRITE(DPLL_MD(pipe), temp); > + POSTING_READ(DPLL_MD(pipe)); > } > - if(intel_pipe_has_type(crtc,INTEL_OUTPUT_EDP)) > - { > - temp = 0x1000C4; > - if(pipe == 1) > - temp |= (1 << 21); > - intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL2, temp); > + > + vlv_pll_enable_reset(crtc); > + > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || > + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { > + intel_dp_set_m_n(crtc, mode, adjusted_mode); > } > > mutex_unlock(&dev_priv->dpio_lock); > @@ -4748,11 +4891,12 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, > i8xx_update_pll(crtc, adjusted_mode, &clock, > has_reduced_clock ? &reduced_clock : NULL, > num_connectors); > - else if (IS_VALLEYVIEW(dev)) > + else if (IS_VALLEYVIEW(dev)) { > + refclk = i9xx_get_refclk(crtc, num_connectors); > vlv_update_pll(crtc, mode, adjusted_mode, &clock, > has_reduced_clock ? &reduced_clock : NULL, > num_connectors); > - else > + } else > i9xx_update_pll(crtc, mode, adjusted_mode, &clock, > has_reduced_clock ? &reduced_clock : NULL, > num_connectors); > @@ -4845,6 +4989,21 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, > > intel_update_watermarks(dev); > > + if (IS_VALLEYVIEW(dev)) { > + u32 port_mask; > + > + /* Wait for Phy status bits to go low */ > + for_each_encoder_on_crtc(dev, crtc, encoder) { > + if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || > + encoder->type == INTEL_OUTPUT_HDMI) > + port_mask = DPLL_PORTB_READY_MASK; > + else > + port_mask = DPLL_PORTC_READY_MASK; /* eDP */ > + if (wait_for((I915_READ(DPLL(0)) & port_mask) == 0, 100)) > + DRM_ERROR("timed out waiting for port ready\n"); > + } > + } > + > return ret; > } > > @@ -9284,9 +9443,6 @@ void intel_modeset_cleanup(struct drm_device *dev) > > ironlake_teardown_rc6(dev); > > - if (IS_VALLEYVIEW(dev)) > - vlv_init_dpio(dev); > - > mutex_unlock(&dev->struct_mutex); > > /* Disable the irq before mode object teardown, for the irq might > -- > 1.7.10.4 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d0f7cb9..858a712 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -362,6 +362,11 @@ #define DPIO_SFR_BYPASS (1<<1) #define DPIO_RESET (1<<0) +#define _DPIO_TX3_SWING_CTL4_A 0x690 +#define _DPIO_TX3_SWING_CTL4_B 0x2a90 +#define DPIO_TX3_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL4_A, \ + _DPIO_TX3_SWING_CTL4_B) + #define _DPIO_DIV_A 0x800c #define DPIO_POST_DIV_SHIFT (28) /* 3 bits */ #define DPIO_K_SHIFT (24) /* 4 bits */ @@ -389,14 +394,109 @@ #define _DPIO_CORE_CLK_B 0x803c #define DPIO_CORE_CLK(pipe) _PIPE(pipe, _DPIO_CORE_CLK_A, _DPIO_CORE_CLK_B) +#define _DPIO_IREF_CTL_A 0x8040 +#define _DPIO_IREF_CTL_B 0x8060 +#define DPIO_IREF_CTL(pipe) _PIPE(pipe, _DPIO_IREF_CTL_A, _DPIO_IREF_CTL_B) + +#define DPIO_IREF_BCAST 0xc044 +#define _DPIO_IREF_A 0x8044 +#define _DPIO_IREF_B 0x8064 +#define DPIO_IREF(pipe) _PIPE(pipe, _DPIO_IREF_A, _DPIO_IREF_B) + +#define _DPIO_PLL_CML_A 0x804c +#define _DPIO_PLL_CML_B 0x806c +#define DPIO_PLL_CML(pipe) _PIPE(pipe, _DPIO_PLL_CML_A, _DPIO_PLL_CML_B) + #define _DPIO_LFP_COEFF_A 0x8048 #define _DPIO_LFP_COEFF_B 0x8068 #define DPIO_LFP_COEFF(pipe) _PIPE(pipe, _DPIO_LFP_COEFF_A, _DPIO_LFP_COEFF_B) +#define DPIO_CALIBRATION 0x80ac + #define DPIO_FASTCLK_DISABLE 0x8100 -#define DPIO_DATA_CHANNEL1 0x8220 -#define DPIO_DATA_CHANNEL2 0x8420 +#define _DPIO_PCS_TX_0 0x8200 +#define _DPIO_PCS_TX_1 0x8400 +#define DPIO_PCS_TX_LANE2_RESET (1<<16) +#define DPIO_PCS_TX_LANE1_RESET (1<<7) +#define DPIO_PCS_TX(pipe) _PIPE(pipe, _DPIO_PCS_TX_0, _DPIO_PCS_TX_1) + +#define _DPIO_PCS_CLK_0 0x8204 +#define _DPIO_PCS_CLK_1 0x8404 +#define DPIO_PCS_CLK_CRI_RXEB_EIOS_EN (1<<22) +#define DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN (1<<21) +#define DPIO_PCS_CLK_DATAWIDTH_SHIFT (6) +#define DPIO_PCS_CLK_SOFT_RESET (1<<5) +#define DPIO_PCS_CLK(pipe) _PIPE(pipe, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1) + +#define _DPIO_PCS_CTL_OVR1_A 0x8224 +#define _DPIO_PCS_CTL_OVR1_B 0x8424 +#define DPIO_PCS_CTL_OVER1(pipe) _PIPE(pipe, _DPIO_PCS_CTL_OVR1_A, \ + _DPIO_PCS_CTL_OVR1_B) + +#define _DPIO_PCS_STAGGER0_A 0x822c +#define _DPIO_PCS_STAGGER0_B 0x842c +#define DPIO_PCS_STAGGER0(pipe) _PIPE(pipe, _DPIO_PCS_STAGGER0_A, \ + _DPIO_PCS_STAGGER0_B) + +#define _DPIO_PCS_STAGGER1_A 0x8230 +#define _DPIO_PCS_STAGGER1_B 0x8430 +#define DPIO_PCS_STAGGER1(pipe) _PIPE(pipe, _DPIO_PCS_STAGGER1_A, \ + _DPIO_PCS_STAGGER1_B) + +#define _DPIO_PCS_CLOCKBUF0_A 0x8238 +#define _DPIO_PCS_CLOCKBUF0_B 0x8438 +#define DPIO_PCS_CLOCKBUF0(pipe) _PIPE(pipe, _DPIO_PCS_CLOCKBUF0_A, \ + _DPIO_PCS_CLOCKBUF0_B) + +#define _DPIO_PCS_CLOCKBUF8_A 0x825c +#define _DPIO_PCS_CLOCKBUF8_B 0x845c +#define DPIO_PCS_CLOCKBUF8(pipe) _PIPE(pipe, _DPIO_PCS_CLOCKBUF8_A, \ + _DPIO_PCS_CLOCKBUF8_B) + +#define _DPIO_TX_SWING_CTL2_A 0x8288 +#define _DPIO_TX_SWING_CTL2_B 0x8488 +#define DPIO_TX_SWING_CTL2(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL2_A, \ + _DPIO_TX_SWING_CTL2_B) + +#define _DPIO_TX_SWING_CTL3_A 0x828c +#define _DPIO_TX_SWING_CTL3_B 0x848c +#define DPIO_TX_SWING_CTL3(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL3_A, \ + _DPIO_TX_SWING_CTL3_B) + +#define _DPIO_TX_SWING_CTL4_A 0x8290 +#define _DPIO_TX_SWING_CTL4_B 0x8490 +#define DPIO_TX_SWING_CTL4(pipe) _PIPE(pipe, _DPIO_TX_SWING_CTL4_A, \ + _DPIO_TX_SWING_CTL4_B) + +#define _DPIO_TX_OCALINIT_0 0x8294 +#define _DPIO_TX_OCALINIT_1 0x8494 +#define DPIO_TX_OCALINIT_EN (1<<31) +#define DPIO_TX_OCALINIT(pipe) _PIPE(pipe, _DPIO_TX_OCALINIT_0, \ + _DPIO_TX_OCALINIT_1) + +#define _DPIO_TX_CTL_0 0x82ac +#define _DPIO_TX_CTL_1 0x84ac +#define DPIO_TX_CTL(pipe) _PIPE(pipe, _DPIO_TX_CTL_0, _DPIO_TX_CTL_1) + +#define _DPIO_TX_LANE_0 0x82b8 +#define _DPIO_TX_LANE_1 0x84b8 +#define DPIO_TX_LANE(pipe) _PIPE(pipe, _DPIO_TX_LANE_0, _DPIO_TX_LANE_1) + +#define _DPIO_DATA_CHANNEL1 0x8220 +#define _DPIO_DATA_CHANNEL2 0x8420 +#define DPIO_DATA_CHANNEL(pipe) _PIPE(pipe, _DPIO_DATA_CHANNEL1, _DPIO_DATA_CHANNEL2) + +#define _DPIO_DATA_LANE0 0x0220 +#define _DPIO_DATA_LANE1 0x0420 +#define _DPIO_DATA_LANE2 0x2620 +#define _DPIO_DATA_LANE3 0x2820 +#define DPIO_DATA_LANE_A(pipe) _PIPE(pipe, _DPIO_DATA_LANE0, _DPIO_DATA_LANE2) +#define DPIO_DATA_LANE_B(pipe) _PIPE(pipe, _DPIO_DATA_LANE1, _DPIO_DATA_LANE3) +#define DPIO_DATA_CHANNEL1 0x8220 +#define DPIO_DATA_CHANNEL2 0x8420 + +#define DPIO_TX_BROADCAST 0xc044 /* * Fence registers @@ -957,7 +1057,10 @@ #define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */ #define DPLL_FPA01_P1_POST_DIV_MASK_PINEVIEW 0x00ff8000 /* Pineview */ #define DPLL_LOCK_VLV (1<<15) +#define DPLL_INTEGRATED_CRI_CLK_VLV (1<<14) #define DPLL_INTEGRATED_CLOCK_VLV (1<<13) +#define DPLL_PORTC_READY_MASK (0xf << 4) +#define DPLL_PORTB_READY_MASK (0xf) #define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000 /* diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 58e3a7c..9cb0b53 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3696,6 +3696,72 @@ g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe) } } +static void vlv_pll_enable_reset(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + + WARN_ON(!mutex_is_locked(&dev_priv->dpio_lock)); + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { + u32 val; + val = intel_dpio_read(dev_priv, _DPIO_DATA_LANE0); + if (pipe) + val |= (1<<21); + val |= (1<<20); + intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL1, val); + + intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(pipe), + 0x00760018); + intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(pipe), + 0x00400888); + + intel_dpio_write(dev_priv, DPIO_PCS_TX(pipe), + DPIO_PCS_TX_LANE2_RESET | + DPIO_PCS_TX_LANE1_RESET); + intel_dpio_write(dev_priv, DPIO_PCS_CLK(pipe), + DPIO_PCS_CLK_CRI_RXEB_EIOS_EN | + DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN | + (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) | + DPIO_PCS_CLK_SOFT_RESET); + + intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(pipe), 0); + intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL4(pipe), + 0x2b245f5f); + intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL2(pipe), + 0x5578b83a); + intel_dpio_write(dev_priv, DPIO_TX_SWING_CTL3(pipe), + 0x0c782040); + intel_dpio_write(dev_priv, DPIO_TX3_SWING_CTL4(pipe), + 0x2b247878); + intel_dpio_write(dev_priv, DPIO_PCS_STAGGER0(pipe), 0x00030000); + intel_dpio_write(dev_priv, DPIO_PCS_CTL_OVER1(pipe), + 0x00002000); + intel_dpio_write(dev_priv, DPIO_TX_OCALINIT(pipe), + DPIO_TX_OCALINIT_EN); + + } + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { + u32 val; + val = intel_dpio_read(dev_priv, _DPIO_DATA_LANE2); + if (pipe) + val |= (1<<21); + val |= (1<<20); + intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL2, val); + + intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF0(pipe), + 0x00760018); + intel_dpio_write(dev_priv, DPIO_PCS_CLOCKBUF8(pipe), + 0x00400888); + + intel_dpio_write(dev_priv, DPIO_PCS_TX(pipe), 0x10080); + intel_dpio_write(dev_priv, DPIO_PCS_CLK(pipe), 0x00600060); + } +} + static void i9xx_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -3704,6 +3770,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) struct intel_encoder *encoder; int pipe = intel_crtc->pipe; int plane = intel_crtc->plane; + u32 port_mask; WARN_ON(!crtc->enabled); @@ -3715,10 +3782,27 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_enable_pll(dev_priv, pipe); + if (IS_VALLEYVIEW(dev)) { + mutex_lock(&dev_priv->dpio_lock); + vlv_pll_enable_reset(crtc); + mutex_unlock(&dev_priv->dpio_lock); + } + for_each_encoder_on_crtc(dev, crtc, encoder) if (encoder->pre_enable) encoder->pre_enable(encoder); + if (IS_VALLEYVIEW(dev)) { + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) + port_mask = DPLL_PORTB_READY_MASK; + else + port_mask = DPLL_PORTC_READY_MASK; /* eDP on port C */ + + if (wait_for((I915_READ(DPLL(0)) & port_mask) == 0, 100)) + DRM_ERROR("timed out waiting for port ready\n"); + } + intel_enable_pipe(dev_priv, pipe, false); intel_enable_plane(dev_priv, plane, pipe); if (IS_G4X(dev)) @@ -3770,6 +3854,21 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) ((pctl & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT) == pipe) I915_WRITE(PFIT_CONTROL, 0); + for_each_encoder_on_crtc(dev, crtc, encoder) + if (encoder->post_disable) + encoder->post_disable(encoder); + + /* Reset lane for VLV platform*/ + if (IS_VALLEYVIEW(dev)) { + mutex_lock(&dev_priv->dpio_lock); + intel_dpio_write(dev_priv, DPIO_PCS_TX(pipe), 0x00000000); + intel_dpio_write(dev_priv, DPIO_PCS_CLK(pipe), 0x00e00060); + + if (pipe) + vlv_init_dpio(dev); + mutex_unlock(&dev_priv->dpio_lock); + } + intel_disable_pll(dev_priv, pipe); intel_crtc->active = false; @@ -4338,6 +4437,31 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc, } } +static void vlv_pllb_recal_opamp(struct drm_i915_private *dev_priv) +{ + u32 reg_val; + + /* + * PLLB opamp always calibrates to max value of 0x3f, force enable it + * and set it to a reasonable value instead. + */ + reg_val = intel_dpio_read(dev_priv, DPIO_IREF(1)); + reg_val &= 0xffffff30; + intel_dpio_write(dev_priv, DPIO_IREF(1), reg_val); + + reg_val = intel_dpio_read(dev_priv, DPIO_CALIBRATION); + reg_val &= 0x8cffffff; + intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); + + reg_val = intel_dpio_read(dev_priv, DPIO_IREF(1)); + reg_val &= 0xffffff00; + intel_dpio_write(dev_priv, DPIO_IREF(1), reg_val); + + reg_val = intel_dpio_read(dev_priv, DPIO_CALIBRATION); + reg_val &= 0xb0ffffff; + intel_dpio_write(dev_priv, DPIO_CALIBRATION, reg_val); +} + static void vlv_update_pll(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -4348,23 +4472,14 @@ static void vlv_update_pll(struct drm_crtc *crtc, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int pipe = intel_crtc->pipe; - u32 dpll, mdiv, pdiv; + u32 dpll, mdiv; u32 bestn, bestm1, bestm2, bestp1, bestp2; - bool is_sdvo; - u32 temp; + bool is_hdmi; + u32 coreclk, reg_val; mutex_lock(&dev_priv->dpio_lock); - is_sdvo = intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) || - intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); - - dpll = DPLL_VGA_MODE_DIS; - dpll |= DPLL_EXT_BUFFER_ENABLE_VLV; - dpll |= DPLL_REFA_CLK_ENABLE_VLV; - dpll |= DPLL_INTEGRATED_CLOCK_VLV; - - I915_WRITE(DPLL(pipe), dpll); - POSTING_READ(DPLL(pipe)); + is_hdmi = intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI); bestn = clock->n; bestm1 = clock->m1; @@ -4372,71 +4487,99 @@ static void vlv_update_pll(struct drm_crtc *crtc, bestp1 = clock->p1; bestp2 = clock->p2; - /* - * In Valleyview PLL and program lane counter registers are exposed - * through DPIO interface - */ + /* See eDP HDMI DPIO driver vbios notes doc */ + + /* PLL B needs special handling */ + if (pipe) + vlv_pllb_recal_opamp(dev_priv); + + /* Set up Tx target for periodic Rcomp update */ + intel_dpio_write(dev_priv, DPIO_IREF_BCAST, 0x0100000f); + + /* Disable target IRef on PLL */ + reg_val = intel_dpio_read(dev_priv, DPIO_IREF_CTL(pipe)); + reg_val &= 0x00ffffff; + intel_dpio_write(dev_priv, DPIO_IREF_CTL(pipe), reg_val); + + intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x610); + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { + if (adjusted_mode->clock == 162000) + intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), + 0x009f0003); + else + intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), + 0x00d0000f); + + } else + intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), + 0x009f0003); + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { + if (!pipe) + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), + 0x0df40000); + else + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), + 0x0df70000); + } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { + if (!pipe) + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), + 0x0df70000); + else + intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), + 0x0df40000); + } + mdiv = ((bestm1 << DPIO_M1DIV_SHIFT) | (bestm2 & DPIO_M2DIV_MASK)); mdiv |= ((bestp1 << DPIO_P1_SHIFT) | (bestp2 << DPIO_P2_SHIFT)); mdiv |= ((bestn << DPIO_N_SHIFT)); mdiv |= (1 << DPIO_POST_DIV_SHIFT); mdiv |= (1 << DPIO_K_SHIFT); + intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); + mdiv |= DPIO_ENABLE_CALIBRATION; intel_dpio_write(dev_priv, DPIO_DIV(pipe), mdiv); - intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), 0x01000000); + coreclk = intel_dpio_read(dev_priv, DPIO_CORE_CLK(pipe)); + coreclk = (coreclk & 0x0000ff00) | 0x01c00000; + intel_dpio_write(dev_priv, DPIO_CORE_CLK(pipe), coreclk); - pdiv = (1 << DPIO_REFSEL_OVERRIDE) | (5 << DPIO_PLL_MODESEL_SHIFT) | - (3 << DPIO_BIAS_CURRENT_CTL_SHIFT) | (1<<20) | - (7 << DPIO_PLL_REFCLK_SEL_SHIFT) | (8 << DPIO_DRIVER_CTL_SHIFT) | - (5 << DPIO_CLK_BIAS_CTL_SHIFT); - intel_dpio_write(dev_priv, DPIO_REFSFR(pipe), pdiv); + intel_dpio_write(dev_priv, DPIO_PLL_CML(pipe), 0x87871000); - intel_dpio_write(dev_priv, DPIO_LFP_COEFF(pipe), 0x005f003b); + /* Enable DPIO clock input */ + dpll = DPLL_EXT_BUFFER_ENABLE_VLV | DPLL_REFA_CLK_ENABLE_VLV | + DPLL_VGA_MODE_DIS | DPLL_INTEGRATED_CLOCK_VLV; + if (pipe) + dpll |= DPLL_INTEGRATED_CRI_CLK_VLV; dpll |= DPLL_VCO_ENABLE; I915_WRITE(DPLL(pipe), dpll); POSTING_READ(DPLL(pipe)); + udelay(150); + if (wait_for(((I915_READ(DPLL(pipe)) & DPLL_LOCK_VLV) == DPLL_LOCK_VLV), 1)) DRM_ERROR("DPLL %d failed to lock\n", pipe); - intel_dpio_write(dev_priv, DPIO_FASTCLK_DISABLE, 0x620); - - if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) - intel_dp_set_m_n(crtc, mode, adjusted_mode); - - I915_WRITE(DPLL(pipe), dpll); - - /* Wait for the clocks to stabilize. */ - POSTING_READ(DPLL(pipe)); - udelay(150); + if (is_hdmi) { + u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); - temp = 0; - if (is_sdvo) { - temp = intel_mode_get_pixel_multiplier(adjusted_mode); if (temp > 1) temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; else temp = 0; - } - I915_WRITE(DPLL_MD(pipe), temp); - POSTING_READ(DPLL_MD(pipe)); - /* Now program lane control registers */ - if(intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) - || intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) - { - temp = 0x1000C4; - if(pipe == 1) - temp |= (1 << 21); - intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL1, temp); + I915_WRITE(DPLL_MD(pipe), temp); + POSTING_READ(DPLL_MD(pipe)); } - if(intel_pipe_has_type(crtc,INTEL_OUTPUT_EDP)) - { - temp = 0x1000C4; - if(pipe == 1) - temp |= (1 << 21); - intel_dpio_write(dev_priv, DPIO_DATA_CHANNEL2, temp); + + vlv_pll_enable_reset(crtc); + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || + intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) { + intel_dp_set_m_n(crtc, mode, adjusted_mode); } mutex_unlock(&dev_priv->dpio_lock); @@ -4748,11 +4891,12 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, i8xx_update_pll(crtc, adjusted_mode, &clock, has_reduced_clock ? &reduced_clock : NULL, num_connectors); - else if (IS_VALLEYVIEW(dev)) + else if (IS_VALLEYVIEW(dev)) { + refclk = i9xx_get_refclk(crtc, num_connectors); vlv_update_pll(crtc, mode, adjusted_mode, &clock, has_reduced_clock ? &reduced_clock : NULL, num_connectors); - else + } else i9xx_update_pll(crtc, mode, adjusted_mode, &clock, has_reduced_clock ? &reduced_clock : NULL, num_connectors); @@ -4845,6 +4989,21 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, intel_update_watermarks(dev); + if (IS_VALLEYVIEW(dev)) { + u32 port_mask; + + /* Wait for Phy status bits to go low */ + for_each_encoder_on_crtc(dev, crtc, encoder) { + if (encoder->type == INTEL_OUTPUT_DISPLAYPORT || + encoder->type == INTEL_OUTPUT_HDMI) + port_mask = DPLL_PORTB_READY_MASK; + else + port_mask = DPLL_PORTC_READY_MASK; /* eDP */ + if (wait_for((I915_READ(DPLL(0)) & port_mask) == 0, 100)) + DRM_ERROR("timed out waiting for port ready\n"); + } + } + return ret; } @@ -9284,9 +9443,6 @@ void intel_modeset_cleanup(struct drm_device *dev) ironlake_teardown_rc6(dev); - if (IS_VALLEYVIEW(dev)) - vlv_init_dpio(dev); - mutex_unlock(&dev->struct_mutex); /* Disable the irq before mode object teardown, for the irq might