Message ID | 1362175722-9281-4-git-send-email-jbarnes@virtuousgeek.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Fri, 1 Mar 2013 14:08:20 -0800 Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > From: Pallavi G <pallavi.g@intel.com> > > 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 Reviewing myself: - port phyready needs to be conditional on vlv (probably extracted into a separate fn) - early port enable should be vlv only (may not be necessary, need to test)
On Fri, 1 Mar 2013 14:08:20 -0800 Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > From: Pallavi G <pallavi.g@intel.com> > > 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 Oh and some DP stuff snuck in here, that should be separated out.
On Fri, Mar 01, 2013 at 02:08:20PM -0800, Jesse Barnes wrote: > From: Pallavi G <pallavi.g@intel.com> > > 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. This comment here looks stale. With the new modeset infrastructure we should be using the exact same code for dpms and a full modeset call, or something went horribly wrong. -Daniel > > 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 > > 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> > --- > drivers/gpu/drm/i915/i915_reg.h | 54 ++++++- > drivers/gpu/drm/i915/intel_display.c | 266 ++++++++++++++++++++++++++-------- > drivers/gpu/drm/i915/intel_dp.c | 8 +- > 3 files changed, 261 insertions(+), 67 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index fd55b20..b0124e3 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -388,14 +388,61 @@ > #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_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(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(pipe) _PIPE(pipe, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1) > + > +#define _DPIO_PCS_STAGGER_0 0x8230 > +#define _DPIO_PCS_STAGGER_1 0x8430 > +#define DPIO_PCS_STAGGER(pipe) _PIPE(pipe, _DPIO_PCS_STAGGER_0, \ > + _DPIO_PCS_STAGGER_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 > @@ -956,7 +1003,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 794c23e5..cb4ecad 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3648,6 +3648,56 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) > */ > } > > +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, 0x8238, 0x00760018); > + intel_dpio_write(dev_priv, 0x825c, 0x00400888); > + > + intel_dpio_write(dev_priv, 0x8200, 0x10080); > + intel_dpio_write(dev_priv, 0x8204, 0x00600060); > + > + intel_dpio_write(dev_priv, 0x8294, 0x00000000); > + intel_dpio_write(dev_priv, 0x8290, 0x2b245f5f); > + intel_dpio_write(dev_priv, 0x8288, 0x5578b83a); > + intel_dpio_write(dev_priv, 0x828c, 0x0c782040); > + intel_dpio_write(dev_priv, 0x690, 0x2b247878); > + intel_dpio_write(dev_priv, 0x822c, 0x00030000); > + intel_dpio_write(dev_priv, 0x8224, 0x00002000); > + intel_dpio_write(dev_priv, 0x8294, 0x80000000); > + > + } > + 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, 0x8438, 0x00760018); > + intel_dpio_write(dev_priv, 0x845c, 0x00400888); > + > + intel_dpio_write(dev_priv, 0x8400, 0x10080); > + intel_dpio_write(dev_priv, 0x8404, 0x00600060); > + } > +} > + > static void i9xx_crtc_enable(struct drm_crtc *crtc) > { > struct drm_device *dev = crtc->dev; > @@ -3656,6 +3706,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); > > @@ -3667,10 +3718,26 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) > > intel_enable_pll(dev_priv, pipe); > > + 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); > > + for_each_encoder_on_crtc(dev, crtc, encoder) > + encoder->enable(encoder); > + > + 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); > > @@ -3680,9 +3747,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) > /* Give the overlay scaler a chance to enable if it's on this pipe */ > intel_crtc_dpms_overlay(intel_crtc, true); > intel_crtc_update_cursor(crtc, true); > - > - for_each_encoder_on_crtc(dev, crtc, encoder) > - encoder->enable(encoder); > } > > static void i9xx_crtc_disable(struct drm_crtc *crtc) > @@ -3720,6 +3784,26 @@ 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); > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { > + intel_dpio_write(dev_priv, 0x8200, 0x00000000); > + intel_dpio_write(dev_priv, 0x8204, 0x00e00060); > + } else { > + intel_dpio_write(dev_priv, 0x8400, 0x00000000); > + intel_dpio_write(dev_priv, 0x8404, 0x00e00060); > + } > + > + if (pipe) > + vlv_init_dpio(dev); > + mutex_unlock(&dev_priv->dpio_lock); > + } > + > intel_disable_pll(dev_priv, pipe); > > intel_crtc->active = false; > @@ -4272,6 +4356,10 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc, > int pipe = intel_crtc->pipe; > u32 fp, fp2 = 0; > > + /* Disable FP0 register programming for VLV X0 */ > + if (IS_VALLEYVIEW(dev)) > + return; > + > if (IS_PINEVIEW(dev)) { > fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; > if (reduced_clock) > @@ -4296,6 +4384,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, 0x8064); > + reg_val &= 0xffffff30; > + intel_dpio_write(dev_priv, 0x8064, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x80ac); > + reg_val &= 0x8cffffff; > + intel_dpio_write(dev_priv, 0x80ac, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x8064); > + reg_val &= 0xffffff00; > + intel_dpio_write(dev_priv, 0x8064, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x80ac); > + reg_val &= 0xb0ffffff; > + intel_dpio_write(dev_priv, 0x80ac, reg_val); > +} > + > static void vlv_update_pll(struct drm_crtc *crtc, > struct drm_display_mode *mode, > struct drm_display_mode *adjusted_mode, > @@ -4306,23 +4419,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; > @@ -4330,71 +4434,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, 0xc044, 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 (is_hdmi) { > + u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); > > - 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); > - > - 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); > @@ -4710,11 +4842,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); > @@ -4805,6 +4938,17 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, > > intel_update_watermarks(dev); > > + /* Wait for Phy status bits to go low */ > + for_each_encoder_on_crtc(dev, crtc, encoder) { > + if (encoder->type == INTEL_OUTPUT_DISPLAYPORT) { > + if (wait_for(((I915_READ(DPLL(0)) & 0xF0) == 0), 2000)) > + DRM_ERROR("port c phyready timeout\n"); > + } else if (encoder->type == INTEL_OUTPUT_HDMI) { > + if (wait_for(((I915_READ(DPLL(0)) & 0x0F) == 0), 2000)) > + DRM_ERROR("port b phyready timeout\n"); > + } > + } > + > return ret; > } > > @@ -8410,7 +8554,6 @@ static void intel_setup_outputs(struct drm_device *dev) > > if (I915_READ(VLV_DISPLAY_BASE + SDVOC) & PORT_DETECTED) > intel_hdmi_init(dev, VLV_DISPLAY_BASE + SDVOC, PORT_C); > - > } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { > bool found = false; > > @@ -9261,9 +9404,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 > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 0e2750c..2903380 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -1388,10 +1388,12 @@ static void intel_disable_dp(struct intel_encoder *encoder) > static void intel_post_disable_dp(struct intel_encoder *encoder) > { > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > + struct drm_device *dev = encoder->base.dev; > > if (is_cpu_edp(intel_dp)) { > intel_dp_link_down(intel_dp); > - ironlake_edp_pll_off(intel_dp); > + if (!IS_VALLEYVIEW(dev)) > + ironlake_edp_pll_off(intel_dp); > } > } > > @@ -1417,8 +1419,9 @@ static void intel_enable_dp(struct intel_encoder *encoder) > static void intel_pre_enable_dp(struct intel_encoder *encoder) > { > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > + struct drm_device *dev = encoder->base.dev; > > - if (is_cpu_edp(intel_dp)) > + if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) > ironlake_edp_pll_on(intel_dp); > } > > @@ -2760,6 +2763,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, > if (IS_VALLEYVIEW(dev) && port == PORT_C) { > type = DRM_MODE_CONNECTOR_eDP; > intel_encoder->type = INTEL_OUTPUT_EDP; > + intel_dp->is_pch_edp = true; > } else if (port == PORT_A || is_pch_edp(intel_dp)) { > type = DRM_MODE_CONNECTOR_eDP; > intel_encoder->type = INTEL_OUTPUT_EDP; > -- > 1.7.9.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Sat, 02 Mar 2013, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > From: Pallavi G <pallavi.g@intel.com> > > 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 > > 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> > --- > drivers/gpu/drm/i915/i915_reg.h | 54 ++++++- > drivers/gpu/drm/i915/intel_display.c | 266 ++++++++++++++++++++++++++-------- > drivers/gpu/drm/i915/intel_dp.c | 8 +- > 3 files changed, 261 insertions(+), 67 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index fd55b20..b0124e3 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -388,14 +388,61 @@ > #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_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(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(pipe) _PIPE(pipe, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1) > + > +#define _DPIO_PCS_STAGGER_0 0x8230 > +#define _DPIO_PCS_STAGGER_1 0x8430 > +#define DPIO_PCS_STAGGER(pipe) _PIPE(pipe, _DPIO_PCS_STAGGER_0, \ > + _DPIO_PCS_STAGGER_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 > @@ -956,7 +1003,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 794c23e5..cb4ecad 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3648,6 +3648,56 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) > */ > } > > +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, 0x8238, 0x00760018); > + intel_dpio_write(dev_priv, 0x825c, 0x00400888); > + > + intel_dpio_write(dev_priv, 0x8200, 0x10080); > + intel_dpio_write(dev_priv, 0x8204, 0x00600060); > + > + intel_dpio_write(dev_priv, 0x8294, 0x00000000); > + intel_dpio_write(dev_priv, 0x8290, 0x2b245f5f); > + intel_dpio_write(dev_priv, 0x8288, 0x5578b83a); > + intel_dpio_write(dev_priv, 0x828c, 0x0c782040); > + intel_dpio_write(dev_priv, 0x690, 0x2b247878); > + intel_dpio_write(dev_priv, 0x822c, 0x00030000); > + intel_dpio_write(dev_priv, 0x8224, 0x00002000); > + intel_dpio_write(dev_priv, 0x8294, 0x80000000); > + > + } > + 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, 0x8438, 0x00760018); > + intel_dpio_write(dev_priv, 0x845c, 0x00400888); > + > + intel_dpio_write(dev_priv, 0x8400, 0x10080); > + intel_dpio_write(dev_priv, 0x8404, 0x00600060); > + } > +} > + > static void i9xx_crtc_enable(struct drm_crtc *crtc) > { > struct drm_device *dev = crtc->dev; > @@ -3656,6 +3706,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); > > @@ -3667,10 +3718,26 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) > > intel_enable_pll(dev_priv, pipe); > > + mutex_lock(&dev_priv->dpio_lock); > + vlv_pll_enable_reset(crtc); > + mutex_unlock(&dev_priv->dpio_lock); Wrap that in IS_VALLEYVIEW? > + > for_each_encoder_on_crtc(dev, crtc, encoder) > if (encoder->pre_enable) > encoder->pre_enable(encoder); > > + for_each_encoder_on_crtc(dev, crtc, encoder) > + encoder->enable(encoder); > + > + 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); > > @@ -3680,9 +3747,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) > /* Give the overlay scaler a chance to enable if it's on this pipe */ > intel_crtc_dpms_overlay(intel_crtc, true); > intel_crtc_update_cursor(crtc, true); > - > - for_each_encoder_on_crtc(dev, crtc, encoder) > - encoder->enable(encoder); > } > > static void i9xx_crtc_disable(struct drm_crtc *crtc) > @@ -3720,6 +3784,26 @@ 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); > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { > + intel_dpio_write(dev_priv, 0x8200, 0x00000000); > + intel_dpio_write(dev_priv, 0x8204, 0x00e00060); > + } else { > + intel_dpio_write(dev_priv, 0x8400, 0x00000000); > + intel_dpio_write(dev_priv, 0x8404, 0x00e00060); > + } > + > + if (pipe) > + vlv_init_dpio(dev); > + mutex_unlock(&dev_priv->dpio_lock); > + } > + > intel_disable_pll(dev_priv, pipe); > > intel_crtc->active = false; > @@ -4272,6 +4356,10 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc, > int pipe = intel_crtc->pipe; > u32 fp, fp2 = 0; > > + /* Disable FP0 register programming for VLV X0 */ > + if (IS_VALLEYVIEW(dev)) > + return; > + The function isn't called on vlv, afaics. Jani. > if (IS_PINEVIEW(dev)) { > fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; > if (reduced_clock) > @@ -4296,6 +4384,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, 0x8064); > + reg_val &= 0xffffff30; > + intel_dpio_write(dev_priv, 0x8064, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x80ac); > + reg_val &= 0x8cffffff; > + intel_dpio_write(dev_priv, 0x80ac, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x8064); > + reg_val &= 0xffffff00; > + intel_dpio_write(dev_priv, 0x8064, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x80ac); > + reg_val &= 0xb0ffffff; > + intel_dpio_write(dev_priv, 0x80ac, reg_val); > +} > + > static void vlv_update_pll(struct drm_crtc *crtc, > struct drm_display_mode *mode, > struct drm_display_mode *adjusted_mode, > @@ -4306,23 +4419,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; > @@ -4330,71 +4434,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, 0xc044, 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 (is_hdmi) { > + u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); > > - 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); > - > - 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); > @@ -4710,11 +4842,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); > @@ -4805,6 +4938,17 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, > > intel_update_watermarks(dev); > > + /* Wait for Phy status bits to go low */ > + for_each_encoder_on_crtc(dev, crtc, encoder) { > + if (encoder->type == INTEL_OUTPUT_DISPLAYPORT) { > + if (wait_for(((I915_READ(DPLL(0)) & 0xF0) == 0), 2000)) > + DRM_ERROR("port c phyready timeout\n"); > + } else if (encoder->type == INTEL_OUTPUT_HDMI) { > + if (wait_for(((I915_READ(DPLL(0)) & 0x0F) == 0), 2000)) > + DRM_ERROR("port b phyready timeout\n"); > + } > + } > + > return ret; > } > > @@ -8410,7 +8554,6 @@ static void intel_setup_outputs(struct drm_device *dev) > > if (I915_READ(VLV_DISPLAY_BASE + SDVOC) & PORT_DETECTED) > intel_hdmi_init(dev, VLV_DISPLAY_BASE + SDVOC, PORT_C); > - > } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { > bool found = false; > > @@ -9261,9 +9404,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 > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 0e2750c..2903380 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -1388,10 +1388,12 @@ static void intel_disable_dp(struct intel_encoder *encoder) > static void intel_post_disable_dp(struct intel_encoder *encoder) > { > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > + struct drm_device *dev = encoder->base.dev; > > if (is_cpu_edp(intel_dp)) { > intel_dp_link_down(intel_dp); > - ironlake_edp_pll_off(intel_dp); > + if (!IS_VALLEYVIEW(dev)) > + ironlake_edp_pll_off(intel_dp); > } > } > > @@ -1417,8 +1419,9 @@ static void intel_enable_dp(struct intel_encoder *encoder) > static void intel_pre_enable_dp(struct intel_encoder *encoder) > { > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > + struct drm_device *dev = encoder->base.dev; > > - if (is_cpu_edp(intel_dp)) > + if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) > ironlake_edp_pll_on(intel_dp); > } > > @@ -2760,6 +2763,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, > if (IS_VALLEYVIEW(dev) && port == PORT_C) { > type = DRM_MODE_CONNECTOR_eDP; > intel_encoder->type = INTEL_OUTPUT_EDP; > + intel_dp->is_pch_edp = true; > } else if (port == PORT_A || is_pch_edp(intel_dp)) { > type = DRM_MODE_CONNECTOR_eDP; > intel_encoder->type = INTEL_OUTPUT_EDP; > -- > 1.7.9.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Sat, 02 Mar 2013, Jesse Barnes <jbarnes@virtuousgeek.org> wrote: > From: Pallavi G <pallavi.g@intel.com> > > 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 > > 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> > --- > drivers/gpu/drm/i915/i915_reg.h | 54 ++++++- > drivers/gpu/drm/i915/intel_display.c | 266 ++++++++++++++++++++++++++-------- > drivers/gpu/drm/i915/intel_dp.c | 8 +- > 3 files changed, 261 insertions(+), 67 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index fd55b20..b0124e3 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -388,14 +388,61 @@ > #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_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(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(pipe) _PIPE(pipe, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1) > + > +#define _DPIO_PCS_STAGGER_0 0x8230 > +#define _DPIO_PCS_STAGGER_1 0x8430 > +#define DPIO_PCS_STAGGER(pipe) _PIPE(pipe, _DPIO_PCS_STAGGER_0, \ > + _DPIO_PCS_STAGGER_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 > @@ -956,7 +1003,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 794c23e5..cb4ecad 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -3648,6 +3648,56 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) > */ > } > > +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, 0x8238, 0x00760018); > + intel_dpio_write(dev_priv, 0x825c, 0x00400888); > + > + intel_dpio_write(dev_priv, 0x8200, 0x10080); > + intel_dpio_write(dev_priv, 0x8204, 0x00600060); > + > + intel_dpio_write(dev_priv, 0x8294, 0x00000000); > + intel_dpio_write(dev_priv, 0x8290, 0x2b245f5f); > + intel_dpio_write(dev_priv, 0x8288, 0x5578b83a); > + intel_dpio_write(dev_priv, 0x828c, 0x0c782040); > + intel_dpio_write(dev_priv, 0x690, 0x2b247878); > + intel_dpio_write(dev_priv, 0x822c, 0x00030000); > + intel_dpio_write(dev_priv, 0x8224, 0x00002000); > + intel_dpio_write(dev_priv, 0x8294, 0x80000000); > + > + } > + 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, 0x8438, 0x00760018); > + intel_dpio_write(dev_priv, 0x845c, 0x00400888); > + > + intel_dpio_write(dev_priv, 0x8400, 0x10080); > + intel_dpio_write(dev_priv, 0x8404, 0x00600060); > + } > +} Dunno, it feels a bit funny that you add loads of #defines for the dpio stuff, and then use magic numbers here. Also, some of the regs are per-pipe, which is probably all right given the intel_pipe_has_type() checks, but perhaps it would be more self-explanatory if the pipe number was used anyway. All in all, just a /* XXX: clear these up */ would be good too. > + > static void i9xx_crtc_enable(struct drm_crtc *crtc) > { > struct drm_device *dev = crtc->dev; > @@ -3656,6 +3706,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); > > @@ -3667,10 +3718,26 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) > > intel_enable_pll(dev_priv, pipe); > > + mutex_lock(&dev_priv->dpio_lock); > + vlv_pll_enable_reset(crtc); > + mutex_unlock(&dev_priv->dpio_lock); I don't think you should have to grab dpio_lock on !IS_VALLEYVIEW. > + > for_each_encoder_on_crtc(dev, crtc, encoder) > if (encoder->pre_enable) > encoder->pre_enable(encoder); > > + for_each_encoder_on_crtc(dev, crtc, encoder) > + encoder->enable(encoder); > + > + 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); > > @@ -3680,9 +3747,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) > /* Give the overlay scaler a chance to enable if it's on this pipe */ > intel_crtc_dpms_overlay(intel_crtc, true); > intel_crtc_update_cursor(crtc, true); > - > - for_each_encoder_on_crtc(dev, crtc, encoder) > - encoder->enable(encoder); > } > > static void i9xx_crtc_disable(struct drm_crtc *crtc) > @@ -3720,6 +3784,26 @@ 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); > + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { > + intel_dpio_write(dev_priv, 0x8200, 0x00000000); > + intel_dpio_write(dev_priv, 0x8204, 0x00e00060); > + } else { > + intel_dpio_write(dev_priv, 0x8400, 0x00000000); > + intel_dpio_write(dev_priv, 0x8404, 0x00e00060); > + } > + > + if (pipe) > + vlv_init_dpio(dev); > + mutex_unlock(&dev_priv->dpio_lock); > + } > + > intel_disable_pll(dev_priv, pipe); > > intel_crtc->active = false; > @@ -4272,6 +4356,10 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc, > int pipe = intel_crtc->pipe; > u32 fp, fp2 = 0; > > + /* Disable FP0 register programming for VLV X0 */ > + if (IS_VALLEYVIEW(dev)) > + return; > + I don't think i9xx_update_pll_dividers is called on VLV. > if (IS_PINEVIEW(dev)) { > fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; > if (reduced_clock) > @@ -4296,6 +4384,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, 0x8064); > + reg_val &= 0xffffff30; > + intel_dpio_write(dev_priv, 0x8064, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x80ac); > + reg_val &= 0x8cffffff; > + intel_dpio_write(dev_priv, 0x80ac, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x8064); > + reg_val &= 0xffffff00; > + intel_dpio_write(dev_priv, 0x8064, reg_val); > + > + reg_val = intel_dpio_read(dev_priv, 0x80ac); > + reg_val &= 0xb0ffffff; > + intel_dpio_write(dev_priv, 0x80ac, reg_val); > +} > + > static void vlv_update_pll(struct drm_crtc *crtc, > struct drm_display_mode *mode, > struct drm_display_mode *adjusted_mode, > @@ -4306,23 +4419,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; > @@ -4330,71 +4434,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, 0xc044, 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 (is_hdmi) { > + u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); > > - 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); > - > - 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); > @@ -4710,11 +4842,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); > @@ -4805,6 +4938,17 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, > > intel_update_watermarks(dev); > > + /* Wait for Phy status bits to go low */ > + for_each_encoder_on_crtc(dev, crtc, encoder) { > + if (encoder->type == INTEL_OUTPUT_DISPLAYPORT) { > + if (wait_for(((I915_READ(DPLL(0)) & 0xF0) == 0), 2000)) > + DRM_ERROR("port c phyready timeout\n"); > + } else if (encoder->type == INTEL_OUTPUT_HDMI) { > + if (wait_for(((I915_READ(DPLL(0)) & 0x0F) == 0), 2000)) > + DRM_ERROR("port b phyready timeout\n"); > + } > + } > + > return ret; > } > > @@ -8410,7 +8554,6 @@ static void intel_setup_outputs(struct drm_device *dev) > > if (I915_READ(VLV_DISPLAY_BASE + SDVOC) & PORT_DETECTED) > intel_hdmi_init(dev, VLV_DISPLAY_BASE + SDVOC, PORT_C); > - > } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { > bool found = false; > > @@ -9261,9 +9404,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 > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 0e2750c..2903380 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -1388,10 +1388,12 @@ static void intel_disable_dp(struct intel_encoder *encoder) > static void intel_post_disable_dp(struct intel_encoder *encoder) > { > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > + struct drm_device *dev = encoder->base.dev; > > if (is_cpu_edp(intel_dp)) { > intel_dp_link_down(intel_dp); > - ironlake_edp_pll_off(intel_dp); > + if (!IS_VALLEYVIEW(dev)) > + ironlake_edp_pll_off(intel_dp); > } > } > > @@ -1417,8 +1419,9 @@ static void intel_enable_dp(struct intel_encoder *encoder) > static void intel_pre_enable_dp(struct intel_encoder *encoder) > { > struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); > + struct drm_device *dev = encoder->base.dev; > > - if (is_cpu_edp(intel_dp)) > + if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) > ironlake_edp_pll_on(intel_dp); > } > > @@ -2760,6 +2763,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, > if (IS_VALLEYVIEW(dev) && port == PORT_C) { > type = DRM_MODE_CONNECTOR_eDP; > intel_encoder->type = INTEL_OUTPUT_EDP; > + intel_dp->is_pch_edp = true; > } else if (port == PORT_A || is_pch_edp(intel_dp)) { > type = DRM_MODE_CONNECTOR_eDP; > intel_encoder->type = INTEL_OUTPUT_EDP; > -- > 1.7.9.5 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
On Fri, 08 Mar 2013 15:33:32 +0200 Jani Nikula <jani.nikula@linux.intel.com> wrote: > > + intel_dpio_write(dev_priv, 0x8438, 0x00760018); > > + intel_dpio_write(dev_priv, 0x845c, 0x00400888); > > + > > + intel_dpio_write(dev_priv, 0x8400, 0x10080); > > + intel_dpio_write(dev_priv, 0x8404, 0x00600060); > > + } > > +} > > Dunno, it feels a bit funny that you add loads of #defines for the dpio > stuff, and then use magic numbers here. > > Also, some of the regs are per-pipe, which is probably all right given > the intel_pipe_has_type() checks, but perhaps it would be more > self-explanatory if the pipe number was used anyway. > > All in all, just a /* XXX: clear these up */ would be good too. I know, it's ugly. I'm having to make up names for some of these since we don't have real docs for them, just cspec info. Agree that they could be nicer, but w/o a real programming guide they won't map back to anything useful anyway, so the numbers may actually be better. I took your other comments into account already from your last review, I'll post updated patches today.
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index fd55b20..b0124e3 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -388,14 +388,61 @@ #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_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(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(pipe) _PIPE(pipe, _DPIO_PCS_CLK_0, _DPIO_PCS_CLK_1) + +#define _DPIO_PCS_STAGGER_0 0x8230 +#define _DPIO_PCS_STAGGER_1 0x8430 +#define DPIO_PCS_STAGGER(pipe) _PIPE(pipe, _DPIO_PCS_STAGGER_0, \ + _DPIO_PCS_STAGGER_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 @@ -956,7 +1003,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 794c23e5..cb4ecad 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3648,6 +3648,56 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) */ } +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, 0x8238, 0x00760018); + intel_dpio_write(dev_priv, 0x825c, 0x00400888); + + intel_dpio_write(dev_priv, 0x8200, 0x10080); + intel_dpio_write(dev_priv, 0x8204, 0x00600060); + + intel_dpio_write(dev_priv, 0x8294, 0x00000000); + intel_dpio_write(dev_priv, 0x8290, 0x2b245f5f); + intel_dpio_write(dev_priv, 0x8288, 0x5578b83a); + intel_dpio_write(dev_priv, 0x828c, 0x0c782040); + intel_dpio_write(dev_priv, 0x690, 0x2b247878); + intel_dpio_write(dev_priv, 0x822c, 0x00030000); + intel_dpio_write(dev_priv, 0x8224, 0x00002000); + intel_dpio_write(dev_priv, 0x8294, 0x80000000); + + } + 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, 0x8438, 0x00760018); + intel_dpio_write(dev_priv, 0x845c, 0x00400888); + + intel_dpio_write(dev_priv, 0x8400, 0x10080); + intel_dpio_write(dev_priv, 0x8404, 0x00600060); + } +} + static void i9xx_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -3656,6 +3706,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); @@ -3667,10 +3718,26 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_enable_pll(dev_priv, pipe); + 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); + for_each_encoder_on_crtc(dev, crtc, encoder) + encoder->enable(encoder); + + 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); @@ -3680,9 +3747,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) /* Give the overlay scaler a chance to enable if it's on this pipe */ intel_crtc_dpms_overlay(intel_crtc, true); intel_crtc_update_cursor(crtc, true); - - for_each_encoder_on_crtc(dev, crtc, encoder) - encoder->enable(encoder); } static void i9xx_crtc_disable(struct drm_crtc *crtc) @@ -3720,6 +3784,26 @@ 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); + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) { + intel_dpio_write(dev_priv, 0x8200, 0x00000000); + intel_dpio_write(dev_priv, 0x8204, 0x00e00060); + } else { + intel_dpio_write(dev_priv, 0x8400, 0x00000000); + intel_dpio_write(dev_priv, 0x8404, 0x00e00060); + } + + if (pipe) + vlv_init_dpio(dev); + mutex_unlock(&dev_priv->dpio_lock); + } + intel_disable_pll(dev_priv, pipe); intel_crtc->active = false; @@ -4272,6 +4356,10 @@ static void i9xx_update_pll_dividers(struct drm_crtc *crtc, int pipe = intel_crtc->pipe; u32 fp, fp2 = 0; + /* Disable FP0 register programming for VLV X0 */ + if (IS_VALLEYVIEW(dev)) + return; + if (IS_PINEVIEW(dev)) { fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; if (reduced_clock) @@ -4296,6 +4384,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, 0x8064); + reg_val &= 0xffffff30; + intel_dpio_write(dev_priv, 0x8064, reg_val); + + reg_val = intel_dpio_read(dev_priv, 0x80ac); + reg_val &= 0x8cffffff; + intel_dpio_write(dev_priv, 0x80ac, reg_val); + + reg_val = intel_dpio_read(dev_priv, 0x8064); + reg_val &= 0xffffff00; + intel_dpio_write(dev_priv, 0x8064, reg_val); + + reg_val = intel_dpio_read(dev_priv, 0x80ac); + reg_val &= 0xb0ffffff; + intel_dpio_write(dev_priv, 0x80ac, reg_val); +} + static void vlv_update_pll(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -4306,23 +4419,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; @@ -4330,71 +4434,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, 0xc044, 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 (is_hdmi) { + u32 temp = intel_mode_get_pixel_multiplier(adjusted_mode); - 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); - - 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); @@ -4710,11 +4842,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); @@ -4805,6 +4938,17 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, intel_update_watermarks(dev); + /* Wait for Phy status bits to go low */ + for_each_encoder_on_crtc(dev, crtc, encoder) { + if (encoder->type == INTEL_OUTPUT_DISPLAYPORT) { + if (wait_for(((I915_READ(DPLL(0)) & 0xF0) == 0), 2000)) + DRM_ERROR("port c phyready timeout\n"); + } else if (encoder->type == INTEL_OUTPUT_HDMI) { + if (wait_for(((I915_READ(DPLL(0)) & 0x0F) == 0), 2000)) + DRM_ERROR("port b phyready timeout\n"); + } + } + return ret; } @@ -8410,7 +8554,6 @@ static void intel_setup_outputs(struct drm_device *dev) if (I915_READ(VLV_DISPLAY_BASE + SDVOC) & PORT_DETECTED) intel_hdmi_init(dev, VLV_DISPLAY_BASE + SDVOC, PORT_C); - } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { bool found = false; @@ -9261,9 +9404,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 diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0e2750c..2903380 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1388,10 +1388,12 @@ static void intel_disable_dp(struct intel_encoder *encoder) static void intel_post_disable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct drm_device *dev = encoder->base.dev; if (is_cpu_edp(intel_dp)) { intel_dp_link_down(intel_dp); - ironlake_edp_pll_off(intel_dp); + if (!IS_VALLEYVIEW(dev)) + ironlake_edp_pll_off(intel_dp); } } @@ -1417,8 +1419,9 @@ static void intel_enable_dp(struct intel_encoder *encoder) static void intel_pre_enable_dp(struct intel_encoder *encoder) { struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct drm_device *dev = encoder->base.dev; - if (is_cpu_edp(intel_dp)) + if (is_cpu_edp(intel_dp) && !IS_VALLEYVIEW(dev)) ironlake_edp_pll_on(intel_dp); } @@ -2760,6 +2763,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, if (IS_VALLEYVIEW(dev) && port == PORT_C) { type = DRM_MODE_CONNECTOR_eDP; intel_encoder->type = INTEL_OUTPUT_EDP; + intel_dp->is_pch_edp = true; } else if (port == PORT_A || is_pch_edp(intel_dp)) { type = DRM_MODE_CONNECTOR_eDP; intel_encoder->type = INTEL_OUTPUT_EDP;