mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-03-07 04:57:52 +07:00
drm/i915/ddi: Add more sanity check to the encoder HW readout
Check for reserved register field values and conflicting transcoder->port mappings (both MST and non-MST mappings or multiple SST mappings). This is also needed for the next patch to determine if a port is in MST mode during sanitization after HW readout. Cc: Paulo Zanoni <paulo.r.zanoni@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: José Roberto de Souza <jose.souza@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Antonio Argenziano <antonio.argenziano@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Clint Taylor <Clinton.A.Taylor@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181107200836.10191-1-imre.deak@intel.com
This commit is contained in:
parent
a1db9c54eb
commit
9199c322ec
@ -2005,24 +2005,24 @@ bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
|
||||
enum pipe *pipe)
|
||||
static void intel_ddi_get_encoder_pipes(struct intel_encoder *encoder,
|
||||
u8 *pipe_mask, bool *is_dp_mst)
|
||||
{
|
||||
struct drm_device *dev = encoder->base.dev;
|
||||
struct drm_i915_private *dev_priv = to_i915(dev);
|
||||
enum port port = encoder->port;
|
||||
enum pipe p;
|
||||
u32 tmp;
|
||||
bool ret;
|
||||
u8 mst_pipe_mask;
|
||||
|
||||
*pipe_mask = 0;
|
||||
*is_dp_mst = false;
|
||||
|
||||
if (!intel_display_power_get_if_enabled(dev_priv,
|
||||
encoder->power_domain))
|
||||
return false;
|
||||
|
||||
ret = false;
|
||||
return;
|
||||
|
||||
tmp = I915_READ(DDI_BUF_CTL(port));
|
||||
|
||||
if (!(tmp & DDI_BUF_CTL_ENABLE))
|
||||
goto out;
|
||||
|
||||
@ -2030,44 +2030,58 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
|
||||
tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP));
|
||||
|
||||
switch (tmp & TRANS_DDI_EDP_INPUT_MASK) {
|
||||
default:
|
||||
MISSING_CASE(tmp & TRANS_DDI_EDP_INPUT_MASK);
|
||||
/* fallthrough */
|
||||
case TRANS_DDI_EDP_INPUT_A_ON:
|
||||
case TRANS_DDI_EDP_INPUT_A_ONOFF:
|
||||
*pipe = PIPE_A;
|
||||
*pipe_mask = BIT(PIPE_A);
|
||||
break;
|
||||
case TRANS_DDI_EDP_INPUT_B_ONOFF:
|
||||
*pipe = PIPE_B;
|
||||
*pipe_mask = BIT(PIPE_B);
|
||||
break;
|
||||
case TRANS_DDI_EDP_INPUT_C_ONOFF:
|
||||
*pipe = PIPE_C;
|
||||
*pipe_mask = BIT(PIPE_C);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
mst_pipe_mask = 0;
|
||||
for_each_pipe(dev_priv, p) {
|
||||
enum transcoder cpu_transcoder = (enum transcoder) p;
|
||||
enum transcoder cpu_transcoder = (enum transcoder)p;
|
||||
|
||||
tmp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder));
|
||||
|
||||
if ((tmp & TRANS_DDI_PORT_MASK) == TRANS_DDI_SELECT_PORT(port)) {
|
||||
if ((tmp & TRANS_DDI_MODE_SELECT_MASK) ==
|
||||
TRANS_DDI_MODE_SELECT_DP_MST)
|
||||
goto out;
|
||||
if ((tmp & TRANS_DDI_PORT_MASK) != TRANS_DDI_SELECT_PORT(port))
|
||||
continue;
|
||||
|
||||
*pipe = p;
|
||||
ret = true;
|
||||
if ((tmp & TRANS_DDI_MODE_SELECT_MASK) ==
|
||||
TRANS_DDI_MODE_SELECT_DP_MST)
|
||||
mst_pipe_mask |= BIT(p);
|
||||
|
||||
goto out;
|
||||
}
|
||||
*pipe_mask |= BIT(p);
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port));
|
||||
if (!*pipe_mask)
|
||||
DRM_DEBUG_KMS("No pipe for ddi port %c found\n",
|
||||
port_name(port));
|
||||
|
||||
if (!mst_pipe_mask && hweight8(*pipe_mask) > 1) {
|
||||
DRM_DEBUG_KMS("Multiple pipes for non DP-MST port %c (pipe_mask %02x)\n",
|
||||
port_name(port), *pipe_mask);
|
||||
*pipe_mask = BIT(ffs(*pipe_mask) - 1);
|
||||
}
|
||||
|
||||
if (mst_pipe_mask && mst_pipe_mask != *pipe_mask)
|
||||
DRM_DEBUG_KMS("Conflicting MST and non-MST encoders for port %c (pipe_mask %02x mst_pipe_mask %02x)\n",
|
||||
port_name(port), *pipe_mask, mst_pipe_mask);
|
||||
else
|
||||
*is_dp_mst = mst_pipe_mask;
|
||||
|
||||
out:
|
||||
if (ret && IS_GEN9_LP(dev_priv)) {
|
||||
if (*pipe_mask && IS_GEN9_LP(dev_priv)) {
|
||||
tmp = I915_READ(BXT_PHY_CTL(port));
|
||||
if ((tmp & (BXT_PHY_CMNLANE_POWERDOWN_ACK |
|
||||
BXT_PHY_LANE_POWERDOWN_ACK |
|
||||
@ -2077,8 +2091,22 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
|
||||
}
|
||||
|
||||
intel_display_power_put(dev_priv, encoder->power_domain);
|
||||
}
|
||||
|
||||
return ret;
|
||||
bool intel_ddi_get_hw_state(struct intel_encoder *encoder,
|
||||
enum pipe *pipe)
|
||||
{
|
||||
u8 pipe_mask;
|
||||
bool is_mst;
|
||||
|
||||
intel_ddi_get_encoder_pipes(encoder, &pipe_mask, &is_mst);
|
||||
|
||||
if (is_mst || !pipe_mask)
|
||||
return false;
|
||||
|
||||
*pipe = ffs(pipe_mask) - 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline enum intel_display_power_domain
|
||||
|
Loading…
Reference in New Issue
Block a user