Skip to content

Commit 90780a6

Browse files
committed
drm/i915/dp: Sanitize DPCD revision check in intel_dp_get_dsc_sink_cap()
Check only the eDP or the DP specific DPCD revision depending on the sink type. Pass the corresponding revision to the function, which allows getting the DSC caps of a branch device (in an MST topology, which has its own DPCD and so DPCD revision). While at it use DP_DPCD_REV_14 instead of open coding it and for clarity add a separate function to read out the DSC capability on eDP. v2: - Use DP_DPCD_REV_14 instead of open coding it. (Stan) - Check EDP_DCPD_REV/DPCD_REV in a clearer way. (Ville) v3: - Fix the read-out for eDP in intel_dp_detect(). Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> (v1) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (v2) Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231011171606.2540078-1-imre.deak@intel.com
1 parent 34d8311 commit 90780a6

1 file changed

Lines changed: 55 additions & 26 deletions

File tree

drivers/gpu/drm/i915/display/intel_dp.c

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3467,7 +3467,23 @@ bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
34673467
return dprx & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED;
34683468
}
34693469

3470-
static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp)
3470+
static void intel_dp_read_dsc_dpcd(struct drm_dp_aux *aux,
3471+
u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
3472+
{
3473+
if (drm_dp_dpcd_read(aux, DP_DSC_SUPPORT, dsc_dpcd,
3474+
DP_DSC_RECEIVER_CAP_SIZE) < 0) {
3475+
drm_err(aux->drm_dev,
3476+
"Failed to read DPCD register 0x%x\n",
3477+
DP_DSC_SUPPORT);
3478+
return;
3479+
}
3480+
3481+
drm_dbg_kms(aux->drm_dev, "DSC DPCD: %*ph\n",
3482+
DP_DSC_RECEIVER_CAP_SIZE,
3483+
dsc_dpcd);
3484+
}
3485+
3486+
static void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_dp *intel_dp)
34713487
{
34723488
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
34733489

@@ -3480,30 +3496,27 @@ static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp)
34803496
/* Clear fec_capable to avoid using stale values */
34813497
intel_dp->fec_capable = 0;
34823498

3483-
/* Cache the DSC DPCD if eDP or DP rev >= 1.4 */
3484-
if (intel_dp->dpcd[DP_DPCD_REV] >= 0x14 ||
3485-
intel_dp->edp_dpcd[0] >= DP_EDP_14) {
3486-
if (drm_dp_dpcd_read(&intel_dp->aux, DP_DSC_SUPPORT,
3487-
intel_dp->dsc_dpcd,
3488-
sizeof(intel_dp->dsc_dpcd)) < 0)
3489-
drm_err(&i915->drm,
3490-
"Failed to read DPCD register 0x%x\n",
3491-
DP_DSC_SUPPORT);
3492-
3493-
drm_dbg_kms(&i915->drm, "DSC DPCD: %*ph\n",
3494-
(int)sizeof(intel_dp->dsc_dpcd),
3495-
intel_dp->dsc_dpcd);
3499+
if (dpcd_rev < DP_DPCD_REV_14)
3500+
return;
34963501

3497-
/* FEC is supported only on DP 1.4 */
3498-
if (!intel_dp_is_edp(intel_dp) &&
3499-
drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY,
3500-
&intel_dp->fec_capable) < 0)
3501-
drm_err(&i915->drm,
3502-
"Failed to read FEC DPCD register\n");
3502+
intel_dp_read_dsc_dpcd(&intel_dp->aux, intel_dp->dsc_dpcd);
35033503

3504-
drm_dbg_kms(&i915->drm, "FEC CAPABILITY: %x\n",
3505-
intel_dp->fec_capable);
3504+
if (drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY,
3505+
&intel_dp->fec_capable) < 0) {
3506+
drm_err(&i915->drm, "Failed to read FEC DPCD register\n");
3507+
return;
35063508
}
3509+
3510+
drm_dbg_kms(&i915->drm, "FEC CAPABILITY: %x\n",
3511+
intel_dp->fec_capable);
3512+
}
3513+
3514+
static void intel_edp_get_dsc_sink_cap(u8 edp_dpcd_rev, struct intel_dp *intel_dp)
3515+
{
3516+
if (edp_dpcd_rev < DP_EDP_14)
3517+
return;
3518+
3519+
intel_dp_read_dsc_dpcd(&intel_dp->aux, intel_dp->dsc_dpcd);
35073520
}
35083521

35093522
static void intel_edp_mso_mode_fixup(struct intel_connector *connector,
@@ -3674,7 +3687,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
36743687

36753688
/* Read the eDP DSC DPCD registers */
36763689
if (HAS_DSC(dev_priv))
3677-
intel_dp_get_dsc_sink_cap(intel_dp);
3690+
intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
3691+
intel_dp);
36783692

36793693
/*
36803694
* If needed, program our source OUI so we can make various Intel-specific AUX services
@@ -5342,6 +5356,23 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
53425356
false);
53435357
}
53445358

5359+
static void
5360+
intel_dp_detect_dsc_caps(struct intel_dp *intel_dp)
5361+
{
5362+
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
5363+
5364+
/* Read DP Sink DSC Cap DPCD regs for DP v1.4 */
5365+
if (!HAS_DSC(i915))
5366+
return;
5367+
5368+
if (intel_dp_is_edp(intel_dp))
5369+
intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
5370+
intel_dp);
5371+
else
5372+
intel_dp_get_dsc_sink_cap(intel_dp->dpcd[DP_DPCD_REV],
5373+
intel_dp);
5374+
}
5375+
53455376
static int
53465377
intel_dp_detect(struct drm_connector *connector,
53475378
struct drm_modeset_acquire_ctx *ctx,
@@ -5386,9 +5417,7 @@ intel_dp_detect(struct drm_connector *connector,
53865417
goto out;
53875418
}
53885419

5389-
/* Read DP Sink DSC Cap DPCD regs for DP v1.4 */
5390-
if (HAS_DSC(dev_priv))
5391-
intel_dp_get_dsc_sink_cap(intel_dp);
5420+
intel_dp_detect_dsc_caps(intel_dp);
53925421

53935422
intel_dp_configure_mst(intel_dp);
53945423

0 commit comments

Comments
 (0)