Message ID | 20221207-rpi-hdmi-improvements-v1-7-6b15f774c13a@cerno.tech (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/vc4: hdmi: Broadcast RGB, BT601, BT2020 | expand |
Hi Am 07.12.22 um 17:07 schrieb Maxime Ripard: > From: Dave Stevenson <dave.stevenson@raspberrypi.com> > > The CSC matrix to use depends on the output format, its range and the > colorspace. > > Since we're going to add more colorspaces, let's move the CSC matrix > retrieval to a function. > > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> > Signed-off-by: Maxime Ripard <maxime@cerno.tech> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> > --- > drivers/gpu/drm/vc4/vc4_hdmi.c | 26 +++++++++++++++++++++++--- > 1 file changed, 23 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c > index cb92d07680f0..cd6775429b5e 100644 > --- a/drivers/gpu/drm/vc4/vc4_hdmi.c > +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c > @@ -1273,6 +1273,20 @@ static void vc5_hdmi_set_csc_coeffs_swap(struct vc4_hdmi *vc4_hdmi, > HDMI_WRITE(HDMI_CSC_34_33, (coeffs[1][3] << 16) | coeffs[1][2]); > } > > +static const u16 > +(*vc5_hdmi_get_yuv_csc_coeffs(struct vc4_hdmi *vc4_hdmi, u32 colorspace, bool limited))[4] I don't like the function name here. The helper vc5_hdmi_set_csc_coeffs() programs hardware, but this similarly named helper looks up static data. Best regards Thomas > +{ > + switch (colorspace) { > + default: > + case DRM_MODE_COLORIMETRY_NO_DATA: > + case DRM_MODE_COLORIMETRY_BT709_YCC: > + case DRM_MODE_COLORIMETRY_XVYCC_709: > + case DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED: > + case DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT: > + return vc5_hdmi_csc_full_rgb_to_yuv_bt709[limited]; > + } > +} > + > static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, > struct drm_connector_state *state, > const struct drm_display_mode *mode) > @@ -1282,6 +1296,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, > conn_state_to_vc4_hdmi_conn_state(state); > unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, mode) ? 0 : 1; > unsigned long flags; > + const u16 (*csc)[4]; > u32 if_cfg = 0; > u32 if_xbar = 0x543210; > u32 csc_chan_ctl = 0; > @@ -1296,11 +1311,16 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, > > switch (vc4_state->output_format) { > case VC4_HDMI_OUTPUT_YUV444: > - vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, > - vc5_hdmi_csc_full_rgb_to_yuv_bt709[lim_range]); > + csc = vc5_hdmi_get_yuv_csc_coeffs(vc4_hdmi, state->colorspace, > + vc4_hdmi_is_full_range(vc4_hdmi, mode)); > + > + vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc); > break; > > case VC4_HDMI_OUTPUT_YUV422: > + csc = vc5_hdmi_get_yuv_csc_coeffs(vc4_hdmi, state->colorspace, > + vc4_hdmi_is_full_range(vc4_hdmi, mode)); > + > csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD, > VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) | > VC5_MT_CP_CSC_CTL_USE_444_TO_422 | > @@ -1312,7 +1332,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, > if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY, > VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422); > > - vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_yuv_bt709[lim_range]); > + vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc); > break; > > case VC4_HDMI_OUTPUT_RGB: >
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index cb92d07680f0..cd6775429b5e 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -1273,6 +1273,20 @@ static void vc5_hdmi_set_csc_coeffs_swap(struct vc4_hdmi *vc4_hdmi, HDMI_WRITE(HDMI_CSC_34_33, (coeffs[1][3] << 16) | coeffs[1][2]); } +static const u16 +(*vc5_hdmi_get_yuv_csc_coeffs(struct vc4_hdmi *vc4_hdmi, u32 colorspace, bool limited))[4] +{ + switch (colorspace) { + default: + case DRM_MODE_COLORIMETRY_NO_DATA: + case DRM_MODE_COLORIMETRY_BT709_YCC: + case DRM_MODE_COLORIMETRY_XVYCC_709: + case DRM_MODE_COLORIMETRY_RGB_WIDE_FIXED: + case DRM_MODE_COLORIMETRY_RGB_WIDE_FLOAT: + return vc5_hdmi_csc_full_rgb_to_yuv_bt709[limited]; + } +} + static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, struct drm_connector_state *state, const struct drm_display_mode *mode) @@ -1282,6 +1296,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, conn_state_to_vc4_hdmi_conn_state(state); unsigned int lim_range = vc4_hdmi_is_full_range(vc4_hdmi, mode) ? 0 : 1; unsigned long flags; + const u16 (*csc)[4]; u32 if_cfg = 0; u32 if_xbar = 0x543210; u32 csc_chan_ctl = 0; @@ -1296,11 +1311,16 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, switch (vc4_state->output_format) { case VC4_HDMI_OUTPUT_YUV444: - vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, - vc5_hdmi_csc_full_rgb_to_yuv_bt709[lim_range]); + csc = vc5_hdmi_get_yuv_csc_coeffs(vc4_hdmi, state->colorspace, + vc4_hdmi_is_full_range(vc4_hdmi, mode)); + + vc5_hdmi_set_csc_coeffs_swap(vc4_hdmi, csc); break; case VC4_HDMI_OUTPUT_YUV422: + csc = vc5_hdmi_get_yuv_csc_coeffs(vc4_hdmi, state->colorspace, + vc4_hdmi_is_full_range(vc4_hdmi, mode)); + csc_ctl |= VC4_SET_FIELD(VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422_STANDARD, VC5_MT_CP_CSC_CTL_FILTER_MODE_444_TO_422) | VC5_MT_CP_CSC_CTL_USE_444_TO_422 | @@ -1312,7 +1332,7 @@ static void vc5_hdmi_csc_setup(struct vc4_hdmi *vc4_hdmi, if_cfg |= VC4_SET_FIELD(VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422_FORMAT_422_LEGACY, VC5_DVP_HT_VEC_INTERFACE_CFG_SEL_422); - vc5_hdmi_set_csc_coeffs(vc4_hdmi, vc5_hdmi_csc_full_rgb_to_yuv_bt709[lim_range]); + vc5_hdmi_set_csc_coeffs(vc4_hdmi, csc); break; case VC4_HDMI_OUTPUT_RGB: