diff options
author | Jani Nikula <jani.nikula@intel.com> | 2018-12-04 12:19:26 +0200 |
---|---|---|
committer | Jani Nikula <jani.nikula@intel.com> | 2018-12-04 19:05:51 +0200 |
commit | 0716931a82b4d0e211d2ef66616ad7130107e455 (patch) | |
tree | 18edd3aa820771aab8091653f6d023395fef48b5 | |
parent | 5179749925933575a67f9d8f16d0cc204f98a29f (diff) |
drm/i915/icl: fix transcoder state readout
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@linux.intel.com>
Cc: Madhav Chauhan <madhav.chauhan@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20181204101926.17174-1-jani.nikula@intel.com
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a2584f977ab1..07c861884c70 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,26 @@ 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) { + 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. + * + * FIXME: This won't work for two separate DSI displays. + */ + enabled_panel_transcoders |= BIT(panel_transcoder); + if (enabled_panel_transcoders != BIT(panel_transcoder)) + continue; - 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 +9528,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; |