From mboxrd@z Thu Jan 1 00:00:00 1970 From: Imre Deak Subject: Re: [PATCH 22/71] drm/i915/chv: Add phy supports for Cherryview Date: Wed, 30 Apr 2014 15:13:53 +0300 Message-ID: <1398860033.6163.6.camel@intelbox> References: <1397039349-10639-1-git-send-email-ville.syrjala@linux.intel.com> <1397039349-10639-23-git-send-email-ville.syrjala@linux.intel.com> Reply-To: imre.deak@intel.com Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1932568311==" Return-path: Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id E53D76E238 for ; Wed, 30 Apr 2014 05:14:00 -0700 (PDT) In-Reply-To: <1397039349-10639-23-git-send-email-ville.syrjala@linux.intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: ville.syrjala@linux.intel.com Cc: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org --===============1932568311== Content-Type: multipart/signed; micalg="pgp-sha1"; protocol="application/pgp-signature"; boundary="=-XMO5DxJWqiP6BLQrALhJ" --=-XMO5DxJWqiP6BLQrALhJ Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Wed, 2014-04-09 at 13:28 +0300, ville.syrjala@linux.intel.com wrote: > From: Chon Ming Lee >=20 > Added programming phy layer for CHV based on "Application note for 1273 > CHV Display phy". >=20 > v2: Rebase the code and do some cleanup. > v3: Rework based on Ville review. > -Fix the macro where the ch info need to swap, and add parens to ? > operator. > -Fix wrong bit define for DPIO_PCS_SWING_CALC_0 and > DPIO_PCS_SWING_CALC_1 and rename for meaningful. > -Add some comments for CHV specific DPIO registers. > -Change the dp margin registery value to decimal to align with the > doc. > -Fix the not clearing some value in vlv_dpio_read before write again. > -Create new hdmi/dp encoder function for chv instead of share with > valleyview. > v4: Rebase the code after rename the DPIO registers define and upstream > change. > Based on Ville review. > -For unique transition scale selection, after Ville point out, look > like the doc might wrong for the bit 26. Use bit 27 for ch0 and > ch1. > -Break up some dpio write value into two/three steps for readability. > -Remove unrelated change. > -Add some shift define for some registers instead just give the hex > value. > -Fix a bug where write to wrong VLV_TX_DW3. > v5: Based on Ville review. > - Move tx lane latency optimal setting from chv_dp_pre_pll_enable to > chv_pre_enable_dp, and chv_hdmi_pre_pll_enable to > chv_hdmi_pre_enable respectively. > - Fix typo in one margin_reg_value for DP_TRAIN_VOLTAGE_SWING_400. > - Clear DPIO_TX_UNIQ_TRANS_SCALE_EN for DP and HDMI. > - Mask the old deemph and swing bits for hdmi. > v6: Remove stub for pre_pll_enable for dp and hdmi. >=20 > Signed-off-by: Chon Ming Lee > Reviewed-by: Ville Syrj=C3=A4l=C3=A4 > [vsyrjala: Don't touch panel power sequencing on DP] > Signed-off-by: Ville Syrj=C3=A4l=C3=A4 Looks ok, so: Reviewed-by: Imre Deak Some nitpicks follow, fixing them is optional. > --- > drivers/gpu/drm/i915/intel_dp.c | 188 ++++++++++++++++++++++++++++++++= +++++- > drivers/gpu/drm/i915/intel_hdmi.c | 84 ++++++++++++++++- > 2 files changed, 270 insertions(+), 2 deletions(-) >=20 > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel= _dp.c > index 6be7b35..71a4fa2 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -1932,6 +1932,50 @@ static void vlv_dp_pre_pll_enable(struct intel_enc= oder *encoder) > mutex_unlock(&dev_priv->dpio_lock); > } > =20 > +static void chv_pre_enable_dp(struct intel_encoder *encoder) > +{ > + struct intel_dp *intel_dp =3D enc_to_intel_dp(&encoder->base); > + struct intel_digital_port *dport =3D dp_to_dig_port(intel_dp); > + struct drm_device *dev =3D encoder->base.dev; > + struct drm_i915_private *dev_priv =3D dev->dev_private; > + struct edp_power_seq power_seq; > + struct intel_crtc *intel_crtc =3D > + to_intel_crtc(encoder->base.crtc); > + enum dpio_channel ch =3D vlv_dport_to_channel(dport); > + int pipe =3D intel_crtc->pipe; > + int data, i; > + > + /* Program Tx lane latency optimal setting*/ > + mutex_lock(&dev_priv->dpio_lock); > + for (i =3D 0; i < 4; i++) { > + /* Set the latency optimal bit */ > + data =3D (i =3D=3D 1) ? 0x0 : 0x6; > + vlv_dpio_write(dev_priv, pipe, CHV_TX_DW11(ch, i), > + data << DPIO_FRC_LATENCY_SHFIT); > + > + /* Set the upar bit */ > + data =3D (i =3D=3D 1) ? 0x0 : 0x1; > + vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i), > + data << DPIO_UPAR_SHIFT); > + } > + > + /* Data lane stagger programming */ > + /* FIXME: Fix up value only after power analysis */ > + > + mutex_unlock(&dev_priv->dpio_lock); > + > + if (is_edp(intel_dp)) { > + /* init power sequencer on this pipe and port */ > + intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq); > + intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, > + &power_seq); > + } > + > + intel_enable_dp(encoder); > + > + vlv_wait_port_ready(dev_priv, dport); > +} > + > /* > * Native read with retry for link status and receiver capability reads = for > * cases where the sink may still be asleep. > @@ -2156,6 +2200,142 @@ static uint32_t intel_vlv_signal_levels(struct in= tel_dp *intel_dp) > return 0; > } > =20 > +static uint32_t intel_chv_signal_levels(struct intel_dp *intel_dp) > +{ > + struct drm_device *dev =3D intel_dp_to_dev(intel_dp); > + struct drm_i915_private *dev_priv =3D dev->dev_private; > + struct intel_digital_port *dport =3D dp_to_dig_port(intel_dp); > + struct intel_crtc *intel_crtc =3D to_intel_crtc(dport->base.base.crtc); > + u32 deemph_reg_value, margin_reg_value, val, tx_dw2; > + uint8_t train_set =3D intel_dp->train_set[0]; > + enum dpio_channel ch =3D vlv_dport_to_channel(dport); > + int pipe =3D intel_crtc->pipe; > + > + switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { > + case DP_TRAIN_PRE_EMPHASIS_0: > + switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { > + case DP_TRAIN_VOLTAGE_SWING_400: > + deemph_reg_value =3D 128; > + margin_reg_value =3D 52; > + break; > + case DP_TRAIN_VOLTAGE_SWING_600: > + deemph_reg_value =3D 128; > + margin_reg_value =3D 77; > + break; > + case DP_TRAIN_VOLTAGE_SWING_800: > + deemph_reg_value =3D 128; > + margin_reg_value =3D 102; > + break; > + case DP_TRAIN_VOLTAGE_SWING_1200: > + deemph_reg_value =3D 128; > + margin_reg_value =3D 154; > + /* FIXME extra to set for 1200 */ > + break; > + default: We could throw a WARN at these spots, as they would all point to a bug in the driver. > + return 0; > + } > + break; > + case DP_TRAIN_PRE_EMPHASIS_3_5: > + switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { > + case DP_TRAIN_VOLTAGE_SWING_400: > + deemph_reg_value =3D 85; > + margin_reg_value =3D 78; > + break; > + case DP_TRAIN_VOLTAGE_SWING_600: > + deemph_reg_value =3D 85; > + margin_reg_value =3D 116; > + break; > + case DP_TRAIN_VOLTAGE_SWING_800: > + deemph_reg_value =3D 85; > + margin_reg_value =3D 154; > + break; > + default: > + return 0; > + } > + break; > + case DP_TRAIN_PRE_EMPHASIS_6: > + switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { > + case DP_TRAIN_VOLTAGE_SWING_400: > + deemph_reg_value =3D 64; > + margin_reg_value =3D 104; > + break; > + case DP_TRAIN_VOLTAGE_SWING_600: > + deemph_reg_value =3D 64; > + margin_reg_value =3D 154; > + break; > + default: > + return 0; > + } > + break; > + case DP_TRAIN_PRE_EMPHASIS_9_5: > + switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { > + case DP_TRAIN_VOLTAGE_SWING_400: > + deemph_reg_value =3D 43; > + margin_reg_value =3D 154; > + break; > + default: > + return 0; > + } > + break; > + default: > + return 0; > + } > + > + mutex_lock(&dev_priv->dpio_lock); > + > + /* Clear calc init */ > + vlv_dpio_write(dev_priv, pipe, CHV_PCS_DW10(ch), 0); > + > + /* Program swing deemph */ > + val =3D vlv_dpio_read(dev_priv, pipe, VLV_TX_DW4(ch)); > + val &=3D ~DPIO_SWING_DEEMPH9P5_MASK; > + val |=3D deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT; > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(ch), val); > + > + /* Program swing margin */ > + tx_dw2 =3D vlv_dpio_read(dev_priv, pipe, VLV_TX_DW2(ch)); > + tx_dw2 &=3D ~DPIO_SWING_MARGIN_MASK; > + tx_dw2 |=3D margin_reg_value << DPIO_SWING_MARGIN_SHIFT; > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(ch), tx_dw2); > + > + /* Disable unique transition scale */ > + val =3D vlv_dpio_read(dev_priv, pipe, VLV_TX_DW3(ch)); > + val &=3D ~DPIO_TX_UNIQ_TRANS_SCALE_EN; > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(ch), val); > + > + if (((train_set & DP_TRAIN_PRE_EMPHASIS_MASK) > + =3D=3D DP_TRAIN_PRE_EMPHASIS_0) && > + ((train_set & DP_TRAIN_VOLTAGE_SWING_MASK) > + =3D=3D DP_TRAIN_VOLTAGE_SWING_1200)) { It works, but the check for pre-emphasis is redundant. > + > + /* > + * The document said it needs to set bit 27 for ch0 and bit 26 > + * for ch1. Might be a typo in the doc. > + * For now, for this unique transition scale selection, set bit > + * 27 for ch0 and ch1. > + */ > + val =3D vlv_dpio_read(dev_priv, pipe, VLV_TX_DW3(ch)); > + val |=3D DPIO_TX_UNIQ_TRANS_SCALE_EN; > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(ch), val); > + > + tx_dw2 |=3D (0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT); > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(ch), tx_dw2); > + } > + > + /* Start swing calculation */ > + vlv_dpio_write(dev_priv, pipe, CHV_PCS_DW10(ch), > + (DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3)); > + > + /* LRC Bypass */ > + val =3D vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30); > + val |=3D DPIO_LRC_BYPASS; > + vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, val); > + > + mutex_unlock(&dev_priv->dpio_lock); > + > + return 0; > +} > + > static void > intel_get_adjust_train(struct intel_dp *intel_dp, > const uint8_t link_status[DP_LINK_STATUS_SIZE]) > @@ -2370,6 +2550,9 @@ intel_dp_set_signal_levels(struct intel_dp *intel_d= p, uint32_t *DP) > } else if (IS_HASWELL(dev)) { > signal_levels =3D intel_hsw_signal_levels(train_set); > mask =3D DDI_BUF_EMP_MASK; > + } else if (IS_CHERRYVIEW(dev)) { > + signal_levels =3D intel_chv_signal_levels(intel_dp); > + mask =3D 0; > } else if (IS_VALLEYVIEW(dev)) { > signal_levels =3D intel_vlv_signal_levels(intel_dp); > mask =3D 0; > @@ -3865,7 +4048,10 @@ intel_dp_init(struct drm_device *dev, int output_r= eg, enum port port) > intel_encoder->disable =3D intel_disable_dp; > intel_encoder->get_hw_state =3D intel_dp_get_hw_state; > intel_encoder->get_config =3D intel_dp_get_config; > - if (IS_VALLEYVIEW(dev)) { > + if (IS_CHERRYVIEW(dev)) { > + intel_encoder->pre_enable =3D chv_pre_enable_dp; > + intel_encoder->enable =3D vlv_enable_dp; > + } else if (IS_VALLEYVIEW(dev)) { > intel_encoder->pre_pll_enable =3D vlv_dp_pre_pll_enable; > intel_encoder->pre_enable =3D vlv_pre_enable_dp; > intel_encoder->enable =3D vlv_enable_dp; > diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/int= el_hdmi.c > index b0413e1..bbda011 100644 > --- a/drivers/gpu/drm/i915/intel_hdmi.c > +++ b/drivers/gpu/drm/i915/intel_hdmi.c > @@ -1198,6 +1198,85 @@ static void vlv_hdmi_post_disable(struct intel_enc= oder *encoder) > mutex_unlock(&dev_priv->dpio_lock); > } > =20 > +static void chv_hdmi_pre_enable(struct intel_encoder *encoder) > +{ > + struct intel_digital_port *dport =3D enc_to_dig_port(&encoder->base); > + struct drm_device *dev =3D encoder->base.dev; > + struct drm_i915_private *dev_priv =3D dev->dev_private; > + struct intel_crtc *intel_crtc =3D > + to_intel_crtc(encoder->base.crtc); > + enum dpio_channel ch =3D vlv_dport_to_channel(dport); > + int pipe =3D intel_crtc->pipe; > + int data, i; > + u32 val; > + > + /* Program Tx latency optimal setting */ > + mutex_lock(&dev_priv->dpio_lock); > + for (i =3D 0; i < 4; i++) { > + /* Set the latency optimal bit */ > + data =3D (i =3D=3D 1) ? 0x0 : 0x6; > + vlv_dpio_write(dev_priv, pipe, CHV_TX_DW11(ch, i), > + data << DPIO_FRC_LATENCY_SHFIT); > + > + /* Set the upar bit */ > + data =3D (i =3D=3D 1) ? 0x0 : 0x1; > + vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i), > + data << DPIO_UPAR_SHIFT); > + } > + > + /* Data lane stagger programming */ > + /* FIXME: Fix up value only after power analysis */ > + > + /* Clear calc init */ > + vlv_dpio_write(dev_priv, pipe, CHV_PCS_DW10(ch), 0); > + > + /* FIXME: Program the support xxx V-dB */ > + /* Use 800mV-0dB */ > + val =3D vlv_dpio_read(dev_priv, pipe, VLV_TX_DW4(ch)); > + val &=3D ~DPIO_SWING_DEEMPH9P5_MASK; > + val |=3D 128 << DPIO_SWING_DEEMPH9P5_SHIFT; > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(ch), val); > + > + val =3D vlv_dpio_read(dev_priv, pipe, VLV_TX_DW2(ch)); > + val &=3D ~DPIO_SWING_MARGIN_MASK; > + val |=3D 102 << DPIO_SWING_MARGIN_SHIFT; > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(ch), val); > + > + /* Disable unique transition scale */ > + val =3D vlv_dpio_read(dev_priv, pipe, VLV_TX_DW3(ch)); > + val &=3D ~DPIO_TX_UNIQ_TRANS_SCALE_EN; > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(ch), val); > + > + /* Additional steps for 1200mV-0dB */ > +#if 0 > + val =3D vlv_dpio_read(dev_priv, pipe, VLV_TX_DW3(ch)); > + if (ch) > + val |=3D DPIO_TX_UNIQ_TRANS_SCALE_CH1; > + else > + val |=3D DPIO_TX_UNIQ_TRANS_SCALE_CH0; > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(ch), val); > + > + vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(ch), > + vlv_dpio_read(dev_priv, pipe, VLV_TX_DW2(ch)) | > + (0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT)); > +#endif Could remove this chunk. > + /* Start swing calculation */ > + vlv_dpio_write(dev_priv, pipe, CHV_PCS_DW10(ch), > + DPIO_PCS_SWING_CALC_TX0_TX2 | > + DPIO_PCS_SWING_CALC_TX1_TX3); > + > + /* LRC Bypass */ > + val =3D vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30); > + val |=3D DPIO_LRC_BYPASS; > + vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, val); > + > + mutex_unlock(&dev_priv->dpio_lock); > + > + intel_enable_hdmi(encoder); > + > + vlv_wait_port_ready(dev_priv, dport); > +} > + > static void intel_hdmi_destroy(struct drm_connector *connector) > { > drm_connector_cleanup(connector); > @@ -1332,7 +1411,10 @@ void intel_hdmi_init(struct drm_device *dev, int h= dmi_reg, enum port port) > intel_encoder->disable =3D intel_disable_hdmi; > intel_encoder->get_hw_state =3D intel_hdmi_get_hw_state; > intel_encoder->get_config =3D intel_hdmi_get_config; > - if (IS_VALLEYVIEW(dev)) { > + if (IS_CHERRYVIEW(dev)) { > + intel_encoder->pre_enable =3D chv_hdmi_pre_enable; > + intel_encoder->enable =3D vlv_enable_hdmi; > + } else if (IS_VALLEYVIEW(dev)) { > intel_encoder->pre_pll_enable =3D vlv_hdmi_pre_pll_enable; > intel_encoder->pre_enable =3D vlv_hdmi_pre_enable; > intel_encoder->enable =3D vlv_enable_hdmi; --=-XMO5DxJWqiP6BLQrALhJ Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQEcBAABAgAGBQJTYOkBAAoJEORIIAnNuWDFvc4H/1UQI4IDttKFkB6Gwn3BjmbH 6atREM6UpE82ZAQF/BBzloTMNgc/l81V7ClSv0DidrNzPhe7KFSGefYnsju5T1eE 9SbpXG8eJAM5ucDF8rIZjjsFA2nNbfl/14ZeBJJMqfZ0G3vCrVISSx1zQfpRVD7I NhLKXU4qFXm/2RqKL75MjMEl2f2GGA4cvR2BT987HiuVClFau2ekLafOou7RaH6p y/7ylcKTwdlzNU5eEusZNbEHVsBwz7pgAk++3vFHCFIaUkUJ4XzJzLLFCGd8Iyxj aP72VOXf0GqvOGWhCB6+vFNsGSeYsejlhuA4Rf/3YnzeA5/Z2yAfNGOhmeNKLus= =XXqw -----END PGP SIGNATURE----- --=-XMO5DxJWqiP6BLQrALhJ-- --===============1932568311== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx --===============1932568311==--