aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/display/intel_dp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_dp.c216
1 files changed, 128 insertions, 88 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 9c174ff93398..2c1034578984 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -430,7 +430,7 @@ static int mtl_max_source_rate(struct intel_dp *intel_dp)
enum phy phy = intel_port_to_phy(i915, dig_port->base.port);
if (intel_is_c10phy(i915, phy))
- return intel_dp_is_edp(intel_dp) ? 675000 : 810000;
+ return 810000;
return 2000000;
}
@@ -823,11 +823,11 @@ u16 intel_dp_dsc_get_max_compressed_bpp(struct drm_i915_private *i915,
return bits_per_pixel;
}
-u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
+u8 intel_dp_dsc_get_slice_count(const struct intel_connector *connector,
int mode_clock, int mode_hdisplay,
bool bigjoiner)
{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
u8 min_slice_count, i;
int max_slice_width;
@@ -845,7 +845,7 @@ u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
if (mode_clock >= ((i915->display.cdclk.max_cdclk_freq * 85) / 100))
min_slice_count = max_t(u8, min_slice_count, 2);
- max_slice_width = drm_dp_dsc_sink_max_slice_width(intel_dp->dsc_dpcd);
+ max_slice_width = drm_dp_dsc_sink_max_slice_width(connector->dp.dsc_dpcd);
if (max_slice_width < DP_DSC_MIN_SLICE_WIDTH_VALUE) {
drm_dbg_kms(&i915->drm,
"Unsupported slice width %d by DP DSC Sink device\n",
@@ -862,7 +862,7 @@ u8 intel_dp_dsc_get_slice_count(struct intel_dp *intel_dp,
u8 test_slice_count = valid_dsc_slicecount[i] << bigjoiner;
if (test_slice_count >
- drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd, false))
+ drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd, false))
break;
/* big joiner needs small joiner to be enabled */
@@ -1205,7 +1205,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
intel_dp_mode_min_output_bpp(connector, mode));
if (HAS_DSC(dev_priv) &&
- drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd)) {
+ drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd)) {
enum intel_output_format sink_format, output_format;
int pipe_bpp;
@@ -1215,7 +1215,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
* TBD pass the connector BPC,
* for now U8_MAX so that max BPC on that platform would be picked
*/
- pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, U8_MAX);
+ pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, U8_MAX);
/*
* Output bpp is stored in 6.4 format so right shift by 4 to get the
@@ -1223,11 +1223,11 @@ intel_dp_mode_valid(struct drm_connector *_connector,
*/
if (intel_dp_is_edp(intel_dp)) {
dsc_max_compressed_bpp =
- drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd) >> 4;
+ drm_edp_dsc_sink_output_bpp(connector->dp.dsc_dpcd) >> 4;
dsc_slice_count =
- drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
+ drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd,
true);
- } else if (drm_dp_sink_supports_fec(intel_dp->fec_capable)) {
+ } else if (drm_dp_sink_supports_fec(connector->dp.fec_capability)) {
dsc_max_compressed_bpp =
intel_dp_dsc_get_max_compressed_bpp(dev_priv,
max_link_clock,
@@ -1238,7 +1238,7 @@ intel_dp_mode_valid(struct drm_connector *_connector,
output_format,
pipe_bpp, 64);
dsc_slice_count =
- intel_dp_dsc_get_slice_count(intel_dp,
+ intel_dp_dsc_get_slice_count(connector,
target_clock,
mode->hdisplay,
bigjoiner);
@@ -1370,20 +1370,21 @@ static bool intel_dp_source_supports_fec(struct intel_dp *intel_dp,
}
static bool intel_dp_supports_fec(struct intel_dp *intel_dp,
+ const struct intel_connector *connector,
const struct intel_crtc_state *pipe_config)
{
return intel_dp_source_supports_fec(intel_dp, pipe_config) &&
- drm_dp_sink_supports_fec(intel_dp->fec_capable);
+ drm_dp_sink_supports_fec(connector->dp.fec_capability);
}
-static bool intel_dp_supports_dsc(struct intel_dp *intel_dp,
+static bool intel_dp_supports_dsc(const struct intel_connector *connector,
const struct intel_crtc_state *crtc_state)
{
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP) && !crtc_state->fec_enable)
return false;
return intel_dsc_source_support(crtc_state) &&
- drm_dp_sink_supports_dsc(intel_dp->dsc_dpcd);
+ drm_dp_sink_supports_dsc(connector->dp.dsc_dpcd);
}
static int intel_dp_hdmi_compute_bpc(struct intel_dp *intel_dp,
@@ -1577,11 +1578,12 @@ u8 intel_dp_dsc_max_src_input_bpc(struct drm_i915_private *i915)
return 0;
}
-int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
+int intel_dp_dsc_compute_max_bpp(const struct intel_connector *connector,
+ u8 max_req_bpc)
{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
int i, num_bpc;
- u8 dsc_bpc[3] = {0};
+ u8 dsc_bpc[3] = {};
u8 dsc_max_bpc;
dsc_max_bpc = intel_dp_dsc_max_src_input_bpc(i915);
@@ -1591,7 +1593,7 @@ int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
dsc_max_bpc = min_t(u8, dsc_max_bpc, max_req_bpc);
- num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd,
+ num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd,
dsc_bpc);
for (i = 0; i < num_bpc; i++) {
if (dsc_max_bpc >= dsc_bpc[i])
@@ -1601,16 +1603,14 @@ int intel_dp_dsc_compute_max_bpp(struct intel_dp *intel_dp, u8 max_req_bpc)
return 0;
}
-static int intel_dp_source_dsc_version_minor(struct intel_dp *intel_dp)
+static int intel_dp_source_dsc_version_minor(struct drm_i915_private *i915)
{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
-
return DISPLAY_VER(i915) >= 14 ? 2 : 1;
}
-static int intel_dp_sink_dsc_version_minor(struct intel_dp *intel_dp)
+static int intel_dp_sink_dsc_version_minor(const u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
{
- return (intel_dp->dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] & DP_DSC_MINOR_MASK) >>
+ return (dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] & DP_DSC_MINOR_MASK) >>
DP_DSC_MINOR_SHIFT;
}
@@ -1636,11 +1636,10 @@ static int intel_dp_get_slice_height(int vactive)
return 2;
}
-static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
+static int intel_dp_dsc_compute_params(const struct intel_connector *connector,
struct intel_crtc_state *crtc_state)
{
- struct drm_i915_private *i915 = to_i915(encoder->base.dev);
- struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
u8 line_buf_depth;
int ret;
@@ -1661,17 +1660,17 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
return ret;
vdsc_cfg->dsc_version_major =
- (intel_dp->dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] &
+ (connector->dp.dsc_dpcd[DP_DSC_REV - DP_DSC_SUPPORT] &
DP_DSC_MAJOR_MASK) >> DP_DSC_MAJOR_SHIFT;
vdsc_cfg->dsc_version_minor =
- min(intel_dp_source_dsc_version_minor(intel_dp),
- intel_dp_sink_dsc_version_minor(intel_dp));
+ min(intel_dp_source_dsc_version_minor(i915),
+ intel_dp_sink_dsc_version_minor(connector->dp.dsc_dpcd));
if (vdsc_cfg->convert_rgb)
vdsc_cfg->convert_rgb =
- intel_dp->dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] &
+ connector->dp.dsc_dpcd[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT] &
DP_DSC_RGB;
- line_buf_depth = drm_dp_dsc_sink_line_buf_depth(intel_dp->dsc_dpcd);
+ line_buf_depth = drm_dp_dsc_sink_line_buf_depth(connector->dp.dsc_dpcd);
if (!line_buf_depth) {
drm_dbg_kms(&i915->drm,
"DSC Sink Line Buffer Depth invalid\n");
@@ -1686,15 +1685,16 @@ static int intel_dp_dsc_compute_params(struct intel_encoder *encoder,
DSC_1_1_MAX_LINEBUF_DEPTH_BITS : line_buf_depth;
vdsc_cfg->block_pred_enable =
- intel_dp->dsc_dpcd[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] &
+ connector->dp.dsc_dpcd[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] &
DP_DSC_BLK_PREDICTION_IS_SUPPORTED;
return drm_dsc_compute_rc_parameters(vdsc_cfg);
}
-static bool intel_dp_dsc_supports_format(struct intel_dp *intel_dp,
+static bool intel_dp_dsc_supports_format(const struct intel_connector *connector,
enum intel_output_format output_format)
{
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
u8 sink_dsc_format;
switch (output_format) {
@@ -1705,8 +1705,8 @@ static bool intel_dp_dsc_supports_format(struct intel_dp *intel_dp,
sink_dsc_format = DP_DSC_YCbCr444;
break;
case INTEL_OUTPUT_FORMAT_YCBCR420:
- if (min(intel_dp_source_dsc_version_minor(intel_dp),
- intel_dp_sink_dsc_version_minor(intel_dp)) < 2)
+ if (min(intel_dp_source_dsc_version_minor(i915),
+ intel_dp_sink_dsc_version_minor(connector->dp.dsc_dpcd)) < 2)
return false;
sink_dsc_format = DP_DSC_YCbCr420_Native;
break;
@@ -1714,7 +1714,7 @@ static bool intel_dp_dsc_supports_format(struct intel_dp *intel_dp,
return false;
}
- return drm_dp_dsc_sink_supports_format(intel_dp->dsc_dpcd, sink_dsc_format);
+ return drm_dp_dsc_sink_supports_format(connector->dp.dsc_dpcd, sink_dsc_format);
}
static bool is_bw_sufficient_for_dsc_config(u16 compressed_bpp, u32 link_clock,
@@ -1765,11 +1765,11 @@ static int dsc_compute_link_config(struct intel_dp *intel_dp,
}
static
-u16 intel_dp_dsc_max_sink_compressed_bppx16(struct intel_dp *intel_dp,
+u16 intel_dp_dsc_max_sink_compressed_bppx16(const struct intel_connector *connector,
struct intel_crtc_state *pipe_config,
int bpc)
{
- u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(intel_dp->dsc_dpcd);
+ u16 max_bppx16 = drm_edp_dsc_sink_output_bpp(connector->dp.dsc_dpcd);
if (max_bppx16)
return max_bppx16;
@@ -1808,11 +1808,11 @@ static int dsc_sink_min_compressed_bpp(struct intel_crtc_state *pipe_config)
return 0;
}
-static int dsc_sink_max_compressed_bpp(struct intel_dp *intel_dp,
+static int dsc_sink_max_compressed_bpp(const struct intel_connector *connector,
struct intel_crtc_state *pipe_config,
int bpc)
{
- return intel_dp_dsc_max_sink_compressed_bppx16(intel_dp,
+ return intel_dp_dsc_max_sink_compressed_bppx16(connector,
pipe_config, bpc) >> 4;
}
@@ -1911,6 +1911,7 @@ xelpd_dsc_compute_link_config(struct intel_dp *intel_dp,
}
static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
+ const struct intel_connector *connector,
struct intel_crtc_state *pipe_config,
struct link_config_limits *limits,
int pipe_bpp,
@@ -1928,7 +1929,7 @@ static int dsc_compute_compressed_bpp(struct intel_dp *intel_dp,
dsc_min_bpp = max(dsc_min_bpp, to_bpp_int_roundup(limits->link.min_bpp_x16));
dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
- dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, pipe_bpp / 3);
+ dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(connector, pipe_config, pipe_bpp / 3);
dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp;
dsc_joiner_max_bpp = get_max_compressed_bpp_with_joiner(i915, adjusted_mode->clock,
@@ -2000,17 +2001,19 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
int timeslots)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ const struct intel_connector *connector =
+ to_intel_connector(conn_state->connector);
u8 max_req_bpc = conn_state->max_requested_bpc;
u8 dsc_max_bpc, dsc_max_bpp;
u8 dsc_min_bpc, dsc_min_bpp;
- u8 dsc_bpc[3] = {0};
+ u8 dsc_bpc[3] = {};
int forced_bpp, pipe_bpp;
int num_bpc, i, ret;
forced_bpp = intel_dp_force_dsc_pipe_bpp(intel_dp, conn_state, limits);
if (forced_bpp) {
- ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
+ ret = dsc_compute_compressed_bpp(intel_dp, connector, pipe_config,
limits, forced_bpp, timeslots);
if (ret == 0) {
pipe_config->pipe_bpp = forced_bpp;
@@ -2032,14 +2035,14 @@ static int intel_dp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
* Get the maximum DSC bpc that will be supported by any valid
* link configuration and compressed bpp.
*/
- num_bpc = drm_dp_dsc_sink_supported_input_bpcs(intel_dp->dsc_dpcd, dsc_bpc);
+ num_bpc = drm_dp_dsc_sink_supported_input_bpcs(connector->dp.dsc_dpcd, dsc_bpc);
for (i = 0; i < num_bpc; i++) {
pipe_bpp = dsc_bpc[i] * 3;
if (pipe_bpp < dsc_min_bpp)
break;
if (pipe_bpp > dsc_max_bpp)
continue;
- ret = dsc_compute_compressed_bpp(intel_dp, pipe_config,
+ ret = dsc_compute_compressed_bpp(intel_dp, connector, pipe_config,
limits, pipe_bpp, timeslots);
if (ret == 0) {
pipe_config->pipe_bpp = pipe_bpp;
@@ -2056,6 +2059,8 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
struct link_config_limits *limits)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ struct intel_connector *connector =
+ to_intel_connector(conn_state->connector);
int pipe_bpp, forced_bpp;
int dsc_src_min_bpp, dsc_sink_min_bpp, dsc_min_bpp;
int dsc_src_max_bpp, dsc_sink_max_bpp, dsc_max_bpp;
@@ -2068,7 +2073,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
int max_bpc = min(limits->pipe.max_bpp / 3, (int)conn_state->max_requested_bpc);
/* For eDP use max bpp that can be supported with DSC. */
- pipe_bpp = intel_dp_dsc_compute_max_bpp(intel_dp, max_bpc);
+ pipe_bpp = intel_dp_dsc_compute_max_bpp(connector, max_bpc);
if (!is_dsc_pipe_bpp_sufficient(i915, conn_state, limits, pipe_bpp)) {
drm_dbg_kms(&i915->drm,
"Computed BPC is not in DSC BPC limits\n");
@@ -2084,7 +2089,7 @@ static int intel_edp_dsc_compute_pipe_bpp(struct intel_dp *intel_dp,
dsc_min_bpp = max(dsc_min_bpp, to_bpp_int_roundup(limits->link.min_bpp_x16));
dsc_src_max_bpp = dsc_src_max_compressed_bpp(intel_dp);
- dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(intel_dp, pipe_config, pipe_bpp / 3);
+ dsc_sink_max_bpp = dsc_sink_max_compressed_bpp(connector, pipe_config, pipe_bpp / 3);
dsc_max_bpp = dsc_sink_max_bpp ? min(dsc_sink_max_bpp, dsc_src_max_bpp) : dsc_src_max_bpp;
dsc_max_bpp = min(dsc_max_bpp, to_bpp_int(limits->link.max_bpp_x16));
@@ -2107,17 +2112,19 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
{
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+ const struct intel_connector *connector =
+ to_intel_connector(conn_state->connector);
const struct drm_display_mode *adjusted_mode =
&pipe_config->hw.adjusted_mode;
int ret;
pipe_config->fec_enable = !intel_dp_is_edp(intel_dp) &&
- intel_dp_supports_fec(intel_dp, pipe_config);
+ intel_dp_supports_fec(intel_dp, connector, pipe_config);
- if (!intel_dp_supports_dsc(intel_dp, pipe_config))
+ if (!intel_dp_supports_dsc(connector, pipe_config))
return -EINVAL;
- if (!intel_dp_dsc_supports_format(intel_dp, pipe_config->output_format))
+ if (!intel_dp_dsc_supports_format(connector, pipe_config->output_format))
return -EINVAL;
/*
@@ -2143,7 +2150,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
/* Calculate Slice count */
if (intel_dp_is_edp(intel_dp)) {
pipe_config->dsc.slice_count =
- drm_dp_dsc_sink_max_slice_count(intel_dp->dsc_dpcd,
+ drm_dp_dsc_sink_max_slice_count(connector->dp.dsc_dpcd,
true);
if (!pipe_config->dsc.slice_count) {
drm_dbg_kms(&dev_priv->drm, "Unsupported Slice Count %d\n",
@@ -2154,7 +2161,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
u8 dsc_dp_slice_count;
dsc_dp_slice_count =
- intel_dp_dsc_get_slice_count(intel_dp,
+ intel_dp_dsc_get_slice_count(connector,
adjusted_mode->crtc_clock,
adjusted_mode->crtc_hdisplay,
pipe_config->bigjoiner_pipes);
@@ -2174,7 +2181,7 @@ int intel_dp_dsc_compute_config(struct intel_dp *intel_dp,
if (pipe_config->bigjoiner_pipes || pipe_config->dsc.slice_count > 1)
pipe_config->dsc.dsc_split = true;
- ret = intel_dp_dsc_compute_params(&dig_port->base, pipe_config);
+ ret = intel_dp_dsc_compute_params(connector, pipe_config);
if (ret < 0) {
drm_dbg_kms(&dev_priv->drm,
"Cannot compute valid DSC parameters for Input Bpp = %d "
@@ -2933,7 +2940,7 @@ intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful)
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
u8 oui[] = { 0x00, 0xaa, 0x01 };
- u8 buf[3] = { 0 };
+ u8 buf[3] = {};
/*
* During driver init, we want to be careful and avoid changing the source OUI if it's
@@ -3467,43 +3474,57 @@ bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
return dprx & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED;
}
-static void intel_dp_get_dsc_sink_cap(struct intel_dp *intel_dp)
+static void intel_dp_read_dsc_dpcd(struct drm_dp_aux *aux,
+ u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
{
- struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+ if (drm_dp_dpcd_read(aux, DP_DSC_SUPPORT, dsc_dpcd,
+ DP_DSC_RECEIVER_CAP_SIZE) < 0) {
+ drm_err(aux->drm_dev,
+ "Failed to read DPCD register 0x%x\n",
+ DP_DSC_SUPPORT);
+ return;
+ }
+
+ drm_dbg_kms(aux->drm_dev, "DSC DPCD: %*ph\n",
+ DP_DSC_RECEIVER_CAP_SIZE,
+ dsc_dpcd);
+}
+
+void intel_dp_get_dsc_sink_cap(u8 dpcd_rev, struct intel_connector *connector)
+{
+ struct drm_i915_private *i915 = to_i915(connector->base.dev);
/*
* Clear the cached register set to avoid using stale values
* for the sinks that do not support DSC.
*/
- memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd));
+ memset(connector->dp.dsc_dpcd, 0, sizeof(connector->dp.dsc_dpcd));
/* Clear fec_capable to avoid using stale values */
- intel_dp->fec_capable = 0;
-
- /* Cache the DSC DPCD if eDP or DP rev >= 1.4 */
- if (intel_dp->dpcd[DP_DPCD_REV] >= 0x14 ||
- intel_dp->edp_dpcd[0] >= DP_EDP_14) {
- if (drm_dp_dpcd_read(&intel_dp->aux, DP_DSC_SUPPORT,
- intel_dp->dsc_dpcd,
- sizeof(intel_dp->dsc_dpcd)) < 0)
- drm_err(&i915->drm,
- "Failed to read DPCD register 0x%x\n",
- DP_DSC_SUPPORT);
+ connector->dp.fec_capability = 0;
- drm_dbg_kms(&i915->drm, "DSC DPCD: %*ph\n",
- (int)sizeof(intel_dp->dsc_dpcd),
- intel_dp->dsc_dpcd);
+ if (dpcd_rev < DP_DPCD_REV_14)
+ return;
- /* FEC is supported only on DP 1.4 */
- if (!intel_dp_is_edp(intel_dp) &&
- drm_dp_dpcd_readb(&intel_dp->aux, DP_FEC_CAPABILITY,
- &intel_dp->fec_capable) < 0)
- drm_err(&i915->drm,
- "Failed to read FEC DPCD register\n");
+ intel_dp_read_dsc_dpcd(connector->dp.dsc_decompression_aux,
+ connector->dp.dsc_dpcd);
- drm_dbg_kms(&i915->drm, "FEC CAPABILITY: %x\n",
- intel_dp->fec_capable);
+ if (drm_dp_dpcd_readb(connector->dp.dsc_decompression_aux, DP_FEC_CAPABILITY,
+ &connector->dp.fec_capability) < 0) {
+ drm_err(&i915->drm, "Failed to read FEC DPCD register\n");
+ return;
}
+
+ drm_dbg_kms(&i915->drm, "FEC CAPABILITY: %x\n",
+ connector->dp.fec_capability);
+}
+
+static void intel_edp_get_dsc_sink_cap(u8 edp_dpcd_rev, struct intel_connector *connector)
+{
+ if (edp_dpcd_rev < DP_EDP_14)
+ return;
+
+ intel_dp_read_dsc_dpcd(connector->dp.dsc_decompression_aux, connector->dp.dsc_dpcd);
}
static void intel_edp_mso_mode_fixup(struct intel_connector *connector,
@@ -3595,7 +3616,7 @@ static void intel_edp_mso_init(struct intel_dp *intel_dp)
}
static bool
-intel_edp_init_dpcd(struct intel_dp *intel_dp)
+intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector)
{
struct drm_i915_private *dev_priv =
to_i915(dp_to_dig_port(intel_dp)->base.base.dev);
@@ -3674,7 +3695,8 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp)
/* Read the eDP DSC DPCD registers */
if (HAS_DSC(dev_priv))
- intel_dp_get_dsc_sink_cap(intel_dp);
+ intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
+ connector);
/*
* If needed, program our source OUI so we can make various Intel-specific AUX services
@@ -5338,13 +5360,32 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
false);
}
+static void
+intel_dp_detect_dsc_caps(struct intel_dp *intel_dp, struct intel_connector *connector)
+{
+ struct drm_i915_private *i915 = dp_to_i915(intel_dp);
+
+ /* Read DP Sink DSC Cap DPCD regs for DP v1.4 */
+ if (!HAS_DSC(i915))
+ return;
+
+ if (intel_dp_is_edp(intel_dp))
+ intel_edp_get_dsc_sink_cap(intel_dp->edp_dpcd[0],
+ connector);
+ else
+ intel_dp_get_dsc_sink_cap(intel_dp->dpcd[DP_DPCD_REV],
+ connector);
+}
+
static int
intel_dp_detect(struct drm_connector *connector,
struct drm_modeset_acquire_ctx *ctx,
bool force)
{
struct drm_i915_private *dev_priv = to_i915(connector->dev);
- struct intel_dp *intel_dp = intel_attached_dp(to_intel_connector(connector));
+ struct intel_connector *intel_connector =
+ to_intel_connector(connector);
+ struct intel_dp *intel_dp = intel_attached_dp(intel_connector);
struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
struct intel_encoder *encoder = &dig_port->base;
enum drm_connector_status status;
@@ -5354,7 +5395,7 @@ intel_dp_detect(struct drm_connector *connector,
drm_WARN_ON(&dev_priv->drm,
!drm_modeset_is_locked(&dev_priv->drm.mode_config.connection_mutex));
- if (!INTEL_DISPLAY_ENABLED(dev_priv))
+ if (!intel_display_device_enabled(dev_priv))
return connector_status_disconnected;
/* Can't disconnect eDP */
@@ -5367,7 +5408,7 @@ intel_dp_detect(struct drm_connector *connector,
if (status == connector_status_disconnected) {
memset(&intel_dp->compliance, 0, sizeof(intel_dp->compliance));
- memset(intel_dp->dsc_dpcd, 0, sizeof(intel_dp->dsc_dpcd));
+ memset(intel_connector->dp.dsc_dpcd, 0, sizeof(intel_connector->dp.dsc_dpcd));
if (intel_dp->is_mst) {
drm_dbg_kms(&dev_priv->drm,
@@ -5382,9 +5423,7 @@ intel_dp_detect(struct drm_connector *connector,
goto out;
}
- /* Read DP Sink DSC Cap DPCD regs for DP v1.4 */
- if (HAS_DSC(dev_priv))
- intel_dp_get_dsc_sink_cap(intel_dp);
+ intel_dp_detect_dsc_caps(intel_dp, intel_connector);
intel_dp_configure_mst(intel_dp);
@@ -5980,7 +6019,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp,
intel_hpd_enable_detection(encoder);
/* Cache DPCD and EDID for edp. */
- has_dpcd = intel_edp_init_dpcd(intel_dp);
+ has_dpcd = intel_edp_init_dpcd(intel_dp, intel_connector);
if (!has_dpcd) {
/* if this fails, presume the device is a ghost */
@@ -6154,6 +6193,7 @@ intel_dp_init_connector(struct intel_digital_port *dig_port,
intel_dp->pps.active_pipe = vlv_active_pipe(intel_dp);
intel_dp_aux_init(intel_dp);
+ intel_connector->dp.dsc_decompression_aux = &intel_dp->aux;
drm_dbg_kms(&dev_priv->drm,
"Adding %s connector on [ENCODER:%d:%s]\n",