aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJani Nikula <jani.nikula@intel.com>2018-12-04 05:19:26 -0500
committerJani Nikula <jani.nikula@intel.com>2018-12-04 12:05:51 -0500
commit0716931a82b4d0e211d2ef66616ad7130107e455 (patch)
tree18edd3aa820771aab8091653f6d023395fef48b5
parent5179749925933575a67f9d8f16d0cc204f98a29f (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.c52
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,
9476 struct drm_device *dev = crtc->base.dev; 9476 struct drm_device *dev = crtc->base.dev;
9477 struct drm_i915_private *dev_priv = to_i915(dev); 9477 struct drm_i915_private *dev_priv = to_i915(dev);
9478 enum intel_display_power_domain power_domain; 9478 enum intel_display_power_domain power_domain;
9479 unsigned long panel_transcoder_mask = BIT(TRANSCODER_EDP);
9480 unsigned long enabled_panel_transcoders = 0;
9481 enum transcoder panel_transcoder;
9479 u32 tmp; 9482 u32 tmp;
9480 bool is_dsi = false; 9483
9481 bool is_edp = false; 9484 if (IS_ICELAKE(dev_priv))
9485 panel_transcoder_mask |=
9486 BIT(TRANSCODER_DSI_0) | BIT(TRANSCODER_DSI_1);
9482 9487
9483 /* 9488 /*
9484 * The pipe->transcoder mapping is fixed with the exception of the eDP 9489 * The pipe->transcoder mapping is fixed with the exception of the eDP
9485 * transcoder handled below. 9490 * and DSI transcoders handled below.
9486 */ 9491 */
9487 pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe; 9492 pipe_config->cpu_transcoder = (enum transcoder) crtc->pipe;
9488 9493
@@ -9490,23 +9495,26 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
9490 * XXX: Do intel_display_power_get_if_enabled before reading this (for 9495 * XXX: Do intel_display_power_get_if_enabled before reading this (for
9491 * consistency and less surprising code; it's in always on power). 9496 * consistency and less surprising code; it's in always on power).
9492 */ 9497 */
9493 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); 9498 for_each_set_bit(panel_transcoder, &panel_transcoder_mask, 32) {
9494 if (tmp & TRANS_DDI_FUNC_ENABLE) 9499 enum pipe trans_pipe;
9495 is_edp = true;
9496 9500
9497 if (IS_ICELAKE(dev_priv)) { 9501 tmp = I915_READ(TRANS_DDI_FUNC_CTL(panel_transcoder));
9498 tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_DSI_0)); 9502 if (!(tmp & TRANS_DDI_FUNC_ENABLE))
9499 if (tmp & TRANS_DDI_FUNC_ENABLE) 9503 continue;
9500 is_dsi = true;
9501 }
9502 9504
9503 WARN_ON(is_edp && is_dsi); 9505 /*
9506 * Log all enabled ones, only use the first one.
9507 *
9508 * FIXME: This won't work for two separate DSI displays.
9509 */
9510 enabled_panel_transcoders |= BIT(panel_transcoder);
9511 if (enabled_panel_transcoders != BIT(panel_transcoder))
9512 continue;
9504 9513
9505 if (is_edp || is_dsi) {
9506 enum pipe trans_pipe;
9507 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { 9514 switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
9508 default: 9515 default:
9509 WARN(1, "unknown pipe linked to edp transcoder\n"); 9516 WARN(1, "unknown pipe linked to transcoder %s\n",
9517 transcoder_name(panel_transcoder));
9510 /* fall through */ 9518 /* fall through */
9511 case TRANS_DDI_EDP_INPUT_A_ONOFF: 9519 case TRANS_DDI_EDP_INPUT_A_ONOFF:
9512 case TRANS_DDI_EDP_INPUT_A_ON: 9520 case TRANS_DDI_EDP_INPUT_A_ON:
@@ -9520,14 +9528,16 @@ static bool hsw_get_transcoder_state(struct intel_crtc *crtc,
9520 break; 9528 break;
9521 } 9529 }
9522 9530
9523 if (trans_pipe == crtc->pipe) { 9531 if (trans_pipe == crtc->pipe)
9524 if (is_edp) 9532 pipe_config->cpu_transcoder = panel_transcoder;
9525 pipe_config->cpu_transcoder = TRANSCODER_EDP;
9526 else if (is_dsi)
9527 pipe_config->cpu_transcoder = TRANSCODER_DSI_0;
9528 }
9529 } 9533 }
9530 9534
9535 /*
9536 * Valid combos: none, eDP, DSI0, DSI1, DSI0+DSI1
9537 */
9538 WARN_ON((enabled_panel_transcoders & BIT(TRANSCODER_EDP)) &&
9539 enabled_panel_transcoders != BIT(TRANSCODER_EDP));
9540
9531 power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder); 9541 power_domain = POWER_DOMAIN_TRANSCODER(pipe_config->cpu_transcoder);
9532 if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) 9542 if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
9533 return false; 9543 return false;