Commit cafac5a9 authored by Gwan-gyeong Mun's avatar Gwan-gyeong Mun Committed by Jani Nikula

drm/i915/dp: Add compute routine for DP PSR VSC SDP

In order to use a common VSC SDP Colorimetry calculating code on PSR,
it adds a compute routine for PSR VSC SDP.
As PSR routine can not use infoframes.vsc of crtc state, it also adds new
writing of DP SDPs (Secondary Data Packet) for PSR.
PSR routine has its own scenario and timings of writing a VSC SDP.

v3: Replace a structure name to drm_dp_vsc_sdp from intel_dp_vsc_sdp
v4: Use struct drm_device logging macros
v10: 1) Fix packing of VSC SDP where Pixel Encoding/Colorimetry Format is
        not supported.
     2) Change a checking of PSR state.
Signed-off-by: default avatarGwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Reviewed-by: default avatarUma Shankar <uma.shankar@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200514060732.3378396-14-gwan-gyeong.mun@intel.com
parent fa37a213
...@@ -2487,8 +2487,8 @@ static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp, ...@@ -2487,8 +2487,8 @@ static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
{ {
struct drm_dp_vsc_sdp *vsc = &crtc_state->infoframes.vsc; struct drm_dp_vsc_sdp *vsc = &crtc_state->infoframes.vsc;
/* When PSR is enabled, VSC SDP is handled by PSR routine */ /* When a crtc state has PSR, VSC SDP will be handled by PSR routine */
if (intel_psr_enabled(intel_dp)) if (crtc_state->has_psr)
return; return;
if (!intel_dp_needs_vsc_sdp(crtc_state, conn_state)) if (!intel_dp_needs_vsc_sdp(crtc_state, conn_state))
...@@ -2500,6 +2500,42 @@ static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp, ...@@ -2500,6 +2500,42 @@ static void intel_dp_compute_vsc_sdp(struct intel_dp *intel_dp,
&crtc_state->infoframes.vsc); &crtc_state->infoframes.vsc);
} }
void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state,
struct drm_dp_vsc_sdp *vsc)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
vsc->sdp_type = DP_SDP_VSC;
if (dev_priv->psr.psr2_enabled) {
if (dev_priv->psr.colorimetry_support &&
intel_dp_needs_vsc_sdp(crtc_state, conn_state)) {
/* [PSR2, +Colorimetry] */
intel_dp_compute_vsc_colorimetry(crtc_state, conn_state,
vsc);
} else {
/*
* [PSR2, -Colorimetry]
* Prepare VSC Header for SU as per eDP 1.4 spec, Table 6-11
* 3D stereo + PSR/PSR2 + Y-coordinate.
*/
vsc->revision = 0x4;
vsc->length = 0xe;
}
} else {
/*
* [PSR1]
* Prepare VSC Header for SU as per DP 1.4 spec, Table 2-118
* VSC SDP supporting 3D stereo + PSR (applies to eDP v1.3 or
* higher).
*/
vsc->revision = 0x2;
vsc->length = 0x8;
}
}
static void static void
intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp, intel_dp_compute_hdr_metadata_infoframe_sdp(struct intel_dp *intel_dp,
struct intel_crtc_state *crtc_state, struct intel_crtc_state *crtc_state,
...@@ -4791,6 +4827,13 @@ static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, ...@@ -4791,6 +4827,13 @@ static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */ sdp->sdp_header.HB2 = vsc->revision; /* Revision Number */
sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */ sdp->sdp_header.HB3 = vsc->length; /* Number of Valid Data Bytes */
/*
* Only revision 0x5 supports Pixel Encoding/Colorimetry Format as
* per DP 1.4a spec.
*/
if (vsc->revision != 0x5)
goto out;
/* VSC SDP Payload for DB16 through DB18 */ /* VSC SDP Payload for DB16 through DB18 */
/* Pixel Encoding and Colorimetry Formats */ /* Pixel Encoding and Colorimetry Formats */
sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */ sdp->db[16] = (vsc->pixelformat & 0xf) << 4; /* DB16[7:4] */
...@@ -4823,6 +4866,7 @@ static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc, ...@@ -4823,6 +4866,7 @@ static ssize_t intel_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
/* Content Type */ /* Content Type */
sdp->db[18] = vsc->content_type & 0x7; sdp->db[18] = vsc->content_type & 0x7;
out:
return length; return length;
} }
...@@ -4935,6 +4979,24 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder, ...@@ -4935,6 +4979,24 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder,
intel_dig_port->write_infoframe(encoder, crtc_state, type, &sdp, len); intel_dig_port->write_infoframe(encoder, crtc_state, type, &sdp, len);
} }
void intel_write_dp_vsc_sdp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
struct drm_dp_vsc_sdp *vsc)
{
struct intel_digital_port *intel_dig_port = enc_to_dig_port(encoder);
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
struct dp_sdp sdp = {};
ssize_t len;
len = intel_dp_vsc_sdp_pack(vsc, &sdp, sizeof(sdp));
if (drm_WARN_ON(&dev_priv->drm, len < 0))
return;
intel_dig_port->write_infoframe(encoder, crtc_state, DP_SDP_VSC,
&sdp, len);
}
void intel_dp_set_infoframes(struct intel_encoder *encoder, void intel_dp_set_infoframes(struct intel_encoder *encoder,
bool enable, bool enable,
const struct intel_crtc_state *crtc_state, const struct intel_crtc_state *crtc_state,
......
...@@ -16,6 +16,7 @@ struct drm_connector_state; ...@@ -16,6 +16,7 @@ struct drm_connector_state;
struct drm_encoder; struct drm_encoder;
struct drm_i915_private; struct drm_i915_private;
struct drm_modeset_acquire_ctx; struct drm_modeset_acquire_ctx;
struct drm_dp_vsc_sdp;
struct intel_connector; struct intel_connector;
struct intel_crtc_state; struct intel_crtc_state;
struct intel_digital_port; struct intel_digital_port;
...@@ -108,6 +109,13 @@ int intel_dp_link_required(int pixel_clock, int bpp); ...@@ -108,6 +109,13 @@ int intel_dp_link_required(int pixel_clock, int bpp);
int intel_dp_max_data_rate(int max_link_clock, int max_lanes); int intel_dp_max_data_rate(int max_link_clock, int max_lanes);
bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state, bool intel_dp_needs_vsc_sdp(const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state); const struct drm_connector_state *conn_state);
void intel_dp_compute_psr_vsc_sdp(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state,
struct drm_dp_vsc_sdp *vsc);
void intel_write_dp_vsc_sdp(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
struct drm_dp_vsc_sdp *vsc);
void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable, void intel_dp_set_infoframes(struct intel_encoder *encoder, bool enable,
const struct intel_crtc_state *crtc_state, const struct intel_crtc_state *crtc_state,
const struct drm_connector_state *conn_state); const struct drm_connector_state *conn_state);
......
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