Skip to content

Commit 7389829

Browse files
committed
drm/i915/dp: Store DSC DPCD capabilities in the connector
In an MST topology the DSC capabilities are specific to each connector, retrieved either from the sink if it decompresses the stream, or from a branch device between the source and the sink in case this branch device does the decompression. Accordingly each connector needs to cache its own DSC DPCD and FEC capabilities, along with the AUX device through which the decompression can be enabled. This patch prepares for that by storing the capabilities and the DSC AUX device in the connector, for now these just matching the version stored in intel_dp. The follow-up patches will convert all users to look up these in the connector instead of intel_dp, after which the intel_dp copies are removed. v2: - Rebased on intel_edp_get_dsc_sink_cap() addition in previous patch. v3: - Rebased on read-out fix for eDP in previous patch. Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> (v1) Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20231011171606.2540078-2-imre.deak@intel.com
1 parent 90780a6 commit 7389829

2 files changed

Lines changed: 47 additions & 17 deletions

File tree

drivers/gpu/drm/i915/display/intel_display_types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,12 @@ struct intel_connector {
620620

621621
struct intel_dp *mst_port;
622622

623+
struct {
624+
struct drm_dp_aux *dsc_decompression_aux;
625+
u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE];
626+
u8 fec_capability;
627+
} dp;
628+
623629
/* Work struct to schedule a uevent on link train failure */
624630
struct work_struct modeset_retry_work;
625631

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

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3483,40 +3483,55 @@ static void intel_dp_read_dsc_dpcd(struct drm_dp_aux *aux,
34833483
dsc_dpcd);
34843484
}
34853485

3486-
static void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_dp *intel_dp)
3486+
static void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_dp *intel_dp,
3487+
struct intel_connector *connector)
34873488
{
34883489
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
34893490

34903491
/*
34913492
* Clear the cached register set to avoid using stale values
34923493
* for the sinks that do not support DSC.
34933494
*/
3494-
memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd));
3495+
memset(connector->dp.dsc_dpcd, 0, sizeof(connector->dp.dsc_dpcd));
34953496

34963497
/* Clear fec_capable to avoid using stale values */
3497-
intel_dp->fec_capable = 0;
3498+
connector->dp.fec_capability = 0;
34983499

34993500
if (dpcd_rev < DP_DPCD_REV_14)
35003501
return;
35013502

3502-
intel_dp_read_dsc_dpcd(&intel_dp->aux, intel_dp->dsc_dpcd);
3503+
intel_dp_read_dsc_dpcd(connector->dp.dsc_decompression_aux,
3504+
connector->dp.dsc_dpcd);
35033505

3504-
if (drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY,
3505-
&intel_dp->fec_capable) < 0) {
3506+
if (drm_dp_dpcd_readb(connector->dp.dsc_decompression_aux, DP_FEC_CAPABILITY,
3507+
&connector->dp.fec_capability) < 0) {
35063508
drm_err(&i915->drm, "Failed to read FEC DPCD register\n");
35073509
return;
35083510
}
35093511

35103512
drm_dbg_kms(&i915->drm, "FEC CAPABILITY: %x\n",
3511-
intel_dp->fec_capable);
3513+
connector->dp.fec_capability);
3514+
3515+
/*
3516+
* TODO: remove the following intel_dp copies once all users
3517+
* are converted to look up DSC DPCD/FEC capability via the
3518+
* connector.
3519+
*/
3520+
memcpy(intel_dp->dsc_dpcd, connector->dp.dsc_dpcd,
3521+
sizeof(intel_dp->dsc_dpcd));
3522+
intel_dp->fec_capable = connector->dp.fec_capability;
35123523
}
35133524

3514-
static void intel_edp_get_dsc_sink_cap(u8 edp_dpcd_rev, struct intel_dp *intel_dp)
3525+
static void intel_edp_get_dsc_sink_cap(u8 edp_dpcd_rev, struct intel_dp *intel_dp,
3526+
struct intel_connector *connector)
35153527
{
35163528
if (edp_dpcd_rev < DP_EDP_14)
35173529
return;
35183530

3519-
intel_dp_read_dsc_dpcd(&intel_dp->aux, intel_dp->dsc_dpcd);
3531+
intel_dp_read_dsc_dpcd(connector->dp.dsc_decompression_aux, connector->dp.dsc_dpcd);
3532+
3533+
memcpy(intel_dp->dsc_dpcd, connector->dp.dsc_dpcd,
3534+
sizeof(intel_dp->dsc_dpcd));
35203535
}
35213536

35223537
static void intel_edp_mso_mode_fixup(struct intel_connector *connector,
@@ -3608,7 +3623,7 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp)
36083623
}
36093624

36103625
static bool
3611-
intel_edp_init_dpcd(struct intel_dp *intel_dp)
3626+
intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector)
36123627
{
36133628
struct drm_i915_private *dev_priv =
36143629
to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
@@ -3688,7 +3703,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
36883703
/* Read the eDP DSC DPCD registers */
36893704
if (HAS_DSC(dev_priv))
36903705
intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
3691-
intel_dp);
3706+
intel_dp,
3707+
connector);
36923708

36933709
/*
36943710
* If needed, program our source OUI so we can make various Intel-specific AUX services
@@ -5357,7 +5373,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
53575373
}
53585374

53595375
static void
5360-
intel_dp_detect_dsc_caps(struct intel_dp *intel_dp)
5376+
intel_dp_detect_dsc_caps(struct intel_dp *intel_dp, struct intel_connector *connector)
53615377
{
53625378
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
53635379

@@ -5367,10 +5383,10 @@ intel_dp_detect_dsc_caps(struct intel_dp *intel_dp)
53675383

53685384
if (intel_dp_is_edp(intel_dp))
53695385
intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
5370-
intel_dp);
5386+
intel_dp, connector);
53715387
else
53725388
intel_dp_get_dsc_sink_cap(intel_dp->dpcd[DP_DPCD_REV],
5373-
intel_dp);
5389+
intel_dp, connector);
53745390
}
53755391

53765392
static int
@@ -5379,7 +5395,9 @@ intel_dp_detect(struct drm_connector *connector,
53795395
bool force)
53805396
{
53815397
struct drm_i915_private *dev_priv = to_i915(connector->dev);
5382-
struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
5398+
struct intel_connector *intel_connector =
5399+
to_intel_connector(connector);
5400+
struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
53835401
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
53845402
struct intel_encoder *encoder = &dig_port->base;
53855403
enum drm_connector_status status;
@@ -5402,7 +5420,12 @@ intel_dp_detect(struct drm_connector *connector,
54025420

54035421
if (status == connector_status_disconnected) {
54045422
memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
5423+
/*
5424+
* TODO: Remove clearing the DPCD in intel_dp, once all
5425+
* user are converted to using the DPCD in connector.
5426+
*/
54055427
memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd));
5428+
memset(intel_connector->dp.dsc_dpcd, 0, sizeof(intel_connector->dp.dsc_dpcd));
54065429

54075430
if (intel_dp->is_mst) {
54085431
drm_dbg_kms(&dev_priv->drm,
@@ -5417,7 +5440,7 @@ intel_dp_detect(struct drm_connector *connector,
54175440
goto out;
54185441
}
54195442

5420-
intel_dp_detect_dsc_caps(intel_dp);
5443+
intel_dp_detect_dsc_caps(intel_dp, intel_connector);
54215444

54225445
intel_dp_configure_mst(intel_dp);
54235446

@@ -6002,7 +6025,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
60026025
intel_hpd_enable_detection(encoder);
60036026

60046027
/* Cache DPCD and EDID for edp. */
6005-
has_dpcd = intel_edp_init_dpcd(intel_dp);
6028+
has_dpcd = intel_edp_init_dpcd(intel_dp, intel_connector);
60066029

60076030
if (!has_dpcd) {
60086031
/* if this fails, presume the device is a ghost */
@@ -6176,6 +6199,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
61766199
intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
61776200

61786201
intel_dp_aux_init(intel_dp);
6202+
intel_connector->dp.dsc_decompression_aux = &intel_dp->aux;
61796203

61806204
drm_dbg_kms(&dev_priv->drm,
61816205
"Adding %s connector on [ENCODER:%d:%s]\n",

0 commit comments

Comments
 (0)