From ef534507e63b97d9b2d8473563e5617954148824 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 6 Mar 2020 20:26:29 +0100 Subject: [PATCH] Allwinner: Linux: Improve colour management --- .../linux/0001-backport-from-5.6.patch | 497 ++++++++++++++++++ .../linux/0003-hdmi-improvements.patch | 155 +++++- .../patches/linux/0013-force-full-range.patch | 43 -- 3 files changed, 647 insertions(+), 48 deletions(-) delete mode 100644 projects/Allwinner/patches/linux/0013-force-full-range.patch diff --git a/projects/Allwinner/patches/linux/0001-backport-from-5.6.patch b/projects/Allwinner/patches/linux/0001-backport-from-5.6.patch index 8b32b6543a..e2513e9290 100644 --- a/projects/Allwinner/patches/linux/0001-backport-from-5.6.patch +++ b/projects/Allwinner/patches/linux/0001-backport-from-5.6.patch @@ -1900,3 +1900,500 @@ index c17d30e74bb1..ce497d0197df 100644 -- 2.24.1 +From deda8aa0bedde60a7a8e0b471acad67bce60670b Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Tue, 18 Feb 2020 17:52:59 +0100 +Subject: [PATCH 1/7] drm/sun4i: de2/de3: Remove unsupported VI layer formats + +YUV444 and YVU444 are planar formats, but HW format RGB888 is packed. +This means that those two mappings were never correct. Remove them. + +Fixes: 60a3dcf96aa8 ("drm/sun4i: Add DE2 definitions for YUV formats") +Signed-off-by: Jernej Skrabec +--- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 12 ------------ + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 2 -- + 2 files changed, 14 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index 7c24f8f832a5..3a78dbbceb8a 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -196,12 +196,6 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, +- { +- .drm_fmt = DRM_FORMAT_YUV444, +- .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, +- .rgb = true, +- .csc = SUN8I_CSC_MODE_YUV2RGB, +- }, + { + .drm_fmt = DRM_FORMAT_YUV422, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, +@@ -220,12 +214,6 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = false, + .csc = SUN8I_CSC_MODE_YUV2RGB, + }, +- { +- .drm_fmt = DRM_FORMAT_YVU444, +- .de2_fmt = SUN8I_MIXER_FBFMT_RGB888, +- .rgb = true, +- .csc = SUN8I_CSC_MODE_YVU2RGB, +- }, + { + .drm_fmt = DRM_FORMAT_YVU422, + .de2_fmt = SUN8I_MIXER_FBFMT_YUV422, +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index 42d445d23773..6a244d6fafd9 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -431,11 +431,9 @@ static const u32 sun8i_vi_layer_formats[] = { + DRM_FORMAT_YUV411, + DRM_FORMAT_YUV420, + DRM_FORMAT_YUV422, +- DRM_FORMAT_YUV444, + DRM_FORMAT_YVU411, + DRM_FORMAT_YVU420, + DRM_FORMAT_YVU422, +- DRM_FORMAT_YVU444, + }; + + struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, +-- +2.25.1 + +From 3d1e6278957050416a425e0b2f3108c1e070ef4f Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Mon, 17 Feb 2020 17:32:10 +0100 +Subject: [PATCH 2/7] drm/sun4i: Add separate DE3 VI layer formats + +DE3 VI layers support alpha blending, but DE2 VI layers do not. +Additionally, DE3 VI layers support 10-bit RGB and YUV formats. + +Make a separate list for DE3. + +Fixes: c50519e6db4d ("drm/sun4i: Add basic support for DE3") +Signed-off-by: Jernej Skrabec +--- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 36 ++++++++++++++++ + drivers/gpu/drm/sun4i/sun8i_mixer.h | 11 +++++ + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 58 ++++++++++++++++++++++++-- + 3 files changed, 102 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index 3a78dbbceb8a..655445bfe64a 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -148,6 +148,30 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ .drm_fmt = DRM_FORMAT_ARGB2101010, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ARGB2101010, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_ABGR2101010, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ABGR2101010, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_RGBA1010102, ++ .de2_fmt = SUN8I_MIXER_FBFMT_RGBA1010102, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_BGRA1010102, ++ .de2_fmt = SUN8I_MIXER_FBFMT_BGRA1010102, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_UYVY, + .de2_fmt = SUN8I_MIXER_FBFMT_UYVY, +@@ -232,6 +256,18 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = false, + .csc = SUN8I_CSC_MODE_YVU2RGB, + }, ++ { ++ .drm_fmt = DRM_FORMAT_P010, ++ .de2_fmt = SUN8I_MIXER_FBFMT_P010_YUV, ++ .rgb = false, ++ .csc = SUN8I_CSC_MODE_YUV2RGB, ++ }, ++ { ++ .drm_fmt = DRM_FORMAT_P210, ++ .de2_fmt = SUN8I_MIXER_FBFMT_P210_YUV, ++ .rgb = false, ++ .csc = SUN8I_CSC_MODE_YUV2RGB, ++ }, + }; + + const struct de2_fmt_info *sun8i_mixer_format_info(u32 format) +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h +index c6cc94057faf..345b28b0a80a 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.h ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h +@@ -93,6 +93,10 @@ + #define SUN8I_MIXER_FBFMT_ABGR1555 17 + #define SUN8I_MIXER_FBFMT_RGBA5551 18 + #define SUN8I_MIXER_FBFMT_BGRA5551 19 ++#define SUN8I_MIXER_FBFMT_ARGB2101010 20 ++#define SUN8I_MIXER_FBFMT_ABGR2101010 21 ++#define SUN8I_MIXER_FBFMT_RGBA1010102 22 ++#define SUN8I_MIXER_FBFMT_BGRA1010102 23 + + #define SUN8I_MIXER_FBFMT_YUYV 0 + #define SUN8I_MIXER_FBFMT_UYVY 1 +@@ -109,6 +113,13 @@ + /* format 12 is semi-planar YUV411 UVUV */ + /* format 13 is semi-planar YUV411 VUVU */ + #define SUN8I_MIXER_FBFMT_YUV411 14 ++/* format 15 doesn't exist */ ++/* format 16 is P010 YVU */ ++#define SUN8I_MIXER_FBFMT_P010_YUV 17 ++/* format 18 is P210 YVU */ ++#define SUN8I_MIXER_FBFMT_P210_YUV 19 ++/* format 20 is packed YVU444 10-bit */ ++/* format 21 is packed YUV444 10-bit */ + + /* + * Sub-engines listed bellow are unused for now. The EN registers are here only +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index 6a244d6fafd9..6c0084a3c3d7 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -436,24 +436,76 @@ static const u32 sun8i_vi_layer_formats[] = { + DRM_FORMAT_YVU422, + }; + ++static const u32 sun8i_vi_layer_de3_formats[] = { ++ DRM_FORMAT_ABGR1555, ++ DRM_FORMAT_ABGR2101010, ++ DRM_FORMAT_ABGR4444, ++ DRM_FORMAT_ABGR8888, ++ DRM_FORMAT_ARGB1555, ++ DRM_FORMAT_ARGB2101010, ++ DRM_FORMAT_ARGB4444, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_BGR565, ++ DRM_FORMAT_BGR888, ++ DRM_FORMAT_BGRA1010102, ++ DRM_FORMAT_BGRA5551, ++ DRM_FORMAT_BGRA4444, ++ DRM_FORMAT_BGRA8888, ++ DRM_FORMAT_BGRX8888, ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_RGB888, ++ DRM_FORMAT_RGBA1010102, ++ DRM_FORMAT_RGBA4444, ++ DRM_FORMAT_RGBA5551, ++ DRM_FORMAT_RGBA8888, ++ DRM_FORMAT_RGBX8888, ++ DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_XRGB8888, ++ ++ DRM_FORMAT_NV16, ++ DRM_FORMAT_NV12, ++ DRM_FORMAT_NV21, ++ DRM_FORMAT_NV61, ++ DRM_FORMAT_P010, ++ DRM_FORMAT_P210, ++ DRM_FORMAT_UYVY, ++ DRM_FORMAT_VYUY, ++ DRM_FORMAT_YUYV, ++ DRM_FORMAT_YVYU, ++ DRM_FORMAT_YUV411, ++ DRM_FORMAT_YUV420, ++ DRM_FORMAT_YUV422, ++ DRM_FORMAT_YVU411, ++ DRM_FORMAT_YVU420, ++ DRM_FORMAT_YVU422, ++}; ++ + struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, + struct sun8i_mixer *mixer, + int index) + { + u32 supported_encodings, supported_ranges; ++ unsigned int plane_cnt, format_count; + struct sun8i_vi_layer *layer; +- unsigned int plane_cnt; ++ const u32 *formats; + int ret; + + layer = devm_kzalloc(drm->dev, sizeof(*layer), GFP_KERNEL); + if (!layer) + return ERR_PTR(-ENOMEM); + ++ if (mixer->cfg->is_de3) { ++ formats = sun8i_vi_layer_de3_formats; ++ format_count = ARRAY_SIZE(sun8i_vi_layer_de3_formats); ++ } else { ++ formats = sun8i_vi_layer_formats; ++ format_count = ARRAY_SIZE(sun8i_vi_layer_formats); ++ } ++ + /* possible crtcs are set later */ + ret = drm_universal_plane_init(drm, &layer->plane, 0, + &sun8i_vi_layer_funcs, +- sun8i_vi_layer_formats, +- ARRAY_SIZE(sun8i_vi_layer_formats), ++ formats, format_count, + NULL, DRM_PLANE_TYPE_OVERLAY, NULL); + if (ret) { + dev_err(drm->dev, "Couldn't initialize layer\n"); +-- +2.25.1 + +From 9cdf885761bd5fc00ad3a34249b083999e4a0b8c Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Mon, 17 Feb 2020 18:02:46 +0100 +Subject: [PATCH 3/7] drm/sun4i: Fix DE2 VI layer format support + +DE2 VI layer doesn't support blending which means alpha channel is +ignored. Replace all formats with alpha with "don't care" (X) channel. + +Signed-off-by: Jernej Skrabec +--- + drivers/gpu/drm/sun4i/sun8i_mixer.c | 56 ++++++++++++++++++++++++++ + drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 22 +++++----- + 2 files changed, 67 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c +index 655445bfe64a..4a64f7ae437a 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_mixer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c +@@ -106,48 +106,104 @@ static const struct de2_fmt_info de2_formats[] = { + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_XRGB4444, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ARGB4444, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_ABGR4444, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_XBGR4444, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ABGR4444, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_RGBA4444, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_RGBX4444, ++ .de2_fmt = SUN8I_MIXER_FBFMT_RGBA4444, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_BGRA4444, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_BGRX4444, ++ .de2_fmt = SUN8I_MIXER_FBFMT_BGRA4444, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_ARGB1555, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_XRGB1555, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ARGB1555, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_ABGR1555, + .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_XBGR1555, ++ .de2_fmt = SUN8I_MIXER_FBFMT_ABGR1555, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_RGBA5551, + .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_RGBX5551, ++ .de2_fmt = SUN8I_MIXER_FBFMT_RGBA5551, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_BGRA5551, + .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, + .rgb = true, + .csc = SUN8I_CSC_MODE_OFF, + }, ++ { ++ /* for DE2 VI layer which ignores alpha */ ++ .drm_fmt = DRM_FORMAT_BGRX5551, ++ .de2_fmt = SUN8I_MIXER_FBFMT_BGRA5551, ++ .rgb = true, ++ .csc = SUN8I_CSC_MODE_OFF, ++ }, + { + .drm_fmt = DRM_FORMAT_ARGB2101010, + .de2_fmt = SUN8I_MIXER_FBFMT_ARGB2101010, +diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +index 6c0084a3c3d7..b8398ca18b0f 100644 +--- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c ++++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +@@ -398,26 +398,26 @@ static const struct drm_plane_funcs sun8i_vi_layer_funcs = { + }; + + /* +- * While all RGB formats are supported, VI planes don't support +- * alpha blending, so there is no point having formats with alpha +- * channel if their opaque analog exist. ++ * While DE2 VI layer supports same RGB formats as UI layer, alpha ++ * channel is ignored. This structure lists all unique variants ++ * where alpha channel is replaced with "don't care" (X) channel. + */ + static const u32 sun8i_vi_layer_formats[] = { +- DRM_FORMAT_ABGR1555, +- DRM_FORMAT_ABGR4444, +- DRM_FORMAT_ARGB1555, +- DRM_FORMAT_ARGB4444, + DRM_FORMAT_BGR565, + DRM_FORMAT_BGR888, +- DRM_FORMAT_BGRA5551, +- DRM_FORMAT_BGRA4444, ++ DRM_FORMAT_BGRX4444, ++ DRM_FORMAT_BGRX5551, + DRM_FORMAT_BGRX8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, +- DRM_FORMAT_RGBA4444, +- DRM_FORMAT_RGBA5551, ++ DRM_FORMAT_RGBX4444, ++ DRM_FORMAT_RGBX5551, + DRM_FORMAT_RGBX8888, ++ DRM_FORMAT_XBGR1555, ++ DRM_FORMAT_XBGR4444, + DRM_FORMAT_XBGR8888, ++ DRM_FORMAT_XRGB1555, ++ DRM_FORMAT_XRGB4444, + DRM_FORMAT_XRGB8888, + + DRM_FORMAT_NV16, +-- +2.25.1 + +From ad659ce8a20e12b2508c977818e8c21487f67793 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sat, 29 Feb 2020 09:49:49 +0100 +Subject: [PATCH v2 1/4] drm/bridge: dw-hdmi: fix AVI frame colorimetry + +CTA-861-F explicitly states that for RGB colorspace colorimetry should +be set to "none". Fix that. + +Acked-by: Laurent Pinchart +Fixes: def23aa7e982 ("drm: bridge: dw-hdmi: Switch to V4L bus format and encodings") +Signed-off-by: Jernej Skrabec +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 46 +++++++++++++---------- + 1 file changed, 26 insertions(+), 20 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index 67fca439bbfb..24965e53d351 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1624,28 +1624,34 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + frame.colorspace = HDMI_COLORSPACE_RGB; + + /* Set up colorimetry */ +- switch (hdmi->hdmi_data.enc_out_encoding) { +- case V4L2_YCBCR_ENC_601: +- if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) +- frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; +- else ++ if (!hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { ++ switch (hdmi->hdmi_data.enc_out_encoding) { ++ case V4L2_YCBCR_ENC_601: ++ if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV601) ++ frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; ++ else ++ frame.colorimetry = HDMI_COLORIMETRY_ITU_601; ++ frame.extended_colorimetry = ++ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; ++ break; ++ case V4L2_YCBCR_ENC_709: ++ if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) ++ frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; ++ else ++ frame.colorimetry = HDMI_COLORIMETRY_ITU_709; ++ frame.extended_colorimetry = ++ HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; ++ break; ++ default: /* Carries no data */ + frame.colorimetry = HDMI_COLORIMETRY_ITU_601; ++ frame.extended_colorimetry = ++ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; ++ break; ++ } ++ } else { ++ frame.colorimetry = HDMI_COLORIMETRY_NONE; + frame.extended_colorimetry = +- HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; +- break; +- case V4L2_YCBCR_ENC_709: +- if (hdmi->hdmi_data.enc_in_encoding == V4L2_YCBCR_ENC_XV709) +- frame.colorimetry = HDMI_COLORIMETRY_EXTENDED; +- else +- frame.colorimetry = HDMI_COLORIMETRY_ITU_709; +- frame.extended_colorimetry = +- HDMI_EXTENDED_COLORIMETRY_XV_YCC_709; +- break; +- default: /* Carries no data */ +- frame.colorimetry = HDMI_COLORIMETRY_ITU_601; +- frame.extended_colorimetry = +- HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; +- break; ++ HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; + } + + frame.scan_mode = HDMI_SCAN_MODE_NONE; +-- +2.25.1 + diff --git a/projects/Allwinner/patches/linux/0003-hdmi-improvements.patch b/projects/Allwinner/patches/linux/0003-hdmi-improvements.patch index 59af29dd52..35c4dcefa4 100644 --- a/projects/Allwinner/patches/linux/0003-hdmi-improvements.patch +++ b/projects/Allwinner/patches/linux/0003-hdmi-improvements.patch @@ -555,22 +555,33 @@ index dff27934287c..c922639e25eb 100644 ddc_node = of_parse_phandle(np, "ddc-i2c-bus", 0); -From 59c0e09a4133d36772397e59224fd32f1410cc26 Mon Sep 17 00:00:00 2001 +From cb6130315f4ae856051725b2de4e208ed90eb740 Mon Sep 17 00:00:00 2001 From: Jonas Karlman Date: Sun, 8 Dec 2019 23:41:44 +0000 -Subject: [PATCH] WIP: drm: dw-hdmi: do not force none scan mode +Subject: [PATCH v2 2/4] drm/bridge: dw-hdmi: do not force "none" scan mode +Setting scan mode to "none" confuses some TVs like LG B8, which randomly +change overscan percentage over time. Digital outputs like HDMI and DVI, +handled by this controller, don't really need overscan, so we can always +set scan mode to underscan. Actually, this is exactly what +drm_hdmi_avi_infoframe_from_display_mode() already does, so we can just +remove offending line. + +Reviewed-by: Neil Armstrong +Acked-by: Laurent Pinchart Signed-off-by: Jonas Karlman +[updated commit message] +Signed-off-by: Jernej Skrabec --- drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -index c922639e25eb..ea4f940406fc 100644 +index 24965e53d351..de2c7ec887c8 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c -@@ -1658,8 +1658,6 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) - break; +@@ -1654,8 +1654,6 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + HDMI_EXTENDED_COLORIMETRY_XV_YCC_601; } - frame.scan_mode = HDMI_SCAN_MODE_NONE; @@ -578,4 +589,138 @@ index c922639e25eb..ea4f940406fc 100644 /* * The Designware IP uses a different byte format from standard * AVI info frames, though generally the bits are in the correct +-- +2.25.1 + +From 3043a1caa3f6d26128c746b991d086bbb85d50c2 Mon Sep 17 00:00:00 2001 +From: Jernej Skrabec +Date: Sat, 29 Feb 2020 16:23:38 +0100 +Subject: [PATCH v2 3/4] drm/bridge: dw-hdmi: Add support for RGB limited range + +CEA 861 standard requestis that RGB quantization range is "limited" for +CEA modes. Support that by adding CSC matrix which downscales values. + +This allows proper color reproduction on TV and PC monitor at the same +time. In future, override property can be added, like "Broadcast RGB" +in i915 driver. + +Signed-off-by: Jernej Skrabec +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 63 +++++++++++++++++------ + 1 file changed, 46 insertions(+), 17 deletions(-) + +diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +index de2c7ec887c8..c8a02e5b5e1b 100644 +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -92,6 +92,12 @@ static const u16 csc_coeff_rgb_in_eitu709[3][4] = { + { 0x6756, 0x78ab, 0x2000, 0x0200 } + }; + ++static const u16 csc_coeff_rgb_full_to_rgb_limited[3][4] = { ++ { 0x1b7c, 0x0000, 0x0000, 0x0020 }, ++ { 0x0000, 0x1b7c, 0x0000, 0x0020 }, ++ { 0x0000, 0x0000, 0x1b7c, 0x0020 } ++}; ++ + struct hdmi_vmode { + bool mdataenablepolarity; + +@@ -109,6 +115,7 @@ struct hdmi_data_info { + unsigned int pix_repet_factor; + unsigned int hdcp_enable; + struct hdmi_vmode video_mode; ++ bool rgb_limited_range; + }; + + struct dw_hdmi_i2c { +@@ -956,7 +963,11 @@ static void hdmi_video_sample(struct dw_hdmi *hdmi) + + static int is_color_space_conversion(struct dw_hdmi *hdmi) + { +- return hdmi->hdmi_data.enc_in_bus_format != hdmi->hdmi_data.enc_out_bus_format; ++ return (hdmi->hdmi_data.enc_in_bus_format != ++ hdmi->hdmi_data.enc_out_bus_format) || ++ (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format) && ++ hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format) && ++ hdmi->hdmi_data.rgb_limited_range); + } + + static int is_color_space_decimation(struct dw_hdmi *hdmi) +@@ -986,25 +997,27 @@ static int is_color_space_interpolation(struct dw_hdmi *hdmi) + static void dw_hdmi_update_csc_coeffs(struct dw_hdmi *hdmi) + { + const u16 (*csc_coeff)[3][4] = &csc_coeff_default; ++ bool is_input_rgb, is_output_rgb; + unsigned i; + u32 csc_scale = 1; + +- if (is_color_space_conversion(hdmi)) { +- if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { +- if (hdmi->hdmi_data.enc_out_encoding == +- V4L2_YCBCR_ENC_601) +- csc_coeff = &csc_coeff_rgb_out_eitu601; +- else +- csc_coeff = &csc_coeff_rgb_out_eitu709; +- } else if (hdmi_bus_fmt_is_rgb( +- hdmi->hdmi_data.enc_in_bus_format)) { +- if (hdmi->hdmi_data.enc_out_encoding == +- V4L2_YCBCR_ENC_601) +- csc_coeff = &csc_coeff_rgb_in_eitu601; +- else +- csc_coeff = &csc_coeff_rgb_in_eitu709; +- csc_scale = 0; +- } ++ is_input_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_in_bus_format); ++ is_output_rgb = hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format); ++ ++ if (!is_input_rgb && is_output_rgb) { ++ if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601) ++ csc_coeff = &csc_coeff_rgb_out_eitu601; ++ else ++ csc_coeff = &csc_coeff_rgb_out_eitu709; ++ } else if (is_input_rgb && !is_output_rgb) { ++ if (hdmi->hdmi_data.enc_out_encoding == V4L2_YCBCR_ENC_601) ++ csc_coeff = &csc_coeff_rgb_in_eitu601; ++ else ++ csc_coeff = &csc_coeff_rgb_in_eitu709; ++ csc_scale = 0; ++ } else if (is_input_rgb && is_output_rgb && ++ hdmi->hdmi_data.rgb_limited_range) { ++ csc_coeff = &csc_coeff_rgb_full_to_rgb_limited; + } + + /* The CSC registers are sequential, alternating MSB then LSB */ +@@ -1614,6 +1627,18 @@ static void hdmi_config_AVI(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + drm_hdmi_avi_infoframe_from_display_mode(&frame, + &hdmi->connector, mode); + ++ if (hdmi_bus_fmt_is_rgb(hdmi->hdmi_data.enc_out_bus_format)) { ++ drm_hdmi_avi_infoframe_quant_range(&frame, &hdmi->connector, ++ mode, ++ hdmi->hdmi_data.rgb_limited_range ? ++ HDMI_QUANTIZATION_RANGE_LIMITED : ++ HDMI_QUANTIZATION_RANGE_FULL); ++ } else { ++ frame.quantization_range = HDMI_QUANTIZATION_RANGE_DEFAULT; ++ frame.ycc_quantization_range = ++ HDMI_YCC_QUANTIZATION_RANGE_LIMITED; ++ } ++ + if (hdmi_bus_fmt_is_yuv444(hdmi->hdmi_data.enc_out_bus_format)) + frame.colorspace = HDMI_COLORSPACE_YUV444; + else if (hdmi_bus_fmt_is_yuv422(hdmi->hdmi_data.enc_out_bus_format)) +@@ -2099,6 +2124,10 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode) + /* TOFIX: Default to RGB888 output format */ + hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; + ++ hdmi->hdmi_data.rgb_limited_range = hdmi->sink_is_hdmi && ++ drm_default_rgb_quant_range(mode) == ++ HDMI_QUANTIZATION_RANGE_LIMITED; ++ + hdmi->hdmi_data.pix_repet_factor = 0; + hdmi->hdmi_data.hdcp_enable = 0; + hdmi->hdmi_data.video_mode.mdataenablepolarity = true; +-- +2.25.1 diff --git a/projects/Allwinner/patches/linux/0013-force-full-range.patch b/projects/Allwinner/patches/linux/0013-force-full-range.patch deleted file mode 100644 index edb1240a5e..0000000000 --- a/projects/Allwinner/patches/linux/0013-force-full-range.patch +++ /dev/null @@ -1,43 +0,0 @@ -From c8217462c6c143a9fada595bf3e34af83eb15f87 Mon Sep 17 00:00:00 2001 -From: Jernej Skrabec -Date: Thu, 27 Jun 2019 21:50:16 +0200 -Subject: [PATCH 4/4] HACK: Force full range - -Signed-off-by: Jernej Skrabec ---- - drivers/gpu/drm/sun4i/sun8i_csc.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c -index 70c792d052fe..7b60fce1a8c6 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_csc.c -+++ b/drivers/gpu/drm/sun4i/sun8i_csc.c -@@ -160,10 +160,10 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, - - switch (mode) { - case SUN8I_CSC_MODE_YUV2RGB: -- table = yuv2rgb[range][encoding]; -+ table = yuv2rgb[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; - break; - case SUN8I_CSC_MODE_YVU2RGB: -- table = yvu2rgb[range][encoding]; -+ table = yvu2rgb[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; - break; - default: - DRM_WARN("Wrong CSC mode specified.\n"); -@@ -184,10 +184,10 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, - - switch (mode) { - case SUN8I_CSC_MODE_YUV2RGB: -- table = yuv2rgb_de3[range][encoding]; -+ table = yuv2rgb_de3[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; - break; - case SUN8I_CSC_MODE_YVU2RGB: -- table = yvu2rgb_de3[range][encoding]; -+ table = yvu2rgb_de3[DRM_COLOR_YCBCR_FULL_RANGE][encoding]; - break; - default: - DRM_WARN("Wrong CSC mode specified.\n"); --- -2.22.0 -