From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Imre Deak <imre.deak@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH v2 3/6] drm/i915/lvds: Restore initial HW state during encoder enabling
Date: Tue, 9 Aug 2016 20:46:54 +0300 [thread overview]
Message-ID: <20160809174654.GB4329@intel.com> (raw)
In-Reply-To: <1470763294-7183-2-git-send-email-imre.deak@intel.com>
On Tue, Aug 09, 2016 at 08:21:32PM +0300, Imre Deak wrote:
> Atm the LVDS encoder depends on the PPS HW context being saved/restored
> from generic suspend/resume code. Since the PPS is specific to the LVDS
> and eDP encoders a cleaner way is to reinitialize it during encoder
> enabling, so do this here for LVDS. Follow-up patches will init the PPS
> for the eDP encoder similarly and remove the suspend/resume time save /
> restore.
>
> v2:
> - Apply BSpec +1 offset and use DIV_ROUND_UP() when programming the
> power cycle delay. (Ville)
>
> Signed-off-by: Imre Deak <imre.deak@intel.com>
> ---
> drivers/gpu/drm/i915/i915_reg.h | 1 +
> drivers/gpu/drm/i915/intel_lvds.c | 113 +++++++++++++++++++++++++++++++++-----
> 2 files changed, 101 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 889508f..da82744 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3710,6 +3710,7 @@ enum {
>
> #define _PP_ON_DELAYS 0x61208
> #define PP_ON_DELAYS(pps_idx) _MMIO_PPS(pps_idx, _PP_ON_DELAYS)
> +#define PANEL_PORT_SELECT_SHIFT 30
> #define PANEL_PORT_SELECT_MASK (3 << 30)
> #define PANEL_PORT_SELECT_LVDS (0 << 30)
> #define PANEL_PORT_SELECT_DPA (1 << 30)
> diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
> index c5739fc..939f51f 100644
> --- a/drivers/gpu/drm/i915/intel_lvds.c
> +++ b/drivers/gpu/drm/i915/intel_lvds.c
> @@ -48,6 +48,20 @@ struct intel_lvds_connector {
> struct notifier_block lid_notifier;
> };
>
> +struct intel_lvds_pps {
> + /* 100us units */
> + int t1_t2;
> + int t3;
> + int t4;
> + int t5;
> + int tx;
> +
> + int divider;
> +
> + int port;
> + bool reset_on_powerdown;
powerdown_on_reset?
> +};
> +
> struct intel_lvds_encoder {
> struct intel_encoder base;
>
> @@ -55,6 +69,9 @@ struct intel_lvds_encoder {
> i915_reg_t reg;
> u32 a3_power;
>
> + struct intel_lvds_pps init_pps;
> + u32 init_lvds_val;
> +
> struct intel_lvds_connector *attached_connector;
> };
>
> @@ -136,6 +153,82 @@ static void intel_lvds_get_config(struct intel_encoder *encoder,
> pipe_config->base.adjusted_mode.crtc_clock = pipe_config->port_clock;
> }
>
> +static void intel_lvds_pps_get_hw_state(struct drm_i915_private *dev_priv,
> + struct intel_lvds_pps *pps)
> +{
> + u32 val;
> +
> + pps->reset_on_powerdown = I915_READ(PP_CONTROL(0)) & PANEL_POWER_RESET;
> +
> + val = I915_READ(PP_ON_DELAYS(0));
> + pps->port = (val & PANEL_PORT_SELECT_MASK) >>
> + PANEL_PORT_SELECT_SHIFT;
> + pps->t1_t2 = (val & PANEL_POWER_UP_DELAY_MASK) >>
> + PANEL_POWER_UP_DELAY_SHIFT;
> + pps->t5 = (val & PANEL_LIGHT_ON_DELAY_MASK) >>
> + PANEL_LIGHT_ON_DELAY_SHIFT;
> +
> + val = I915_READ(PP_OFF_DELAYS(0));
> + pps->t3 = (val & PANEL_POWER_DOWN_DELAY_MASK) >>
> + PANEL_POWER_DOWN_DELAY_SHIFT;
> + pps->tx = (val & PANEL_LIGHT_OFF_DELAY_MASK) >>
> + PANEL_LIGHT_OFF_DELAY_SHIFT;
> +
> + val = I915_READ(PP_DIVISOR(0));
> + pps->divider = (val & PP_REFERENCE_DIVIDER_MASK) >>
> + PP_REFERENCE_DIVIDER_SHIFT;
> + val = (val & PANEL_POWER_CYCLE_DELAY_MASK) >>
> + PANEL_POWER_CYCLE_DELAY_SHIFT;
> + /*
> + * Remove the BSpec specified +1 (100ms) offset that accounts for a
> + * too short power-cycle delay due to the asynchronous programming of
> + * the register.
> + */
> + if (val)
> + val--;
> + /* Convert from 100ms to 100us units */
> + pps->t4 = val * 1000;
> +
> + if (INTEL_INFO(dev_priv)->gen <= 4 &&
> + pps->t1_t2 == 0 && pps->t5 == 0 && pps->t3 == 0 && pps->tx == 0) {
> + DRM_DEBUG_KMS("Panel power timings uninitialized, "
> + "setting defaults\n");
> + /* Set T2 to 40ms and T5 to 200ms in 100 usec units */
> + pps->t1_t2 = 40 * 10;
> + pps->t5 = 200 * 10;
> + /* Set T3 to 35ms and Tx to 200ms in 100 usec units */
> + pps->t3 = 35 * 10;
> + pps->tx = 200 * 10;
> + }
> +
> + DRM_DEBUG_DRIVER("LVDS PPS:t1+t2 %d t3 %d t4 %d t5 %d tx %d "
> + "divider %d port %d reset_on_powerdown %d\n",
> + pps->t1_t2, pps->t3, pps->t4, pps->t5, pps->tx,
> + pps->divider, pps->port, pps->reset_on_powerdown);
> +}
> +
> +static void intel_lvds_pps_init_hw(struct drm_i915_private *dev_priv,
> + struct intel_lvds_pps *pps)
> +{
> + u32 val;
> +
> + val = I915_READ(PP_CONTROL(0));
> + WARN_ON((val & PANEL_UNLOCK_MASK) != PANEL_UNLOCK_REGS);
> + if (pps->reset_on_powerdown)
> + val |= PANEL_POWER_RESET;
> + I915_WRITE(PP_CONTROL(0), val);
> +
> + I915_WRITE(PP_ON_DELAYS(0), (pps->port << PANEL_PORT_SELECT_SHIFT) |
> + (pps->t1_t2 << PANEL_POWER_UP_DELAY_SHIFT) |
> + (pps->t5 << PANEL_LIGHT_ON_DELAY_SHIFT));
> + I915_WRITE(PP_OFF_DELAYS(0), (pps->t3 << PANEL_POWER_DOWN_DELAY_SHIFT) |
> + (pps->tx << PANEL_LIGHT_OFF_DELAY_SHIFT));
> +
> + val = pps->divider << PP_REFERENCE_DIVIDER_SHIFT;
> + val |= DIV_ROUND_UP(pps->t4 + 1, 1000) << PANEL_POWER_CYCLE_DELAY_SHIFT;
+1 vs. div in the wrong order
With that fixed
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> + I915_WRITE(PP_DIVISOR(0), val);
> +}
> +
> static void intel_pre_enable_lvds(struct intel_encoder *encoder)
> {
> struct intel_lvds_encoder *lvds_encoder = to_lvds_encoder(&encoder->base);
> @@ -154,7 +247,9 @@ static void intel_pre_enable_lvds(struct intel_encoder *encoder)
> assert_pll_disabled(dev_priv, pipe);
> }
>
> - temp = I915_READ(lvds_encoder->reg);
> + intel_lvds_pps_init_hw(dev_priv, &lvds_encoder->init_pps);
> +
> + temp = lvds_encoder->init_lvds_val;
> temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
>
> if (HAS_PCH_CPT(dev)) {
> @@ -922,18 +1017,6 @@ void intel_lvds_init(struct drm_device *dev)
> DRM_DEBUG_KMS("LVDS is not present in VBT, but enabled anyway\n");
> }
>
> - /* Set the Panel Power On/Off timings if uninitialized. */
> - if (INTEL_INFO(dev_priv)->gen < 5 &&
> - I915_READ(PP_ON_DELAYS(0)) == 0 && I915_READ(PP_OFF_DELAYS(0)) == 0) {
> - /* Set T2 to 40ms and T5 to 200ms */
> - I915_WRITE(PP_ON_DELAYS(0), 0x019007d0);
> -
> - /* Set T3 to 35ms and Tx to 200ms */
> - I915_WRITE(PP_OFF_DELAYS(0), 0x015e07d0);
> -
> - DRM_DEBUG_KMS("Panel power timings uninitialized, setting defaults\n");
> - }
> -
> lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL);
> if (!lvds_encoder)
> return;
> @@ -999,6 +1082,10 @@ void intel_lvds_init(struct drm_device *dev)
> dev->mode_config.scaling_mode_property,
> DRM_MODE_SCALE_ASPECT);
> intel_connector->panel.fitting_mode = DRM_MODE_SCALE_ASPECT;
> +
> + intel_lvds_pps_get_hw_state(dev_priv, &lvds_encoder->init_pps);
> + lvds_encoder->init_lvds_val = lvds;
> +
> /*
> * LVDS discovery:
> * 1) check for EDID on DDC
> --
> 2.5.0
--
Ville Syrjälä
Intel OTC
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2016-08-09 17:46 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-09 11:34 [PATCH 0/6] drm/i915: Clean up LVDS/PPS macros, suspend/resume logic Imre Deak
2016-08-09 11:34 ` [PATCH 1/6] drm/i915: Merge the PPS register definitions Imre Deak
2016-08-09 11:53 ` Ville Syrjälä
2016-08-09 13:24 ` Imre Deak
2016-08-09 17:21 ` [PATCH v2 " Imre Deak
2016-08-09 17:50 ` Ville Syrjälä
2016-08-09 11:34 ` [PATCH 2/6] drm/i915: Merge TARGET_POWER_ON and PANEL_POWER_ON flag definitions Imre Deak
2016-08-09 17:51 ` Ville Syrjälä
2016-08-09 11:34 ` [PATCH 3/6] drm/i915/lvds: Restore initial HW state during encoder enabling Imre Deak
2016-08-09 12:48 ` Ville Syrjälä
2016-08-09 14:40 ` Imre Deak
2016-08-09 14:55 ` Ville Syrjälä
2016-08-09 17:21 ` [PATCH v2 " Imre Deak
2016-08-09 17:46 ` Ville Syrjälä [this message]
2016-08-09 18:59 ` [PATCH v3 " Imre Deak
2016-08-09 11:34 ` [PATCH 4/6] drm/i915/dp: Restore PPS HW state from the encoder resume hook Imre Deak
2016-08-09 12:52 ` Ville Syrjälä
2016-08-09 15:15 ` Imre Deak
2016-08-09 17:21 ` [PATCH v2 " Imre Deak
2016-08-09 17:49 ` Ville Syrjälä
2016-08-09 11:34 ` [PATCH 5/6] drm/i915: Apply the PPS register unlock workaround more consistently Imre Deak
2016-08-09 13:01 ` Ville Syrjälä
2016-08-09 15:17 ` Imre Deak
2016-08-09 17:21 ` [PATCH v2 " Imre Deak
2016-08-09 17:46 ` Ville Syrjälä
2016-08-09 18:59 ` [PATCH v3 " Imre Deak
2016-08-09 11:34 ` [PATCH 6/6] drm/i915: Remove LVDS and PPS suspend time save/restore Imre Deak
2016-08-09 18:44 ` Ville Syrjälä
2016-08-09 12:05 ` ✓ Ro.CI.BAT: success for drm/i915: Clean up LVDS/PPS macros, suspend/resume logic Patchwork
2016-08-10 9:35 ` ✗ Ro.CI.BAT: failure for drm/i915: Clean up LVDS/PPS macros, suspend/resume logic (rev7) Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160809174654.GB4329@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=imre.deak@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox