From b3906054ef7d410715bdf42d52ea8c1ec7918eae Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Fri, 26 Jan 2024 14:23:40 +0800 Subject: [PATCH] drm/rockchip: drv: use color_encoding and color_range instead of private COLOR_SPACE The old method to description color space and range is borrowing V4L2 defined, It's difficult to understand, so we change to DRM defined property. Signed-off-by: Sandy Huang Change-Id: I7eacc60dfda912b9becae1ce026cdb82eebef7f8 --- .../gpu/drm/rockchip/analogix_dp-rockchip.c | 3 +- drivers/gpu/drm/rockchip/dw-dp.c | 4 +- .../gpu/drm/rockchip/dw-mipi-dsi-rockchip.c | 3 +- .../gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c | 3 +- drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c | 19 +- .../gpu/drm/rockchip/rockchip-mipi-csi-tx.c | 3 +- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 35 +++- drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 6 +- drivers/gpu/drm/rockchip/rockchip_drm_tve.c | 3 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 167 +++++++++--------- drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 2 +- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 126 ++++++------- drivers/gpu/drm/rockchip/rockchip_lvds.c | 3 +- drivers/gpu/drm/rockchip/rockchip_post_csc.c | 2 +- drivers/gpu/drm/rockchip/rockchip_rgb.c | 6 +- 15 files changed, 215 insertions(+), 170 deletions(-) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 4ad6551ede24..9362c63a8086 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -478,7 +478,8 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder, s->bus_flags = di->bus_flags; s->tv_state = &conn_state->tv; s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; - s->color_space = V4L2_COLORSPACE_DEFAULT; + s->color_encoding = DRM_COLOR_YCBCR_BT709; + s->color_range = DRM_COLOR_YCBCR_FULL_RANGE; /** * It's priority to user rate range define in dtsi. */ diff --git a/drivers/gpu/drm/rockchip/dw-dp.c b/drivers/gpu/drm/rockchip/dw-dp.c index 2a1cd92fd1b8..dad4f8810418 100644 --- a/drivers/gpu/drm/rockchip/dw-dp.c +++ b/drivers/gpu/drm/rockchip/dw-dp.c @@ -2621,9 +2621,9 @@ static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder, s->tv_state = &conn_state->tv; s->eotf = dp->eotf_type; if (dw_dp_is_hdr_eotf(s->eotf)) - s->color_space = V4L2_COLORSPACE_BT2020; + s->color_encoding = DRM_COLOR_YCBCR_BT2020; else - s->color_space = V4L2_COLORSPACE_DEFAULT; + s->color_encoding = DRM_COLOR_YCBCR_BT709; dw_dp_mode_fixup(dp, &crtc_state->adjusted_mode); diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c index 910e58ecb71a..2b14a66d7c03 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c @@ -829,7 +829,8 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder, s->output_type = DRM_MODE_CONNECTOR_DSI; s->tv_state = &conn_state->tv; - s->color_space = V4L2_COLORSPACE_DEFAULT; + s->color_encoding = DRM_COLOR_YCBCR_BT709; + s->color_range = DRM_COLOR_YCBCR_FULL_RANGE; s->output_if = dsi->id ? VOP_OUTPUT_IF_MIPI1 : VOP_OUTPUT_IF_MIPI0; if (dsi->slave) { s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE; diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c index 48d19850be78..8f521017e4ae 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi2-rockchip.c @@ -998,7 +998,8 @@ dw_mipi_dsi2_encoder_atomic_check(struct drm_encoder *encoder, s->bus_flags = info->bus_flags; s->tv_state = &conn_state->tv; - s->color_space = V4L2_COLORSPACE_DEFAULT; + s->color_encoding = DRM_COLOR_YCBCR_BT709; + s->color_range = DRM_COLOR_YCBCR_FULL_RANGE; if (!(dsi2->mode_flags & MIPI_DSI_MODE_VIDEO)) { s->output_flags |= ROCKCHIP_OUTPUT_MIPI_DS_MODE; diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c index d8e40cd75daa..196d87156fc9 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c @@ -2402,13 +2402,20 @@ secondary: hdmi->bus_format = s->bus_format; if (hdmi->enc_out_encoding == V4L2_YCBCR_ENC_BT2020) - s->color_space = V4L2_COLORSPACE_BT2020; - else if (colorformat == RK_IF_FORMAT_RGB) - s->color_space = V4L2_COLORSPACE_DEFAULT; + s->color_encoding = DRM_COLOR_YCBCR_BT2020; + else if (colorformat == RK_IF_FORMAT_RGB)/* sRGB color space is almost equal to bt.709 */ + s->color_encoding = DRM_COLOR_YCBCR_BT709; else if (hdmi->enc_out_encoding == V4L2_YCBCR_ENC_709) - s->color_space = V4L2_COLORSPACE_REC709; + s->color_encoding = DRM_COLOR_YCBCR_BT709; else - s->color_space = V4L2_COLORSPACE_SMPTE170M; + s->color_encoding = DRM_COLOR_YCBCR_BT601; + + if (colorformat == RK_IF_FORMAT_RGB) + s->color_range = hdmi->hdmi_quant_range == HDMI_QUANTIZATION_RANGE_LIMITED ? + DRM_COLOR_YCBCR_LIMITED_RANGE : DRM_COLOR_YCBCR_FULL_RANGE; + else + s->color_range = hdmi->hdmi_quant_range == HDMI_QUANTIZATION_RANGE_FULL ? + DRM_COLOR_YCBCR_FULL_RANGE : DRM_COLOR_YCBCR_LIMITED_RANGE; if (hdmi->plat_data->split_mode && !secondary) { hdmi = rockchip_hdmi_find_by_id(hdmi->dev->driver, !hdmi->id); @@ -2865,7 +2872,7 @@ dw_hdmi_rockchip_attach_properties(struct drm_connector *connector, if (!hdmi->is_hdmi_qp) { prop = drm_property_create_enum(connector->dev, 0, - "hdmi_quant_range", + "quant_range", quant_range_enum_list, ARRAY_SIZE(quant_range_enum_list)); if (prop) { diff --git a/drivers/gpu/drm/rockchip/rockchip-mipi-csi-tx.c b/drivers/gpu/drm/rockchip/rockchip-mipi-csi-tx.c index adbc11679f53..8fcd95970ff0 100644 --- a/drivers/gpu/drm/rockchip/rockchip-mipi-csi-tx.c +++ b/drivers/gpu/drm/rockchip/rockchip-mipi-csi-tx.c @@ -925,7 +925,8 @@ rockchip_mipi_csi_encoder_atomic_check(struct drm_encoder *encoder, s->bus_format = MEDIA_BUS_FMT_RGB888_1X24; s->tv_state = &conn_state->tv; s->eotf = TRADITIONAL_GAMMA_SDR; - s->color_space = V4L2_COLORSPACE_DEFAULT; + s->color_encoding = DRM_COLOR_YCBCR_BT709; + s->color_range = DRM_COLOR_YCBCR_FULL_RANGE; return 0; } diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index e9adc96a5e71..80d1acaa49d1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -48,7 +48,7 @@ #define DRIVER_NAME "rockchip" #define DRIVER_DESC "RockChip Soc DRM" #define DRIVER_DATE "20140818" -#define DRIVER_MAJOR 3 +#define DRIVER_MAJOR 4 #define DRIVER_MINOR 0 #define for_each_displayid_db(displayid, block, idx, length) \ @@ -447,6 +447,33 @@ u32 rockchip_drm_get_dclk_by_width(int width) } EXPORT_SYMBOL(rockchip_drm_get_dclk_by_width); +static const char * const color_encoding_name[] = { + [DRM_COLOR_YCBCR_BT601] = "BT.601", + [DRM_COLOR_YCBCR_BT709] = "BT.709", + [DRM_COLOR_YCBCR_BT2020] = "BT.2020", +}; + +static const char * const color_range_name[] = { + [DRM_COLOR_YCBCR_LIMITED_RANGE] = "Limited", + [DRM_COLOR_YCBCR_FULL_RANGE] = "Full", +}; + +const char *rockchip_drm_get_color_encoding_name(enum drm_color_encoding encoding) +{ + if (WARN_ON(encoding >= ARRAY_SIZE(color_encoding_name))) + return "unknown"; + + return color_encoding_name[encoding]; +} + +const char *rockchip_drm_get_color_range_name(enum drm_color_range range) +{ + if (WARN_ON(range >= ARRAY_SIZE(color_range_name))) + return "unknown"; + + return color_range_name[range]; +} + static int cea_db_tag(const u8 *db) { @@ -1339,12 +1366,6 @@ static int rockchip_drm_create_properties(struct drm_device *dev) return -ENOMEM; private->eotf_prop = prop; - prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, - "COLOR_SPACE", 0, 12); - if (!prop) - return -ENOMEM; - private->color_space_prop = prop; - prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC, "ASYNC_COMMIT", 0, 1); if (!prop) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index 0854b965671f..323c8fcbc2d7 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -281,7 +281,8 @@ struct rockchip_crtc_state { int post_y2r_en; int post_csc_mode; int bcsh_en; - int color_space; + enum drm_color_encoding color_encoding; + enum drm_color_range color_range; int eotf; u32 background; u32 line_flag; @@ -507,7 +508,6 @@ struct rockchip_drm_private { /* private plane prop */ struct drm_property *eotf_prop; - struct drm_property *color_space_prop; struct drm_property *async_commit_prop; struct drm_property *share_id_prop; @@ -567,6 +567,8 @@ void rockchip_drm_te_handle(struct drm_crtc *crtc); void drm_mode_convert_to_split_mode(struct drm_display_mode *mode); void drm_mode_convert_to_origin_mode(struct drm_display_mode *mode); u32 rockchip_drm_get_dclk_by_width(int width); +const char *rockchip_drm_get_color_encoding_name(enum drm_color_encoding encoding); +const char *rockchip_drm_get_color_range_name(enum drm_color_range range); #if IS_REACHABLE(CONFIG_DRM_ROCKCHIP) int rockchip_drm_get_sub_dev_type(void); u32 rockchip_drm_get_scan_line_time_ns(void); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_tve.c b/drivers/gpu/drm/rockchip/rockchip_drm_tve.c index 6fbd17c1b003..a8b5f0c4cbc1 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_tve.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_tve.c @@ -483,7 +483,8 @@ rockchip_tve_encoder_atomic_check(struct drm_encoder *encoder, */ if (tve->soc_type == SOC_RK3528) s->output_if |= VOP_OUTPUT_IF_BT656; - s->color_space = V4L2_COLORSPACE_SMPTE170M; + s->color_encoding = DRM_COLOR_YCBCR_BT601; + s->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; s->tv_state = &conn_state->tv; return 0; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index f4fe35c11155..387812d3cfc3 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -180,7 +180,6 @@ struct vop_plane_state { bool y2r_en; bool r2r_en; bool r2y_en; - int color_space; u32 color_key; unsigned int csc_mode; int global_alpha; @@ -1030,18 +1029,17 @@ static int vop_hdr_atomic_check(struct drm_crtc *crtc, pre_sdr2hdr_state = 0; post_sdr2hdr_state = 0; drm_atomic_crtc_state_for_each_plane(plane, crtc_state) { - struct vop_plane_state *vop_plane_state; struct vop_win *win = to_vop_win(plane); pstate = drm_atomic_get_plane_state(state, plane); if (IS_ERR(pstate)) return PTR_ERR(pstate); - vop_plane_state = to_vop_plane_state(pstate); if (!pstate->fb) continue; - if (vop_plane_state->color_space == V4L2_COLORSPACE_BT2020 && - vop_plane_state->color_space > s->color_space) { + /* bt.2020 to bt.709 */ + if (pstate->color_encoding == DRM_COLOR_YCBCR_BT2020 && + s->color_encoding != DRM_COLOR_YCBCR_BT2020) { if (win->feature & WIN_FEATURE_PRE_OVERLAY) { pre_sdr2hdr_mode = BT2020_TO_BT709; pre_sdr2hdr_state |= BIT(plane_id); @@ -1050,8 +1048,10 @@ static int vop_hdr_atomic_check(struct drm_crtc *crtc, post_sdr2hdr_state |= BIT(plane_id); } } - if (s->color_space == V4L2_COLORSPACE_BT2020 && - vop_plane_state->color_space < s->color_space) { + + /* bt.709 to bt.2020 */ + if (s->color_encoding == DRM_COLOR_YCBCR_BT2020 && + pstate->color_encoding != DRM_COLOR_YCBCR_BT2020) { if (win->feature & WIN_FEATURE_PRE_OVERLAY) { pre_sdr2hdr_mode = BT709_TO_BT2020; pre_sdr2hdr_state |= BIT(plane_id); @@ -1088,24 +1088,43 @@ exit_hdr_convert: return 0; } -static int to_vop_csc_mode(int csc_mode) +static enum vop_csc_format to_vop_csc_mode(enum drm_color_encoding color_encoding, + enum drm_color_range color_range) { - switch (csc_mode) { - case V4L2_COLORSPACE_SMPTE170M: - case V4L2_COLORSPACE_470_SYSTEM_M: - case V4L2_COLORSPACE_470_SYSTEM_BG: - return CSC_BT601L; - case V4L2_COLORSPACE_REC709: - case V4L2_COLORSPACE_SMPTE240M: - case V4L2_COLORSPACE_DEFAULT: - return CSC_BT709L; - case V4L2_COLORSPACE_JPEG: - return CSC_BT601F; - case V4L2_COLORSPACE_BT2020: - return CSC_BT2020; + bool full_range = color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0; + enum vop_csc_format csc_mode = CSC_BT709L; + + switch (color_encoding) { + case DRM_COLOR_YCBCR_BT601: + if (full_range) + csc_mode = CSC_BT601F; + else + csc_mode = CSC_BT601L; + break; + + case DRM_COLOR_YCBCR_BT709: + if (full_range) { + csc_mode = CSC_BT601F; + DRM_DEBUG("Unsupported bt709f at 10bit csc depth, use bt601f instead\n"); + } else { + csc_mode = CSC_BT709L; + } + break; + + case DRM_COLOR_YCBCR_BT2020: + if (full_range) { + csc_mode = CSC_BT601F; + DRM_DEBUG("Unsupported bt2020f at 10bit csc depth, use bt601f instead\n"); + } else { + csc_mode = CSC_BT2020L; + } + break; + default: - return CSC_BT709L; + DRM_ERROR("Unsuport color_encoding:%d\n", color_encoding); } + + return csc_mode; } static void vop_disable_all_planes(struct vop *vop) @@ -1154,13 +1173,17 @@ static void vop_disable_all_planes(struct vop *vop) * * 11. RGB --> bypass --> RGB_OUTPUT(709) */ -static int vop_setup_csc_table(const struct vop_csc_table *csc_table, - bool is_input_yuv, bool is_output_yuv, - int input_csc, int output_csc, +static int vop_setup_csc_table(struct rockchip_crtc_state *s, + struct drm_plane_state *pstate, const struct vop_csc_table *csc_table, const uint32_t **y2r_table, const uint32_t **r2r_table, const uint32_t **r2y_table) { + bool is_input_yuv = is_yuv_support(pstate->fb->format->format); + bool is_output_yuv = is_yuv_output(s->bus_format); + int input_csc = pstate->color_encoding; + int output_csc = s->color_encoding; + *y2r_table = NULL; *r2r_table = NULL; *r2y_table = NULL; @@ -1169,28 +1192,25 @@ static int vop_setup_csc_table(const struct vop_csc_table *csc_table, return 0; if (is_output_yuv) { - if (output_csc == V4L2_COLORSPACE_BT2020) { + if (output_csc == DRM_COLOR_YCBCR_BT2020) { if (is_input_yuv) { - if (input_csc == V4L2_COLORSPACE_BT2020) + if (input_csc == DRM_COLOR_YCBCR_BT2020) return 0; *y2r_table = csc_table->y2r_bt709; } - if (input_csc != V4L2_COLORSPACE_BT2020) + if (input_csc != DRM_COLOR_YCBCR_BT2020) *r2r_table = csc_table->r2r_bt709_to_bt2020; *r2y_table = csc_table->r2y_bt2020; } else { - if (is_input_yuv && input_csc == V4L2_COLORSPACE_BT2020) + if (is_input_yuv && input_csc == DRM_COLOR_YCBCR_BT2020) *y2r_table = csc_table->y2r_bt2020; - if (input_csc == V4L2_COLORSPACE_BT2020) + if (input_csc == DRM_COLOR_YCBCR_BT2020) *r2r_table = csc_table->r2r_bt2020_to_bt709; if (!is_input_yuv || *y2r_table) { - if (output_csc == V4L2_COLORSPACE_REC709 || - output_csc == V4L2_COLORSPACE_SMPTE240M || - output_csc == V4L2_COLORSPACE_DEFAULT) + if (output_csc == DRM_COLOR_YCBCR_BT709) *r2y_table = csc_table->r2y_bt709; - else if (output_csc == V4L2_COLORSPACE_SMPTE170M || - output_csc == V4L2_COLORSPACE_470_SYSTEM_M || - output_csc == V4L2_COLORSPACE_470_SYSTEM_BG) + else if (output_csc == DRM_COLOR_YCBCR_BT601 && + s->color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) *r2y_table = csc_table->r2y_bt601_12_235; /* bt601 limit */ else *r2y_table = csc_table->r2y_bt601; /* bt601 full */ @@ -1203,23 +1223,20 @@ static int vop_setup_csc_table(const struct vop_csc_table *csc_table, /* * is possible use bt2020 on rgb mode? */ - if (WARN_ON(output_csc == V4L2_COLORSPACE_BT2020)) + if (WARN_ON(output_csc == DRM_COLOR_YCBCR_BT2020)) return -EINVAL; - if (input_csc == V4L2_COLORSPACE_BT2020) + if (input_csc == DRM_COLOR_YCBCR_BT2020) *y2r_table = csc_table->y2r_bt2020; - else if (input_csc == V4L2_COLORSPACE_REC709 || - input_csc == V4L2_COLORSPACE_SMPTE240M || - input_csc == V4L2_COLORSPACE_DEFAULT) + else if (input_csc == DRM_COLOR_YCBCR_BT709) *y2r_table = csc_table->y2r_bt709; - else if (input_csc == V4L2_COLORSPACE_SMPTE170M || - input_csc == V4L2_COLORSPACE_470_SYSTEM_M || - input_csc == V4L2_COLORSPACE_470_SYSTEM_BG) + else if (input_csc == DRM_COLOR_YCBCR_BT601 && + pstate->color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) *y2r_table = csc_table->y2r_bt601_12_235; /* bt601 limit */ else *y2r_table = csc_table->y2r_bt601; /* bt601 full */ - if (input_csc == V4L2_COLORSPACE_BT2020) + if (input_csc == DRM_COLOR_YCBCR_BT2020) /* * We don't have bt601 to bt709 table, force use bt709. */ @@ -1229,19 +1246,6 @@ static int vop_setup_csc_table(const struct vop_csc_table *csc_table, return 0; } -static void vop_setup_csc_mode(bool is_input_yuv, bool is_output_yuv, - int input_csc, int output_csc, - bool *y2r_en, bool *r2y_en, int *csc_mode) -{ - if (is_input_yuv && !is_output_yuv) { - *y2r_en = true; - *csc_mode = to_vop_csc_mode(input_csc); - } else if (!is_input_yuv && is_output_yuv) { - *r2y_en = true; - *csc_mode = to_vop_csc_mode(output_csc); - } -} - static int vop_csc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state) { @@ -1272,21 +1276,20 @@ static int vop_csc_atomic_check(struct drm_crtc *crtc, vop_plane_state->r2r_en = false; vop_plane_state->r2y_en = false; - ret = vop_setup_csc_table(csc_table, is_input_yuv, - is_output_yuv, - vop_plane_state->color_space, - s->color_space, + ret = vop_setup_csc_table(s, pstate, csc_table, &vop_plane_state->y2r_table, &vop_plane_state->r2r_table, &vop_plane_state->r2y_table); if (ret) return ret; - vop_setup_csc_mode(is_input_yuv, s->yuv_overlay, - vop_plane_state->color_space, s->color_space, - &vop_plane_state->y2r_en, - &vop_plane_state->r2y_en, - &vop_plane_state->csc_mode); + if (is_input_yuv && !is_output_yuv) { + vop_plane_state->y2r_en = true; + vop_plane_state->csc_mode = to_vop_csc_mode(pstate->color_encoding, pstate->color_range); + } else if (!is_input_yuv && is_output_yuv) { + vop_plane_state->r2y_en = true; + vop_plane_state->csc_mode = to_vop_csc_mode(s->color_encoding, s->color_range); + } if (csc_table) { vop_plane_state->y2r_en = !!vop_plane_state->y2r_table; @@ -2526,11 +2529,6 @@ static int vop_atomic_plane_set_property(struct drm_plane *plane, return 0; } - if (property == private->color_space_prop) { - plane_state->color_space = val; - return 0; - } - if (property == private->async_commit_prop) { plane_state->async_commit = val; return 0; @@ -2561,11 +2559,6 @@ static int vop_atomic_plane_get_property(struct drm_plane *plane, return 0; } - if (property == private->color_space_prop) { - *val = plane_state->color_space; - return 0; - } - if (property == private->async_commit_prop) { *val = plane_state->async_commit; return 0; @@ -2736,11 +2729,11 @@ static int vop_plane_info_dump(struct seq_file *s, struct drm_plane *plane) src = &pstate->src; dest = &pstate->dest; - DEBUG_PRINT("\tformat: %p4cc%s%s[%d] color_space[%d]\n", + DEBUG_PRINT("\tformat: %p4cc%s%s[%d] color-encoding[%d] color-range[%d]\n", &fb->format->format, rockchip_afbc(plane, state->fb->modifier) ? "[AFBC]" : "", pstate->eotf ? " HDR" : " SDR", pstate->eotf, - pstate->color_space); + state->color_encoding, state->color_range); DEBUG_PRINT("\tcsc: y2r[%d] r2r[%d] r2y[%d] csc mode[%d]\n", pstate->y2r_en, pstate->r2r_en, pstate->r2y_en, pstate->csc_mode); @@ -2798,8 +2791,8 @@ static int vop_crtc_debugfs_dump(struct drm_crtc *crtc, struct seq_file *s) drm_get_bus_format_name(state->bus_format)); DEBUG_PRINT("\toverlay_mode[%d] output_mode[%x]", state->yuv_overlay, state->output_mode); - DEBUG_PRINT(" color_space[%d]\n", - state->color_space); + DEBUG_PRINT("color-encoding[%d] color-range[%d]\n", + state->color_encoding, state->color_range); DEBUG_PRINT(" Display mode: %dx%d%s%d\n", mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p", drm_mode_vrefresh(mode)); @@ -4047,7 +4040,7 @@ static void vop_tv_config_update(struct drm_crtc *crtc, s->post_y2r_en = 1; } - s->post_csc_mode = to_vop_csc_mode(s->color_space); + s->post_csc_mode = to_vop_csc_mode(s->color_encoding, s->color_range); VOP_CTRL_SET(vop, bcsh_r2y_en, s->post_r2y_en); VOP_CTRL_SET(vop, bcsh_y2r_en, s->post_y2r_en); VOP_CTRL_SET(vop, bcsh_r2y_csc_mode, s->post_csc_mode); @@ -4696,8 +4689,14 @@ static int vop_plane_init(struct vop *vop, struct vop_win *win, drm_object_attach_property(&win->base.base, vop->plane_feature_prop, feature); drm_object_attach_property(&win->base.base, private->eotf_prop, 0); - drm_object_attach_property(&win->base.base, - private->color_space_prop, 0); + drm_plane_create_color_properties(&win->base, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709) | + BIT(DRM_COLOR_YCBCR_BT2020), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_LIMITED_RANGE); if (VOP_WIN_SUPPORT(vop, win, global_alpha_val)) drm_plane_create_alpha_property(&win->base); drm_object_attach_property(&win->base.base, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h index ff646fe0fc5a..d3a596bc2fad 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.h @@ -171,7 +171,7 @@ enum vop_csc_format { CSC_BT601L, CSC_BT709L, CSC_BT601F, - CSC_BT2020, + CSC_BT2020L, CSC_BT709L_13BIT, CSC_BT709F_13BIT, CSC_BT2020L_13BIT, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index 4c2f0fd588ae..389de34d79fb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -367,7 +367,6 @@ struct vop2_plane_state { uint8_t afbc_half_block_en; uint8_t tiled_en; int eotf; - int color_space; int global_alpha; int blend_mode; uint64_t color_key; @@ -2748,44 +2747,46 @@ static void vop2_setup_scale(struct vop2 *vop2, struct vop2_win *win, } } -static int vop2_convert_csc_mode(int csc_mode, int bit_depth) +static enum vop_csc_format vop2_convert_csc_mode(enum drm_color_encoding color_encoding, + enum drm_color_range color_range, + int bit_depth) { - switch (csc_mode) { - case V4L2_COLORSPACE_SMPTE170M: - case V4L2_COLORSPACE_470_SYSTEM_M: - case V4L2_COLORSPACE_470_SYSTEM_BG: - return CSC_BT601L; - case V4L2_COLORSPACE_REC709: - case V4L2_COLORSPACE_SMPTE240M: - case V4L2_COLORSPACE_DEFAULT: - if (bit_depth == CSC_13BIT_DEPTH) - return CSC_BT709L_13BIT; + bool full_range = color_range == DRM_COLOR_YCBCR_FULL_RANGE ? 1 : 0; + enum vop_csc_format csc_mode = CSC_BT709L; + + switch (color_encoding) { + case DRM_COLOR_YCBCR_BT601: + if (full_range) + csc_mode = CSC_BT601F; else - return CSC_BT709L; - case V4L2_COLORSPACE_JPEG: - return CSC_BT601F; - case V4L2_COLORSPACE_BT2020: - if (bit_depth == CSC_13BIT_DEPTH) - return CSC_BT2020L_13BIT; - else - return CSC_BT2020; - case V4L2_COLORSPACE_BT709F: - if (bit_depth == CSC_10BIT_DEPTH) { - DRM_WARN("Unsupported bt709f at 10bit csc depth, use bt601f instead\n"); - return CSC_BT601F; + csc_mode = CSC_BT601L; + break; + + case DRM_COLOR_YCBCR_BT709: + if (full_range) { + csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT709F_13BIT : CSC_BT601F; + if (bit_depth != CSC_13BIT_DEPTH) + DRM_DEBUG("Unsupported bt709f at 10bit csc depth, use bt601f instead\n"); } else { - return CSC_BT709F_13BIT; + csc_mode = CSC_BT709L; } - case V4L2_COLORSPACE_BT2020F: - if (bit_depth == CSC_10BIT_DEPTH) { - DRM_WARN("Unsupported bt2020f at 10bit csc depth, use bt601f instead\n"); - return CSC_BT601F; + break; + + case DRM_COLOR_YCBCR_BT2020: + if (full_range) { + csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT2020F_13BIT : CSC_BT601F; + if (bit_depth != CSC_13BIT_DEPTH) + DRM_DEBUG("Unsupported bt2020f at 10bit csc depth, use bt601f instead\n"); } else { - return CSC_BT2020F_13BIT; + csc_mode = bit_depth == CSC_13BIT_DEPTH ? CSC_BT2020L_13BIT : CSC_BT2020L; } + break; + default: - return CSC_BT709L; + DRM_ERROR("Unsuport color_encoding:%d\n", color_encoding); } + + return csc_mode; } static bool vop2_is_allwin_disabled(struct drm_crtc *crtc) @@ -2869,8 +2870,6 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp, struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->rockchip_crtc.crtc.state); int is_input_yuv = pstate->fb->format->is_yuv; int is_output_yuv = vcstate->yuv_overlay; - int input_csc = vpstate->color_space; - int output_csc = vcstate->color_space; struct vop2_win *win = to_vop2_win(pstate->plane); int csc_y2r_bit_depth = CSC_10BIT_DEPTH; @@ -2885,14 +2884,16 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp, if (vpstate->hdr_in) { if (is_input_yuv) { vpstate->y2r_en = 1; - vpstate->csc_mode = vop2_convert_csc_mode(input_csc, + vpstate->csc_mode = vop2_convert_csc_mode(pstate->color_encoding, + pstate->color_range, CSC_13BIT_DEPTH); } return; } else if (vp->sdr2hdr_en) { if (is_input_yuv) { vpstate->y2r_en = 1; - vpstate->csc_mode = vop2_convert_csc_mode(input_csc, + vpstate->csc_mode = vop2_convert_csc_mode(pstate->color_encoding, + pstate->color_range, csc_y2r_bit_depth); } return; @@ -2907,7 +2908,8 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp, */ if (!is_input_yuv) { vpstate->r2y_en = 1; - vpstate->csc_mode = vop2_convert_csc_mode(output_csc, + vpstate->csc_mode = vop2_convert_csc_mode(vcstate->color_encoding, + vcstate->color_range, CSC_10BIT_DEPTH); } return; @@ -2919,7 +2921,8 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp, */ if (is_input_yuv) { vpstate->y2r_en = 1; - vpstate->csc_mode = vop2_convert_csc_mode(input_csc, + vpstate->csc_mode = vop2_convert_csc_mode(pstate->color_encoding, + pstate->color_range, csc_y2r_bit_depth); } return; @@ -2928,10 +2931,10 @@ static void vop2_setup_csc_mode(struct vop2_video_port *vp, if (is_input_yuv && !is_output_yuv) { vpstate->y2r_en = 1; - vpstate->csc_mode = vop2_convert_csc_mode(input_csc, csc_y2r_bit_depth); + vpstate->csc_mode = vop2_convert_csc_mode(pstate->color_encoding, pstate->color_range, csc_y2r_bit_depth); } else if (!is_input_yuv && is_output_yuv) { vpstate->r2y_en = 1; - vpstate->csc_mode = vop2_convert_csc_mode(output_csc, CSC_10BIT_DEPTH); + vpstate->csc_mode = vop2_convert_csc_mode(vcstate->color_encoding, vcstate->color_range, CSC_10BIT_DEPTH); } } @@ -5734,11 +5737,6 @@ static int vop2_atomic_plane_set_property(struct drm_plane *plane, return 0; } - if (property == private->color_space_prop) { - vpstate->color_space = val; - return 0; - } - if (property == private->async_commit_prop) { vpstate->async_commit = val; return 0; @@ -5769,11 +5767,6 @@ static int vop2_atomic_plane_get_property(struct drm_plane *plane, return 0; } - if (property == private->color_space_prop) { - *val = vpstate->color_space; - return 0; - } - if (property == private->async_commit_prop) { *val = vpstate->async_commit; return 0; @@ -6293,11 +6286,14 @@ static int vop2_plane_info_dump(struct seq_file *s, struct drm_plane *plane) DEBUG_PRINT("\twin_id: %d\n", win->win_id); - DEBUG_PRINT("\tformat: %p4cc%s%s[%d] color_space[%d] glb_alpha[0x%x]\n", - &fb->format->format, - modifier_to_string(fb->modifier), - vpstate->eotf ? " HDR" : " SDR", vpstate->eotf, - vpstate->color_space, vpstate->global_alpha); + DEBUG_PRINT("\tformat: %p4cc%s pixel_blend_mode[%d] glb_alpha[0x%x]\n", + &fb->format->format, modifier_to_string(fb->modifier), + pstate->pixel_blend_mode, vpstate->global_alpha); + DEBUG_PRINT("\tcolor: %s[%d] color-encoding[%s] color-range[%s]\n", + vpstate->eotf ? "HDR" : "SDR", vpstate->eotf, + rockchip_drm_get_color_encoding_name(pstate->color_encoding), + rockchip_drm_get_color_range_name(pstate->color_range)); + DEBUG_PRINT("\trotate: xmirror: %d ymirror: %d rotate_90: %d rotate_270: %d\n", vpstate->xmirror_en, vpstate->ymirror_en, vpstate->rotate_90_en, vpstate->rotate_270_en); @@ -6354,10 +6350,12 @@ static int vop2_crtc_debugfs_dump(struct drm_crtc *crtc, struct seq_file *s) vop2_dump_connector_on_crtc(crtc, s); DEBUG_PRINT("\tbus_format[%x]: %s\n", state->bus_format, drm_get_bus_format_name(state->bus_format)); - DEBUG_PRINT("\toverlay_mode[%d] output_mode[%x]", + DEBUG_PRINT("\toverlay_mode[%d] output_mode[%x] ", state->yuv_overlay, state->output_mode); - DEBUG_PRINT(" color_space[%d], eotf:%d\n", - state->color_space, state->eotf); + DEBUG_PRINT("%s[%d] color-encoding[%s] color-range[%s]\n", + state->eotf ? "HDR" : "SDR", state->eotf, + rockchip_drm_get_color_encoding_name(state->color_encoding), + rockchip_drm_get_color_range_name(state->color_range)); DEBUG_PRINT(" Display mode: %dx%d%s%d\n", mode->hdisplay, mode->vdisplay, interlaced ? "i" : "p", drm_mode_vrefresh(mode)); @@ -9738,7 +9736,7 @@ static void vop2_tv_config_update(struct drm_crtc *crtc, vcstate->post_y2r_en = 1; } - vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_space, CSC_10BIT_DEPTH); + vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_encoding, vcstate->color_range, CSC_10BIT_DEPTH); if (vp_data->feature & VOP_FEATURE_OUTPUT_10BIT) brightness = interpolate(0, -128, 100, 127, @@ -9819,7 +9817,7 @@ static void vop3_post_csc_config(struct drm_crtc *crtc, struct post_acm *acm, st if (is_yuv_output(vcstate->bus_format)) is_output_yuv = true; - vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_space, CSC_13BIT_DEPTH); + vcstate->post_csc_mode = vop2_convert_csc_mode(vcstate->color_encoding, vcstate->color_range, CSC_13BIT_DEPTH); if (post_csc_en) { rockchip_calc_post_csc(csc, &csc_coef, vcstate->post_csc_mode, is_input_yuv, @@ -10975,7 +10973,15 @@ static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win, unsigned lon drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs); drm_object_attach_property(&win->base.base, private->eotf_prop, 0); - drm_object_attach_property(&win->base.base, private->color_space_prop, 0); + drm_plane_create_color_properties(&win->base, + BIT(DRM_COLOR_YCBCR_BT601) | + BIT(DRM_COLOR_YCBCR_BT709) | + BIT(DRM_COLOR_YCBCR_BT2020), + BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | + BIT(DRM_COLOR_YCBCR_FULL_RANGE), + DRM_COLOR_YCBCR_BT601, + DRM_COLOR_YCBCR_LIMITED_RANGE); + drm_object_attach_property(&win->base.base, private->async_commit_prop, 0); if (win->feature & (WIN_FEATURE_CLUSTER_SUB | WIN_FEATURE_CLUSTER_MAIN)) diff --git a/drivers/gpu/drm/rockchip/rockchip_lvds.c b/drivers/gpu/drm/rockchip/rockchip_lvds.c index 805027ab6c60..bf92a644f423 100644 --- a/drivers/gpu/drm/rockchip/rockchip_lvds.c +++ b/drivers/gpu/drm/rockchip/rockchip_lvds.c @@ -340,7 +340,8 @@ rockchip_lvds_encoder_atomic_check(struct drm_encoder *encoder, s->bus_flags = info->bus_flags; s->tv_state = &conn_state->tv; s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; - s->color_space = V4L2_COLORSPACE_DEFAULT; + s->color_encoding = DRM_COLOR_YCBCR_BT709; + s->color_range = DRM_COLOR_YCBCR_FULL_RANGE; switch (lvds->pixel_order) { case ROCKCHIP_LVDS_DUAL_LINK_ODD_EVEN_PIXELS: diff --git a/drivers/gpu/drm/rockchip/rockchip_post_csc.c b/drivers/gpu/drm/rockchip/rockchip_post_csc.c index 212a4b4b89e6..4a583ba3bfdb 100644 --- a/drivers/gpu/drm/rockchip/rockchip_post_csc.c +++ b/drivers/gpu/drm/rockchip/rockchip_post_csc.c @@ -1017,7 +1017,7 @@ static const struct csc_mapping csc_mapping_table[] = { true, }, { - CSC_BT2020, + CSC_BT2020L, OPTM_CS_E_RGB_2020, OPTM_CS_E_XV_YCC_2020, true, diff --git a/drivers/gpu/drm/rockchip/rockchip_rgb.c b/drivers/gpu/drm/rockchip/rockchip_rgb.c index 67b53a0b9f1a..ba25a16a2ff4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_rgb.c +++ b/drivers/gpu/drm/rockchip/rockchip_rgb.c @@ -270,6 +270,8 @@ rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder, else s->bus_format = MEDIA_BUS_FMT_RGB888_1X24; + s->color_range = DRM_COLOR_YCBCR_FULL_RANGE; + s->color_encoding = DRM_COLOR_YCBCR_BT709; switch (s->bus_format) { case MEDIA_BUS_FMT_RGB666_1X18: s->output_mode = ROCKCHIP_OUT_MODE_P666; @@ -304,6 +306,8 @@ rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder, case MEDIA_BUS_FMT_VYUY8_2X8: s->output_mode = ROCKCHIP_OUT_MODE_BT656; s->output_if = VOP_OUTPUT_IF_BT656; + s->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; + s->color_encoding = DRM_COLOR_YCBCR_BT601; break; case MEDIA_BUS_FMT_YUYV8_1X16: case MEDIA_BUS_FMT_YVYU8_1X16: @@ -311,6 +315,7 @@ rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder, case MEDIA_BUS_FMT_VYUY8_1X16: s->output_mode = ROCKCHIP_OUT_MODE_BT1120; s->output_if = VOP_OUTPUT_IF_BT1120; + s->color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; break; case MEDIA_BUS_FMT_RGB888_1X24: case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: @@ -324,7 +329,6 @@ rockchip_rgb_encoder_atomic_check(struct drm_encoder *encoder, s->bus_flags = info->bus_flags; s->tv_state = &conn_state->tv; s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR; - s->color_space = V4L2_COLORSPACE_DEFAULT; return 0; }