Re: [Intel-gfx] [RFC PATCH 3/3] drm/i915: add support for per-pipe power sequencing on vlv
On Tue, Sep 03, 2013 at 02:43:39PM +0300, Jani Nikula wrote: > VLV has per-pipe PP registers. Set up power sequencing on mode set. The > connector init time setup is problematic, since we don't have a pipe at > that time. Cook up something. > > Signed-off-by: Jani Nikula > --- > drivers/gpu/drm/i915/intel_dp.c | 139 > +++ > 1 file changed, 97 insertions(+), 42 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index 0ba72f1..95d67fc 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -237,24 +237,47 @@ intel_hrawclk(struct drm_device *dev) > } > } > > +static void > +intel_dp_init_panel_power_sequencer(struct drm_device *dev, > + struct intel_dp *intel_dp, > + struct edp_power_seq *out); > +static void > +intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, > + struct intel_dp *intel_dp, > + struct edp_power_seq *out); > + > +static u32 _pp_ctrl_reg(struct intel_dp *intel_dp) > +{ > + struct drm_device *dev = intel_dp_to_dev(intel_dp); > + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); > + int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe; > + > + return HAS_PCH_SPLIT(dev) ? PCH_PP_CONTROL : VLV_PIPE_PP_CONTROL(pipe); > +} > + > +static u32 _pp_stat_reg(struct intel_dp *intel_dp) > +{ > + struct drm_device *dev = intel_dp_to_dev(intel_dp); > + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); > + int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe; > + > + return HAS_PCH_SPLIT(dev) ? PCH_PP_STATUS : VLV_PIPE_PP_STATUS(pipe); > +} > + > static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp) > { > struct drm_device *dev = intel_dp_to_dev(intel_dp); > struct drm_i915_private *dev_priv = dev->dev_private; > - u32 pp_stat_reg; > > - pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; > - return (I915_READ(pp_stat_reg) & PP_ON) != 0; > + return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0; > } > > static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp) > { > struct drm_device *dev = intel_dp_to_dev(intel_dp); > struct drm_i915_private *dev_priv = dev->dev_private; > - u32 pp_ctrl_reg; > > - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; > - return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0; > + return (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0; > } > > static void > @@ -262,19 +285,15 @@ intel_dp_check_edp(struct intel_dp *intel_dp) > { > struct drm_device *dev = intel_dp_to_dev(intel_dp); > struct drm_i915_private *dev_priv = dev->dev_private; > - u32 pp_stat_reg, pp_ctrl_reg; > > if (!is_edp(intel_dp)) > return; > > - pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; > - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; > - > if (!ironlake_edp_have_panel_power(intel_dp) && > !ironlake_edp_have_panel_vdd(intel_dp)) { > WARN(1, "eDP powered off while attempting aux channel > communication.\n"); > DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n", > - I915_READ(pp_stat_reg), > - I915_READ(pp_ctrl_reg)); > + I915_READ(_pp_stat_reg(intel_dp)), > + I915_READ(_pp_ctrl_reg(intel_dp))); > } > } > > @@ -948,8 +967,8 @@ static void ironlake_wait_panel_status(struct intel_dp > *intel_dp, > struct drm_i915_private *dev_priv = dev->dev_private; > u32 pp_stat_reg, pp_ctrl_reg; > > - pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; > - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; > + pp_stat_reg = _pp_stat_reg(intel_dp); > + pp_ctrl_reg = _pp_ctrl_reg(intel_dp); > > DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", > mask, value, > @@ -991,11 +1010,8 @@ static u32 ironlake_get_pp_control(struct intel_dp > *intel_dp) > struct drm_device *dev = intel_dp_to_dev(intel_dp); > struct drm_i915_private *dev_priv = dev->dev_private; > u32 control; > - u32 pp_ctrl_reg; > - > - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; > - control = I915_READ(pp_ctrl_reg); > > + control = I915_READ(_pp_ctrl_reg(intel_dp)); > control &= ~PANEL_UNLOCK_MASK; > control |= PANEL_UNLOCK_REGS; > return control; > @@ -1028,8 +1044,8 @@ void ironlake_edp_panel_vdd_on(struct intel_dp > *intel_dp) > pp = ironlake_get_pp_control(intel_dp); > pp |= EDP_FORCE_VDD; > > - pp_stat_reg = IS_
[Intel-gfx] [RFC PATCH 3/3] drm/i915: add support for per-pipe power sequencing on vlv
VLV has per-pipe PP registers. Set up power sequencing on mode set. The connector init time setup is problematic, since we don't have a pipe at that time. Cook up something. Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/intel_dp.c | 139 +++ 1 file changed, 97 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0ba72f1..95d67fc 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -237,24 +237,47 @@ intel_hrawclk(struct drm_device *dev) } } +static void +intel_dp_init_panel_power_sequencer(struct drm_device *dev, + struct intel_dp *intel_dp, + struct edp_power_seq *out); +static void +intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, + struct intel_dp *intel_dp, + struct edp_power_seq *out); + +static u32 _pp_ctrl_reg(struct intel_dp *intel_dp) +{ + struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe; + + return HAS_PCH_SPLIT(dev) ? PCH_PP_CONTROL : VLV_PIPE_PP_CONTROL(pipe); +} + +static u32 _pp_stat_reg(struct intel_dp *intel_dp) +{ + struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + int pipe = to_intel_crtc(intel_dig_port->base.base.crtc)->pipe; + + return HAS_PCH_SPLIT(dev) ? PCH_PP_STATUS : VLV_PIPE_PP_STATUS(pipe); +} + static bool ironlake_edp_have_panel_power(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp_stat_reg; - pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; - return (I915_READ(pp_stat_reg) & PP_ON) != 0; + return (I915_READ(_pp_stat_reg(intel_dp)) & PP_ON) != 0; } static bool ironlake_edp_have_panel_vdd(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp_ctrl_reg; - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; - return (I915_READ(pp_ctrl_reg) & EDP_FORCE_VDD) != 0; + return (I915_READ(_pp_ctrl_reg(intel_dp)) & EDP_FORCE_VDD) != 0; } static void @@ -262,19 +285,15 @@ intel_dp_check_edp(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp_stat_reg, pp_ctrl_reg; if (!is_edp(intel_dp)) return; - pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; - if (!ironlake_edp_have_panel_power(intel_dp) && !ironlake_edp_have_panel_vdd(intel_dp)) { WARN(1, "eDP powered off while attempting aux channel communication.\n"); DRM_DEBUG_KMS("Status 0x%08x Control 0x%08x\n", - I915_READ(pp_stat_reg), - I915_READ(pp_ctrl_reg)); + I915_READ(_pp_stat_reg(intel_dp)), + I915_READ(_pp_ctrl_reg(intel_dp))); } } @@ -948,8 +967,8 @@ static void ironlake_wait_panel_status(struct intel_dp *intel_dp, struct drm_i915_private *dev_priv = dev->dev_private; u32 pp_stat_reg, pp_ctrl_reg; - pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; + pp_stat_reg = _pp_stat_reg(intel_dp); + pp_ctrl_reg = _pp_ctrl_reg(intel_dp); DRM_DEBUG_KMS("mask %08x value %08x status %08x control %08x\n", mask, value, @@ -991,11 +1010,8 @@ static u32 ironlake_get_pp_control(struct intel_dp *intel_dp) struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_i915_private *dev_priv = dev->dev_private; u32 control; - u32 pp_ctrl_reg; - - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; - control = I915_READ(pp_ctrl_reg); + control = I915_READ(_pp_ctrl_reg(intel_dp)); control &= ~PANEL_UNLOCK_MASK; control |= PANEL_UNLOCK_REGS; return control; @@ -1028,8 +1044,8 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp) pp = ironlake_get_pp_control(intel_dp); pp |= EDP_FORCE_VDD; - pp_stat_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_STATUS : PCH_PP_STATUS; - pp_ctrl_reg = IS_VALLEYVIEW(dev) ? PIPEA_PP_CONTROL : PCH_PP_CONTROL; + pp_stat_reg = _pp_stat_reg(intel_dp); + pp_ctr