From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jesse Barnes Subject: [PATCH 1/3] drm/i915: add PWM and BLC assertion checks Date: Mon, 31 Mar 2014 11:13:55 -0700 Message-ID: <1396289637-1013-1-git-send-email-jbarnes@virtuousgeek.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from gproxy4-pub.mail.unifiedlayer.com (gproxy4-pub.mail.unifiedlayer.com [69.89.23.142]) by gabe.freedesktop.org (Postfix) with SMTP id D3ADD6E3D2 for ; Mon, 31 Mar 2014 11:14:11 -0700 (PDT) Received: from [67.161.37.189] (port=56306 helo=localhost.localdomain) by box514.bluehost.com with esmtpsa (TLSv1.2:CAMELLIA256-SHA:256) (Exim 4.82) (envelope-from ) id 1WUgih-00041t-RJ for intel-gfx@lists.freedesktop.org; Mon, 31 Mar 2014 12:14:03 -0600 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" To: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org To make sure we properly follow the enable/disable sequences. Signed-off-by: Jesse Barnes --- drivers/gpu/drm/i915/intel_dp.c | 62 ++++++++++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_panel.c | 5 ++- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index bf73771..b6f7087 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -301,6 +301,20 @@ static u32 _pp_stat_reg(struct intel_dp *intel_dp) return VLV_PIPE_PP_STATUS(vlv_power_sequencer_pipe(intel_dp)); } +static void assert_pwm(struct intel_connector *connector, + bool expected_state) +{ + bool state; + + state = intel_panel_get_backlight(connector); + + WARN(state != expected_state, "pwm state failure, expected %d, found " + "%d\n", expected_state, state); +} + +#define assert_pwm_enabled(c) assert_pwm((c), true) +#define assert_pwm_disabled(c) assert_pwm((c), false) + static bool edp_have_panel_power(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); @@ -884,6 +898,8 @@ static void intel_dp_mode_set(struct intel_encoder *encoder) struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); struct drm_display_mode *adjusted_mode = &crtc->config.adjusted_mode; + assert_pwm_disabled(intel_dp->attached_connector); + /* * There are four kinds of DP registers: * @@ -1167,6 +1183,23 @@ static void edp_panel_vdd_off(struct intel_dp *intel_dp, bool sync) } } +/* + * For this and the disable sequence below, Google for actual eDP LCD timing + * diagrams or check the eDP spec. Below is for reference on asserts and + * does not contain Tx values for delays between steps. + * + * For panel on, the sequence should be: + * - LCD power supply on (PP regs or VDD AUX) + * - eDP should display black at this point + * - HPD (if present) should go high + * - AUX channel becomes available + * - link training begins + * - LED backlight power on + * - LED PWM_EN goes high, duty cycle >min (PWM regs) + * - link training completes + * - LED_EN goes high (PP BLC_EN bit) + */ + void intel_edp_panel_on(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); @@ -1212,6 +1245,19 @@ void intel_edp_panel_on(struct intel_dp *intel_dp) } } +/* + * For panel off the sequence should be: + * - LED_EN goes low (BLC_EN in our PP regs) + * - LED PWM_EN goes low (PWM duty cycle 0 and PWM enable = 0) + * - eDP should display black video at this point + * - LED VCCS goes low (power for backlight) + * - DP link goes to idle or off + * - AUX goes down + * - HPD line (if present) drops to low + * - eDP black video stops + * - LCD power supply shuts down (PP regs and VDD AUX) + */ + void intel_edp_panel_off(struct intel_dp *intel_dp) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); @@ -1231,11 +1277,17 @@ void intel_edp_panel_off(struct intel_dp *intel_dp) WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); + /* By this time the PWM and BLC bits should be off already */ + assert_pwm_disabled(intel_dp->attached_connector); + pp = ironlake_get_pp_control(intel_dp); + + WARN(pp & EDP_BLC_ENABLE, + "backlight controller still on at panel off time\n"); + /* We need to switch off panel power _and_ force vdd, for otherwise some * panels get very unhappy and cease to work. */ - pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_FORCE_VDD | - EDP_BLC_ENABLE); + pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_FORCE_VDD); pp_ctrl_reg = _pp_ctrl_reg(intel_dp); @@ -1271,6 +1323,9 @@ void intel_edp_backlight_on(struct intel_dp *intel_dp) * allowing it to appear. */ wait_backlight_on(intel_dp); + + assert_pwm_enabled(intel_dp->attached_connector); + pp = ironlake_get_pp_control(intel_dp); pp |= EDP_BLC_ENABLE; @@ -1292,6 +1347,9 @@ void intel_edp_backlight_off(struct intel_dp *intel_dp) if (!is_edp(intel_dp)) return; + /* PWM must still be enabled here */ + assert_pwm_enabled(intel_dp->attached_connector); + intel_panel_disable_backlight(intel_dp->attached_connector); DRM_DEBUG_KMS("\n"); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 9002e77..0e91c40 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -861,6 +861,7 @@ void intel_gmch_panel_fitting(struct intel_crtc *crtc, int fitting_mode); void intel_panel_set_backlight(struct intel_connector *connector, u32 level, u32 max); +u32 intel_panel_get_backlight(struct intel_connector *connector); int intel_panel_setup_backlight(struct drm_connector *connector); void intel_panel_enable_backlight(struct intel_connector *connector); void intel_panel_disable_backlight(struct intel_connector *connector); diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index cb05840..21c5e6f 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -384,6 +384,9 @@ static u32 _vlv_get_backlight(struct drm_device *dev, enum pipe pipe) { struct drm_i915_private *dev_priv = dev->dev_private; + if (I915_READ(VLV_BLC_PWM_CTL2(pipe) & BLM_PWM_ENABLE)) + return 0; + return I915_READ(VLV_BLC_PWM_CTL(pipe)) & BACKLIGHT_DUTY_CYCLE_MASK; } @@ -395,7 +398,7 @@ static u32 vlv_get_backlight(struct intel_connector *connector) return _vlv_get_backlight(dev, pipe); } -static u32 intel_panel_get_backlight(struct intel_connector *connector) +u32 intel_panel_get_backlight(struct intel_connector *connector) { struct drm_device *dev = connector->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; -- 1.8.4.2