Expose the standard DP Colorspace property with BT2020_RGB support and carry the selected colorspace in bridge atomic state. Force a modeset when it changes so the stream receives the corresponding VSC packet.
Signal full-range RGB to match the existing pixel path and retain CTA range for YUV420. Reject BT2020_RGB with a YUV420-only mode. Reuse the preceding VSC state, update and PSR handling for the new colorimetry. Assisted-by: LLM Signed-off-by: Xilin Wu <[email protected]> --- drivers/gpu/drm/msm/dp/dp_ctrl.c | 2 +- drivers/gpu/drm/msm/dp/dp_display.c | 6 ++++-- drivers/gpu/drm/msm/dp/dp_drm.c | 9 ++++++++- drivers/gpu/drm/msm/dp/dp_drm.h | 1 + drivers/gpu/drm/msm/dp/dp_utils.c | 12 ++++++++++++ drivers/gpu/drm/msm/dp/dp_utils.h | 3 +++ 6 files changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 2fd8dd456852..a1a649c636c7 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -2669,7 +2669,7 @@ int msm_dp_ctrl_on_stream(struct msm_dp_ctrl *msm_dp_ctrl, struct msm_dp_panel * /* Compliance tests may override the checked stream depth. */ if (panel->video_test) { ret = msm_dp_utils_pack_vsc_sdp(&test_vsc_sdp, - DRM_MODE_COLORIMETRY_DEFAULT, + state->colorspace, panel->msm_dp_mode.bpp / 3, panel->msm_dp_mode.out_fmt_is_yuv_420); if (ret) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 5a9162712540..34e1c48cdd79 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -728,14 +728,16 @@ int msm_dp_display_atomic_check(struct msm_dp *msm_dp_display, return bpp; state->bpp = bpp; - state->vsc_enabled = drm_mode_is_420_only(info, mode); + state->colorspace = conn_state->colorspace; + state->vsc_enabled = drm_mode_is_420_only(info, mode) || + state->colorspace != DRM_MODE_COLORIMETRY_DEFAULT; if (!state->vsc_enabled) return 0; if (dp->panel->link_caps_valid && !dp->panel->vsc_sdp_supported) return -EINVAL; - return msm_dp_utils_pack_vsc_sdp(&state->vsc_sdp, DRM_MODE_COLORIMETRY_DEFAULT, + return msm_dp_utils_pack_vsc_sdp(&state->vsc_sdp, state->colorspace, bpp / 3, drm_mode_is_420_only(info, mode)); } diff --git a/drivers/gpu/drm/msm/dp/dp_drm.c b/drivers/gpu/drm/msm/dp/dp_drm.c index 808b6fe3d650..0d17536f02fd 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.c +++ b/drivers/gpu/drm/msm/dp/dp_drm.c @@ -171,7 +171,7 @@ static int msm_dp_bridge_atomic_check(struct drm_bridge *bridge, old_conn_state = drm_atomic_get_old_connector_state(conn_state->state, conn_state->connector); - if (old_conn_state->max_requested_bpc != conn_state->max_requested_bpc) + if (msm_dp_utils_needs_modeset(old_conn_state, conn_state)) crtc_state->mode_changed = true; return 0; @@ -456,11 +456,18 @@ struct drm_connector *msm_dp_drm_connector_init(struct msm_dp *msm_dp_display, struct drm_encoder *encoder) { struct drm_connector *connector = NULL; + int ret; connector = drm_bridge_connector_init(msm_dp_display->drm_dev, encoder); if (IS_ERR(connector)) return connector; + ret = drm_mode_create_dp_colorspace_property(connector, + BIT(DRM_MODE_COLORIMETRY_BT2020_RGB)); + if (ret) + return ERR_PTR(ret); + drm_connector_attach_colorspace_property(connector); + if (!msm_dp_display->is_edp) drm_connector_attach_dp_subconnector_property(connector); diff --git a/drivers/gpu/drm/msm/dp/dp_drm.h b/drivers/gpu/drm/msm/dp/dp_drm.h index 122150d95bbb..0e85a1a55c88 100644 --- a/drivers/gpu/drm/msm/dp/dp_drm.h +++ b/drivers/gpu/drm/msm/dp/dp_drm.h @@ -20,6 +20,7 @@ struct msm_dp_bridge { struct msm_dp_bridge_state { struct drm_bridge_state base; u32 bpp; + enum drm_colorspace colorspace; bool vsc_enabled; struct dp_sdp vsc_sdp; }; diff --git a/drivers/gpu/drm/msm/dp/dp_utils.c b/drivers/gpu/drm/msm/dp/dp_utils.c index bde627a6701b..431c18aa2096 100644 --- a/drivers/gpu/drm/msm/dp/dp_utils.c +++ b/drivers/gpu/drm/msm/dp/dp_utils.c @@ -140,6 +140,11 @@ int msm_dp_utils_pack_vsc_sdp(struct dp_sdp *sdp, enum drm_colorspace colorspace case DRM_MODE_COLORIMETRY_DEFAULT: vsc.colorimetry = DP_COLORIMETRY_DEFAULT; break; + case DRM_MODE_COLORIMETRY_BT2020_RGB: + if (yuv420) + return -EINVAL; + vsc.colorimetry = DP_COLORIMETRY_BT2020_RGB; + break; default: return -EINVAL; } @@ -148,6 +153,13 @@ int msm_dp_utils_pack_vsc_sdp(struct dp_sdp *sdp, enum drm_colorspace colorspace return ret < 0 ? ret : 0; } +bool msm_dp_utils_needs_modeset(struct drm_connector_state *old_state, + struct drm_connector_state *new_state) +{ + return old_state->max_requested_bpc != new_state->max_requested_bpc || + old_state->colorspace != new_state->colorspace; +} + bool msm_dp_utils_psr_needs_modeset(const struct drm_crtc_state *state) { /* active_changed alone also describes a normal self-refresh exit. */ diff --git a/drivers/gpu/drm/msm/dp/dp_utils.h b/drivers/gpu/drm/msm/dp/dp_utils.h index e916de2a5929..81773db75c60 100644 --- a/drivers/gpu/drm/msm/dp/dp_utils.h +++ b/drivers/gpu/drm/msm/dp/dp_utils.h @@ -46,6 +46,9 @@ int msm_dp_utils_select_bpp(unsigned int bpc, unsigned int max_bpc, int msm_dp_utils_pack_vsc_sdp(struct dp_sdp *sdp, enum drm_colorspace colorspace, unsigned int bpc, bool yuv420); +bool msm_dp_utils_needs_modeset(struct drm_connector_state *old_state, + struct drm_connector_state *new_state); + bool msm_dp_utils_psr_needs_modeset(const struct drm_crtc_state *state); #endif /* _DP_UTILS_H_ */ -- 2.56.0
