On Tue, Dec 04, 2018 at 12:19:26PM +0200, Jani Nikula wrote: > Commit 2ca711caeca2 ("drm/i915/icl: Consider DSI for getting transcoder > state") clobbers the previously read TRANS_DDI_FUNC_CTL_EDP register > contents with TRANS_DDI_FUNC_CTL_DSI0 contents. Fix the state readout, > and handle DSI 1 while at it. > > Use a bitmask for iterating and logging transcoders, because the allowed > combinations are a bit funky. > > Fixes: 2ca711caeca2 ("drm/i915/icl: Consider DSI for getting transcoder state") Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108928 > Cc: Ville Syrjala <ville.syrjala@xxxxxxxxxxxxxxx> > Cc: Madhav Chauhan <madhav.chauhan@xxxxxxxxx> > Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> > --- > drivers/gpu/drm/i915/intel_display.c | 48 ++++++++++++++++++++---------------- > 1 file changed, 27 insertions(+), 21 deletions(-) > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index a2584f977ab1..64b0ecd538fd 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -9476,13 +9476,18 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, > struct drm_device *dev = crtc->base.dev; > struct drm_i915_private *dev_priv = to_i915(dev); > enum intel_display_power_domain power_domain; > + unsigned long panel_transcoder_mask = BIT(TRANSCODER_EDP); > + unsigned long enabled_panel_transcoders = 0; > + enum transcoder panel_transcoder; > u32 tmp; > - bool is_dsi = false; > - bool is_edp = false; > + > + if (IS_ICELAKE(dev_priv)) > + panel_transcoder_mask |= > + BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1); > > /* > * The pipe->transcoder mapping is fixed with the exception of the eDP > - * transcoder handled below. > + * and DSI transcoders handled below. > */ > pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; > > @@ -9490,23 +9495,22 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, > * XXX: Do intel_display_power_get_if_enabled before reading this (for > * consistency and less surprising code; it's in always on power). > */ > - tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); > - if (tmp & TRANS_DDI_FUNC_ENABLE) > - is_edp = true; > + for_each_set_bit(panel_transcoder, &panel_transcoder_mask, 32) { nit: BITS_PER_LONG or I915_MAX_TRANSCODERS? > + enum pipe trans_pipe; > > - if (IS_ICELAKE(dev_priv)) { > - tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_DSI_0)); > - if (tmp & TRANS_DDI_FUNC_ENABLE) > - is_dsi = true; > - } > + tmp = I915_READ(TRANS_DDI_FUNC_CTL(panel_transcoder)); > + if (!(tmp & TRANS_DDI_FUNC_ENABLE)) > + continue; > > - WARN_ON(is_edp && is_dsi); > + /* Log all enabled ones, only use the first one */ > + enabled_panel_transcoders |= BIT(panel_transcoder); > + if (enabled_panel_transcoders != BIT(panel_transcoder)) > + continue; nit: As you explained for DSI dual mode both transcoders are needed and we don't support atm two separate DSI ports. A code comment about this would be nice. Maybe for the two DSI port case we should also warn below. With or without the nits: Reviewed-by: Imre Deak <imre.deak@xxxxxxxxx> > > - if (is_edp || is_dsi) { > - enum pipe trans_pipe; > switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { > default: > - WARN(1, "unknown pipe linked to edp transcoder\n"); > + WARN(1, "unknown pipe linked to transcoder %s\n", > + transcoder_name(panel_transcoder)); > /* fall through */ > case TRANS_DDI_EDP_INPUT_A_ONOFF: > case TRANS_DDI_EDP_INPUT_A_ON: > @@ -9520,14 +9524,16 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc, > break; > } > > - if (trans_pipe == crtc->pipe) { > - if (is_edp) > - pipe_config->cpu_transcoder = TRANSCODER_EDP; > - else if (is_dsi) > - pipe_config->cpu_transcoder = TRANSCODER_DSI_0; > - } > + if (trans_pipe == crtc->pipe) > + pipe_config->cpu_transcoder = panel_transcoder; > } > > + /* > + * Valid combos: none, eDP, DSI0, DSI1, DSI0+DSI1 > + */ > + WARN_ON((enabled_panel_transcoders & BIT(TRANSCODER_EDP)) && > + enabled_panel_transcoders != BIT(TRANSCODER_EDP)); > + > power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); > if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) > return false; > -- > 2.11.0 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > https://lists.freedesktop.org/mailman/listinfo/intel-gfx _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx