On Wed, Jun 12, 2013 at 05:55:52PM -0300, Rodrigo Vivi wrote: > Signed-off-by: Rodrigo Vivi <rodrigo.vivi at gmail.com> Shouldn't that be folded into an earlier patch? -Daniel > --- > drivers/gpu/drm/i915/intel_dp.c | 169 +++++++++++++++++++++------------------- > 1 file changed, 87 insertions(+), 82 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c > index a7f3bd1..c5ea419 100644 > --- a/drivers/gpu/drm/i915/intel_dp.c > +++ b/drivers/gpu/drm/i915/intel_dp.c > @@ -1362,7 +1362,79 @@ static bool intel_edp_is_psr_enabled(struct drm_device *dev) > return I915_READ(EDP_PSR_CTL) & EDP_PSR_ENABLE; > } > > -static void intel_edp_psr_enable_src(struct intel_dp *intel_dp) > + > +void intel_edp_psr_write_vsc(struct intel_dp* intel_dp, > + struct edp_vsc_psr *vsc_psr) > +{ > + struct drm_device *dev = intel_dp_to_dev(intel_dp); > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > + struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); > + > + u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config.cpu_transcoder); > + u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config.cpu_transcoder); > + uint32_t *data = (uint32_t *) vsc_psr; > + unsigned int i; > + u32 val = I915_READ(ctl_reg); > + > + /* As per eDP spec, wait for vblank to send SDP VSC packet */ > + intel_wait_for_vblank(dev, crtc->pipe); > + > + /* As per BSPec (Pipe Video Data Island Packet), besides wait for > + vsync we need to disable the video DIP being updated before program > + video DIP data buffer registers for DIP being updated.*/ > + I915_WRITE(ctl_reg, val & ~VIDEO_DIP_ENABLE_VSC_HSW); > + POSTING_READ(ctl_reg); > + > + for (i = 0; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) { > + if (i < sizeof(struct edp_vsc_psr)) > + I915_WRITE(data_reg + i, *data++); > + else > + I915_WRITE(data_reg + i, 0); > + } > + > + I915_WRITE(ctl_reg, val | VIDEO_DIP_ENABLE_VSC_HSW); > + POSTING_READ(ctl_reg); > +} > + > +static void intel_edp_psr_enable_sink(struct intel_dp *intel_dp) > +{ > + struct drm_device *dev = intel_dp_to_dev(intel_dp); > + struct drm_i915_private *dev_priv = dev->dev_private; > + struct edp_vsc_psr psr_vsc; > + uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp); > + int precharge = 0x3; > + int msg_size = 5; /* Header(4) + Message(1) */ > + > + /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ > + memset(&psr_vsc, 0, sizeof(psr_vsc)); > + psr_vsc.sdp_header.HB0 = 0; > + psr_vsc.sdp_header.HB1 = 0x7; > + psr_vsc.sdp_header.HB2 = 0x2; > + psr_vsc.sdp_header.HB3 = 0x8; > + intel_edp_psr_write_vsc(intel_dp, &psr_vsc); > + > + /* Enable PSR in sink */ > + if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) > + intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, > + DP_PSR_ENABLE & > + ~DP_PSR_MAIN_LINK_ACTIVE); > + else > + intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, > + DP_PSR_ENABLE | > + DP_PSR_MAIN_LINK_ACTIVE); > + > + /* Setup AUX registers */ > + I915_WRITE(EDP_PSR_AUX_DATA1, EDP_PSR_DPCD_COMMAND); > + I915_WRITE(EDP_PSR_AUX_DATA2, EDP_PSR_DPCD_NORMAL_OPERATION); > + I915_WRITE(EDP_PSR_AUX_CTL, > + DP_AUX_CH_CTL_TIME_OUT_400us | > + (msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | > + (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | > + (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); > +} > + > +static void intel_edp_psr_enable_source(struct intel_dp *intel_dp) > { > struct drm_device *dev = intel_dp_to_dev(intel_dp); > struct drm_i915_private *dev_priv = dev->dev_private; > @@ -1415,44 +1487,29 @@ static void intel_edp_psr_enable_src(struct intel_dp *intel_dp) > }; > } > > + /* Avoid continuous PSR exit by masking memup and hpd */ > + I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP | > + EDP_PSR_DEBUG_MASK_HPD); > + > + /* Disable unused interrupts */ > + I915_WRITE(GEN6_PMINTRMSK, GEN6_PM_RP_UP_EI_EXPIRED | > + GEN6_PM_RP_DOWN_EI_EXPIRED); > + > + > I915_WRITE(EDP_PSR_CTL, val | > EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES | > max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT | > EDP_PSR_ENABLE); > } > > -void intel_edp_psr_write_vsc(struct intel_dp* intel_dp, > - struct edp_vsc_psr *vsc_psr) > +static void intel_edp_psr_do_enable(struct intel_dp* intel_dp) > { > - struct drm_device *dev = intel_dp_to_dev(intel_dp); > - struct drm_i915_private *dev_priv = dev->dev_private; > - struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); > - struct intel_crtc *crtc = to_intel_crtc(dig_port->base.base.crtc); > - > - u32 ctl_reg = HSW_TVIDEO_DIP_CTL(crtc->config.cpu_transcoder); > - u32 data_reg = HSW_TVIDEO_DIP_VSC_DATA(crtc->config.cpu_transcoder); > - uint32_t *data = (uint32_t *) vsc_psr; > - unsigned int i; > - u32 val = I915_READ(ctl_reg); > - > - /* As per eDP spec, wait for vblank to send SDP VSC packet */ > - intel_wait_for_vblank(dev, crtc->pipe); > - > - /* As per BSPec (Pipe Video Data Island Packet), besides wait for > - vsync we need to disable the video DIP being updated before program > - video DIP data buffer registers for DIP being updated.*/ > - I915_WRITE(ctl_reg, val & ~VIDEO_DIP_ENABLE_VSC_HSW); > - POSTING_READ(ctl_reg); > > - for (i = 0; i < VIDEO_DIP_VSC_DATA_SIZE; i += 4) { > - if (i < sizeof(struct edp_vsc_psr)) > - I915_WRITE(data_reg + i, *data++); > - else > - I915_WRITE(data_reg + i, 0); > - } > + /* Enable PSR on the panel */ > + intel_edp_psr_enable_sink(intel_dp); > > - I915_WRITE(ctl_reg, val | VIDEO_DIP_ENABLE_VSC_HSW); > - POSTING_READ(ctl_reg); > + /* Enable PSR on the host */ > + intel_edp_psr_enable_source(intel_dp); > } > > static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) > @@ -1526,58 +1583,6 @@ static bool intel_edp_psr_match_conditions(struct intel_dp *intel_dp) > return true; > } > > -void intel_edp_psr_do_enable(struct intel_dp* intel_dp) > -{ > - struct drm_device *dev = intel_dp_to_dev(intel_dp); > - struct drm_i915_private *dev_priv = dev->dev_private; > - struct edp_vsc_psr psr_vsc; > - uint32_t aux_clock_divider = get_aux_clock_divider(intel_dp); > - int precharge = 0x3; > - int msg_size = 5; /* Header(4) + Message(1) */ > - > - if (!intel_edp_psr_match_conditions(intel_dp) || > - intel_edp_is_psr_enabled(dev)) > - return; > - > - /* Prepare VSC packet as per EDP 1.3 spec, Table 3.10 */ > - memset(&psr_vsc, 0, sizeof(psr_vsc)); > - psr_vsc.sdp_header.HB0 = 0; > - psr_vsc.sdp_header.HB1 = 0x7; > - psr_vsc.sdp_header.HB2 = 0x2; > - psr_vsc.sdp_header.HB3 = 0x8; > - intel_edp_psr_write_vsc(intel_dp, &psr_vsc); > - > - /* Enable PSR in sink */ > - if (intel_dp->psr_dpcd[1] & DP_PSR_NO_TRAIN_ON_EXIT) > - intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, > - DP_PSR_ENABLE & > - ~DP_PSR_MAIN_LINK_ACTIVE); > - else > - intel_dp_aux_native_write_1(intel_dp, DP_PSR_EN_CFG, > - DP_PSR_ENABLE | > - DP_PSR_MAIN_LINK_ACTIVE); > - > - /* Setup AUX registers */ > - I915_WRITE(EDP_PSR_AUX_DATA1, EDP_PSR_DPCD_COMMAND); > - I915_WRITE(EDP_PSR_AUX_DATA2, EDP_PSR_DPCD_NORMAL_OPERATION); > - I915_WRITE(EDP_PSR_AUX_CTL, > - DP_AUX_CH_CTL_TIME_OUT_400us | > - (msg_size << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | > - (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | > - (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT)); > - > - /* Avoid continuous PSR exit by masking memup and hpd */ > - I915_WRITE(EDP_PSR_DEBUG_CTL, EDP_PSR_DEBUG_MASK_MEMUP | > - EDP_PSR_DEBUG_MASK_HPD); > - > - /* Disable unused interrupts */ > - I915_WRITE(GEN6_PMINTRMSK, GEN6_PM_RP_UP_EI_EXPIRED | > - GEN6_PM_RP_DOWN_EI_EXPIRED); > - > - /* Enable PSR on the host */ > - intel_edp_psr_enable_src(intel_dp); > -} > - > void intel_edp_psr_enable(struct intel_dp* intel_dp) > { > struct drm_device *dev = intel_dp_to_dev(intel_dp); > -- > 1.7.11.7 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch