Commit 7c4631ff authored by Imre Deak's avatar Imre Deak

drm/i915/dp: Enable DSC via the connector decompression AUX

Enable DSC using the DSC AUX device stored for this purpose in the
connector. For clarity add separate functions to enable/disable the
decompression, since these sequences will diverge more in follow-up
patches that also enable/disable DSC passthrough and on MST do the
actual enabling/disabling only for the first/last user of the given
AUX device. As a preparation for the latter refcounting change, also
pass the atomic state to the functions.

While at it set/clear only the DP_DECOMPRESSION_EN flag in the
DP_DSC_ENABLE DPCD register, preserving the reserved register bits.

Besides preserving the reserved register bits, the behavior stays as
before, as DSC is still only enabled for the first MST stream (which a
follow-up patch changes, enabling it for all streams).

v2:
- Add a helper function setting/clearing the decompression flag,
  preserving the reserved register bits.
v3:
- Add separate functions to enable/disable decompression and pass the
  atomic state to these.
- Add DocBook for both functions.

Reviewed-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com> (v2)
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231030155843.2251023-24-imre.deak@intel.com
parent 503611c8
...@@ -2539,7 +2539,9 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -2539,7 +2539,9 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_dp_configure_protocol_converter(intel_dp, crtc_state); intel_dp_configure_protocol_converter(intel_dp, crtc_state);
if (!is_mst) if (!is_mst)
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); intel_dp_sink_enable_decompression(state,
to_intel_connector(conn_state->connector),
crtc_state);
/* /*
* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
...@@ -2692,7 +2694,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -2692,7 +2694,9 @@ static void tgl_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_dp_configure_protocol_converter(intel_dp, crtc_state); intel_dp_configure_protocol_converter(intel_dp, crtc_state);
if (!is_mst) if (!is_mst)
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, true); intel_dp_sink_enable_decompression(state,
to_intel_connector(conn_state->connector),
crtc_state);
/* /*
* DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit * DDI FEC: "anticipates enabling FEC encoding sets the FEC_READY bit
* in the FEC_CONFIGURATION register to 1 before initiating link * in the FEC_CONFIGURATION register to 1 before initiating link
...@@ -2773,8 +2777,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state, ...@@ -2773,8 +2777,9 @@ static void hsw_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_dp_set_power(intel_dp, DP_SET_POWER_D0); intel_dp_set_power(intel_dp, DP_SET_POWER_D0);
intel_dp_configure_protocol_converter(intel_dp, crtc_state); intel_dp_configure_protocol_converter(intel_dp, crtc_state);
if (!is_mst) if (!is_mst)
intel_dp_sink_set_decompression_state(intel_dp, crtc_state, intel_dp_sink_enable_decompression(state,
true); to_intel_connector(conn_state->connector),
crtc_state);
intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true); intel_dp_sink_set_fec_ready(intel_dp, crtc_state, true);
intel_dp_start_link_train(intel_dp, crtc_state); intel_dp_start_link_train(intel_dp, crtc_state);
if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) && if ((port != PORT_A || DISPLAY_VER(dev_priv) >= 9) &&
...@@ -3360,6 +3365,8 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state, ...@@ -3360,6 +3365,8 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state,
const struct drm_connector_state *old_conn_state) const struct drm_connector_state *old_conn_state)
{ {
struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
struct intel_connector *connector =
to_intel_connector(old_conn_state->connector);
intel_dp->link_trained = false; intel_dp->link_trained = false;
...@@ -3368,8 +3375,8 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state, ...@@ -3368,8 +3375,8 @@ static void intel_disable_ddi_dp(struct intel_atomic_state *state,
intel_psr_disable(intel_dp, old_crtc_state); intel_psr_disable(intel_dp, old_crtc_state);
intel_edp_backlight_off(old_conn_state); intel_edp_backlight_off(old_conn_state);
/* Disable the decompression in DP Sink */ /* Disable the decompression in DP Sink */
intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state, intel_dp_sink_disable_decompression(state,
false); connector, old_crtc_state);
/* Disable Ignore_MSA bit in DP Sink */ /* Disable Ignore_MSA bit in DP Sink */
intel_dp_sink_set_msa_timing_par_ignore_state(intel_dp, old_crtc_state, intel_dp_sink_set_msa_timing_par_ignore_state(intel_dp, old_crtc_state,
false); false);
......
...@@ -2937,24 +2937,94 @@ static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp) ...@@ -2937,24 +2937,94 @@ static bool downstream_hpd_needs_d0(struct intel_dp *intel_dp)
intel_dp->downstream_ports[0] & DP_DS_PORT_HPD; intel_dp->downstream_ports[0] & DP_DS_PORT_HPD;
} }
void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, static int
const struct intel_crtc_state *crtc_state, write_dsc_decompression_flag(struct drm_dp_aux *aux, u8 flag, bool set)
bool enable)
{ {
struct drm_i915_private *i915 = dp_to_i915(intel_dp); int err;
int ret; u8 val;
if (!crtc_state->dsc.compression_enable) err = drm_dp_dpcd_readb(aux, DP_DSC_ENABLE, &val);
return; if (err < 0)
return err;
ret = drm_dp_dpcd_writeb(&intel_dp->aux, DP_DSC_ENABLE, if (set)
enable ? DP_DECOMPRESSION_EN : 0); val |= flag;
if (ret < 0) else
val &= ~flag;
return drm_dp_dpcd_writeb(aux, DP_DSC_ENABLE, val);
}
static void
intel_dp_sink_set_dsc_decompression(struct intel_connector *connector,
bool enable)
{
struct drm_i915_private *i915 = to_i915(connector->base.dev);
if (write_dsc_decompression_flag(connector->dp.dsc_decompression_aux,
DP_DECOMPRESSION_EN, enable) < 0)
drm_dbg_kms(&i915->drm, drm_dbg_kms(&i915->drm,
"Failed to %s sink decompression state\n", "Failed to %s sink decompression state\n",
str_enable_disable(enable)); str_enable_disable(enable));
} }
/**
* intel_dp_sink_enable_decompression - Enable DSC decompression in sink/last branch device
* @state: atomic state
* @connector: connector to enable the decompression for
* @new_crtc_state: new state for the CRTC driving @connector
*
* Enable the DSC decompression if required in the %DP_DSC_ENABLE DPCD
* register of the appropriate sink/branch device. On SST this is always the
* sink device, whereas on MST based on each device's DSC capabilities it's
* either the last branch device (enabling decompression in it) or both the
* last branch device (enabling passthrough in it) and the sink device
* (enabling decompression in it).
*/
void intel_dp_sink_enable_decompression(struct intel_atomic_state *state,
struct intel_connector *connector,
const struct intel_crtc_state *new_crtc_state)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
if (!new_crtc_state->dsc.compression_enable)
return;
if (drm_WARN_ON(&i915->drm,
!connector->dp.dsc_decompression_aux))
return;
/* TODO: Enable passthrough in the MST last branch device if needed. */
intel_dp_sink_set_dsc_decompression(connector, true);
}
/**
* intel_dp_sink_disable_decompression - Disable DSC decompression in sink/last branch device
* @state: atomic state
* @connector: connector to disable the decompression for
* @old_crtc_state: old state for the CRTC driving @connector
*
* Disable the DSC decompression if required in the %DP_DSC_ENABLE DPCD
* register of the appropriate sink/branch device, corresponding to the
* sequence in intel_dp_sink_enable_decompression().
*/
void intel_dp_sink_disable_decompression(struct intel_atomic_state *state,
struct intel_connector *connector,
const struct intel_crtc_state *old_crtc_state)
{
struct drm_i915_private *i915 = to_i915(state->base.dev);
if (!old_crtc_state->dsc.compression_enable)
return;
if (drm_WARN_ON(&i915->drm,
!connector->dp.dsc_decompression_aux))
return;
intel_dp_sink_set_dsc_decompression(connector, false);
/* TODO: Disable passthrough in the MST last branch device if needed. */
}
static void static void
intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful) intel_edp_init_source_oui(struct intel_dp *intel_dp, bool careful)
{ {
......
...@@ -57,9 +57,12 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, ...@@ -57,9 +57,12 @@ int intel_dp_retrain_link(struct intel_encoder *encoder,
void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode); void intel_dp_set_power(struct intel_dp *intel_dp, u8 mode);
void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp, void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state); const struct intel_crtc_state *crtc_state);
void intel_dp_sink_set_decompression_state(struct intel_dp *intel_dp, void intel_dp_sink_enable_decompression(struct intel_atomic_state *state,
const struct intel_crtc_state *crtc_state, struct intel_connector *connector,
bool enable); const struct intel_crtc_state *new_crtc_state);
void intel_dp_sink_disable_decompression(struct intel_atomic_state *state,
struct intel_connector *connector,
const struct intel_crtc_state *old_crtc_state);
void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder); void intel_dp_encoder_suspend(struct intel_encoder *intel_encoder);
void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder); void intel_dp_encoder_shutdown(struct intel_encoder *intel_encoder);
void intel_dp_encoder_flush_work(struct drm_encoder *encoder); void intel_dp_encoder_flush_work(struct drm_encoder *encoder);
......
...@@ -782,7 +782,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state, ...@@ -782,7 +782,7 @@ static void intel_mst_disable_dp(struct intel_atomic_state *state,
* TODO: disable decompression for all streams/in any MST ports, not * TODO: disable decompression for all streams/in any MST ports, not
* only in the first downstream branch device. * only in the first downstream branch device.
*/ */
intel_dp_sink_set_decompression_state(intel_dp, old_crtc_state, false); intel_dp_sink_disable_decompression(state, connector, old_crtc_state);
} }
static void intel_mst_post_disable_dp(struct intel_atomic_state *state, static void intel_mst_post_disable_dp(struct intel_atomic_state *state,
...@@ -944,7 +944,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state, ...@@ -944,7 +944,7 @@ static void intel_mst_pre_enable_dp(struct intel_atomic_state *state,
* TODO: enable decompression for all streams/in any MST ports, not * TODO: enable decompression for all streams/in any MST ports, not
* only in the first downstream branch device. * only in the first downstream branch device.
*/ */
intel_dp_sink_set_decompression_state(intel_dp, pipe_config, true); intel_dp_sink_enable_decompression(state, connector, pipe_config);
dig_port->base.pre_enable(state, &dig_port->base, dig_port->base.pre_enable(state, &dig_port->base,
pipe_config, NULL); pipe_config, NULL);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment