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;
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",
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 */
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;
* 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
*/
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,
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);
}
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,
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);
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])
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;
}
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;
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");
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) {
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;
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,
}
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;
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;
}
}
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,
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,
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;
* 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;
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;
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");
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));
{
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;
/*
/* 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",
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);
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 "
{
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
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,
}
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);
/* 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
{
struct drm_i915_private *i915 = dp_to_i915(intel_dp);
struct intel_connector *connector = intel_dp->attached_connector;
- const struct edid *edid;
-
- /* FIXME: Get rid of drm_edid_raw() */
- edid = drm_edid_raw(drm_edid);
intel_dp->dfp.max_bpc =
drm_dp_downstream_max_bpc(intel_dp->dpcd,
- intel_dp->downstream_ports, edid);
+ intel_dp->downstream_ports, drm_edid);
intel_dp->dfp.max_dotclock =
drm_dp_downstream_max_dotclock(intel_dp->dpcd,
intel_dp->dfp.min_tmds_clock =
drm_dp_downstream_min_tmds_clock(intel_dp->dpcd,
intel_dp->downstream_ports,
- edid);
+ drm_edid);
intel_dp->dfp.max_tmds_clock =
drm_dp_downstream_max_tmds_clock(intel_dp->dpcd,
intel_dp->downstream_ports,
- edid);
+ drm_edid);
intel_dp->dfp.pcon_max_frl_bw =
drm_dp_get_pcon_max_frl_bw(intel_dp->dpcd,
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;
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,
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);
return intel_modeset_synced_crtcs(state, conn);
}
-static void intel_dp_oob_hotplug_event(struct drm_connector *connector)
+static void intel_dp_oob_hotplug_event(struct drm_connector *connector,
+ enum drm_connector_status hpd_state)
{
struct intel_encoder *encoder = intel_attached_encoder(to_intel_connector(connector));
struct drm_i915_private *i915 = to_i915(connector->dev);
+ bool hpd_high = hpd_state == connector_status_connected;
+ unsigned int hpd_pin = encoder->hpd_pin;
+ bool need_work = false;
spin_lock_irq(&i915->irq_lock);
- i915->display.hotplug.event_bits |= BIT(encoder->hpd_pin);
+ if (hpd_high != test_bit(hpd_pin, &i915->display.hotplug.oob_hotplug_last_state)) {
+ i915->display.hotplug.event_bits |= BIT(hpd_pin);
+
+ __assign_bit(hpd_pin, &i915->display.hotplug.oob_hotplug_last_state, hpd_high);
+ need_work = true;
+ }
spin_unlock_irq(&i915->irq_lock);
- queue_delayed_work(i915->unordered_wq, &i915->display.hotplug.hotplug_work, 0);
+
+ if (need_work)
+ queue_delayed_work(i915->unordered_wq, &i915->display.hotplug.hotplug_work, 0);
}
static const struct drm_connector_funcs intel_dp_connector_funcs = {
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 */
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",