From 99be71187b6b31f7afdd45a35c369a5ace621786 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 10 Jan 2021 21:19:45 +0100 Subject: drm/sun4i: csc: Rework DE3 CSC macros Rework DE3 CSC macros to take just one coordinate instead of two. This will make its usage easier in subsequent commit. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20210110201947.3611649-2-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_csc.c | 2 +- drivers/gpu/drm/sun4i/sun8i_mixer.h | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/sun4i') diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c index 781955dd4995..5c6ad643dae2 100644 --- a/drivers/gpu/drm/sun4i/sun8i_csc.c +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c @@ -194,7 +194,7 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, return; } - base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0, 0); + base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); regmap_bulk_write(map, base_reg, table, 12); } diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h index 7576b523fdbb..145833a9d82d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h @@ -50,10 +50,8 @@ #define SUN8I_MIXER_BLEND_CK_MIN(base, x) ((base) + 0xe0 + 0x04 * (x)) #define SUN8I_MIXER_BLEND_OUTCTL(base) ((base) + 0xfc) #define SUN50I_MIXER_BLEND_CSC_CTL(base) ((base) + 0x100) -#define SUN50I_MIXER_BLEND_CSC_COEFF(base, layer, x, y) \ - ((base) + 0x110 + (layer) * 0x30 + (x) * 0x10 + 4 * (y)) -#define SUN50I_MIXER_BLEND_CSC_CONST(base, layer, i) \ - ((base) + 0x110 + (layer) * 0x30 + (i) * 0x10 + 0x0c) +#define SUN50I_MIXER_BLEND_CSC_COEFF(base, layer, x) \ + ((base) + 0x110 + (layer) * 0x30 + (x) * 4) #define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK GENMASK(12, 8) #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe) BIT(8 + pipe) -- cgit v1.2.3 From ea067aee45a80c90d170db3de8d80e449665a587 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 10 Jan 2021 21:19:46 +0100 Subject: drm/sun4i: de2/de3: Remove redundant CSC matrices YUV to RGB matrices are almost identical to YVU to RGB matrices. They only have second and third column reversed. Do that reversion in code in order to lower amount of static data and redundancy. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20210110201947.3611649-3-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_csc.c | 99 ++++++++++++++------------------------- 1 file changed, 34 insertions(+), 65 deletions(-) (limited to 'drivers/gpu/drm/sun4i') diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c index 5c6ad643dae2..1d10714e417e 100644 --- a/drivers/gpu/drm/sun4i/sun8i_csc.c +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c @@ -46,33 +46,6 @@ static const u32 yuv2rgb[2][2][12] = { }, }; -static const u32 yvu2rgb[2][2][12] = { - [DRM_COLOR_YCBCR_LIMITED_RANGE] = { - [DRM_COLOR_YCBCR_BT601] = { - 0x000004A8, 0x00000662, 0x00000000, 0xFFFC8451, - 0x000004A8, 0xFFFFFCC0, 0xFFFFFE6F, 0x00021E4D, - 0x000004A8, 0x00000000, 0x00000811, 0xFFFBACA9, - }, - [DRM_COLOR_YCBCR_BT709] = { - 0x000004A8, 0x0000072B, 0x00000000, 0xFFFC1F99, - 0x000004A8, 0xFFFFFDDF, 0xFFFFFF26, 0x00013383, - 0x000004A8, 0x00000000, 0x00000873, 0xFFFB7BEF, - } - }, - [DRM_COLOR_YCBCR_FULL_RANGE] = { - [DRM_COLOR_YCBCR_BT601] = { - 0x00000400, 0x0000059B, 0x00000000, 0xFFFD322E, - 0x00000400, 0xFFFFFD25, 0xFFFFFEA0, 0x00021DD5, - 0x00000400, 0x00000000, 0x00000716, 0xFFFC74BD, - }, - [DRM_COLOR_YCBCR_BT709] = { - 0x00000400, 0x0000064C, 0x00000000, 0xFFFCD9B4, - 0x00000400, 0xFFFFFE21, 0xFFFFFF41, 0x00014F96, - 0x00000400, 0x00000000, 0x0000076C, 0xFFFC49EF, - } - }, -}; - /* * DE3 has a bit different CSC units. Factors are in two's complement format. * First three factors in a row are multiplication factors which have 17 bits @@ -123,33 +96,6 @@ static const u32 yuv2rgb_de3[2][2][12] = { }, }; -static const u32 yvu2rgb_de3[2][2][12] = { - [DRM_COLOR_YCBCR_LIMITED_RANGE] = { - [DRM_COLOR_YCBCR_BT601] = { - 0x0002542A, 0x0003312A, 0x00000000, 0xFFC00000, - 0x0002542A, 0xFFFE5FC3, 0xFFFF376B, 0xFE000000, - 0x0002542A, 0x00000000, 0x000408D2, 0xFE000000, - }, - [DRM_COLOR_YCBCR_BT709] = { - 0x0002542A, 0x000395E2, 0x00000000, 0xFFC00000, - 0x0002542A, 0xFFFEEF27, 0xFFFF92D2, 0xFE000000, - 0x0002542A, 0x00000000, 0x0004398C, 0xFE000000, - } - }, - [DRM_COLOR_YCBCR_FULL_RANGE] = { - [DRM_COLOR_YCBCR_BT601] = { - 0x00020000, 0x0002CDD2, 0x00000000, 0x00000000, - 0x00020000, 0xFFFE925D, 0xFFFF4FCE, 0xFE000000, - 0x00020000, 0x00000000, 0x00038B43, 0xFE000000, - }, - [DRM_COLOR_YCBCR_BT709] = { - 0x00020000, 0x0003264C, 0x00000000, 0x00000000, - 0x00020000, 0xFFFF1053, 0xFFFFA018, 0xFE000000, - 0x00020000, 0x00000000, 0x0003B611, 0xFE000000, - } - }, -}; - static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, enum sun8i_csc_mode mode, enum drm_color_encoding encoding, @@ -157,21 +103,30 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, { const u32 *table; u32 base_reg; + int i; + + table = yuv2rgb[range][encoding]; switch (mode) { case SUN8I_CSC_MODE_YUV2RGB: - table = yuv2rgb[range][encoding]; + base_reg = SUN8I_CSC_COEFF(base, 0); + regmap_bulk_write(map, base_reg, table, 12); break; case SUN8I_CSC_MODE_YVU2RGB: - table = yvu2rgb[range][encoding]; + for (i = 0; i < 12; i++) { + if ((i & 3) == 1) + base_reg = SUN8I_CSC_COEFF(base, i + 1); + else if ((i & 3) == 2) + base_reg = SUN8I_CSC_COEFF(base, i - 1); + else + base_reg = SUN8I_CSC_COEFF(base, i); + regmap_write(map, base_reg, table[i]); + } break; default: DRM_WARN("Wrong CSC mode specified.\n"); return; } - - base_reg = SUN8I_CSC_COEFF(base, 0); - regmap_bulk_write(map, base_reg, table, 12); } static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, @@ -180,22 +135,36 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, enum drm_color_range range) { const u32 *table; - u32 base_reg; + u32 addr; + int i; + + table = yuv2rgb_de3[range][encoding]; switch (mode) { case SUN8I_CSC_MODE_YUV2RGB: - table = yuv2rgb_de3[range][encoding]; + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); + regmap_bulk_write(map, addr, table, 12); break; case SUN8I_CSC_MODE_YVU2RGB: - table = yvu2rgb_de3[range][encoding]; + for (i = 0; i < 12; i++) { + if ((i & 3) == 1) + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, + layer, + i + 1); + else if ((i & 3) == 2) + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, + layer, + i - 1); + else + addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, + layer, i); + regmap_write(map, addr, table[i]); + } break; default: DRM_WARN("Wrong CSC mode specified.\n"); return; } - - base_reg = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); - regmap_bulk_write(map, base_reg, table, 12); } static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable) -- cgit v1.2.3 From 0cf1d704048a52ead7366b9e763b1754a9352b56 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 10 Jan 2021 21:19:47 +0100 Subject: drm/sun4i: Add support for BT2020 to DE3 DE3 supports 10-bit formats, so it's only naturally to also support BT2020 encoding. Add support for it. Signed-off-by: Jernej Skrabec Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20210110201947.3611649-4-jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun8i_csc.c | 12 +++++++++++- drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 2 ++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/gpu/drm/sun4i') diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c index 1d10714e417e..9bd62de0c288 100644 --- a/drivers/gpu/drm/sun4i/sun8i_csc.c +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c @@ -69,7 +69,7 @@ static const u32 yuv2rgb[2][2][12] = { * c20 c21 c22 [d2 const2] */ -static const u32 yuv2rgb_de3[2][2][12] = { +static const u32 yuv2rgb_de3[2][3][12] = { [DRM_COLOR_YCBCR_LIMITED_RANGE] = { [DRM_COLOR_YCBCR_BT601] = { 0x0002542A, 0x00000000, 0x0003312A, 0xFFC00000, @@ -80,6 +80,11 @@ static const u32 yuv2rgb_de3[2][2][12] = { 0x0002542A, 0x00000000, 0x000395E2, 0xFFC00000, 0x0002542A, 0xFFFF92D2, 0xFFFEEF27, 0xFE000000, 0x0002542A, 0x0004398C, 0x00000000, 0xFE000000, + }, + [DRM_COLOR_YCBCR_BT2020] = { + 0x0002542A, 0x00000000, 0x00035B7B, 0xFFC00000, + 0x0002542A, 0xFFFFA017, 0xFFFEB2FC, 0xFE000000, + 0x0002542A, 0x00044896, 0x00000000, 0xFE000000, } }, [DRM_COLOR_YCBCR_FULL_RANGE] = { @@ -92,6 +97,11 @@ static const u32 yuv2rgb_de3[2][2][12] = { 0x00020000, 0x00000000, 0x0003264C, 0x00000000, 0x00020000, 0xFFFFA018, 0xFFFF1053, 0xFE000000, 0x00020000, 0x0003B611, 0x00000000, 0xFE000000, + }, + [DRM_COLOR_YCBCR_BT2020] = { + 0x00020000, 0x00000000, 0x0002F2FE, 0x00000000, + 0x00020000, 0xFFFFABC0, 0xFFFEDB78, 0xFE000000, + 0x00020000, 0x0003C346, 0x00000000, 0xFE000000, } }, }; diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c index 76393fc976fe..8cc294a9969d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c @@ -543,6 +543,8 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, supported_encodings = BIT(DRM_COLOR_YCBCR_BT601) | BIT(DRM_COLOR_YCBCR_BT709); + if (mixer->cfg->is_de3) + supported_encodings |= BIT(DRM_COLOR_YCBCR_BT2020); supported_ranges = BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | BIT(DRM_COLOR_YCBCR_FULL_RANGE); -- cgit v1.2.3 From 67f4aeb2b41a0629abde3794d463547f60b0cbdd Mon Sep 17 00:00:00 2001 From: Giulio Benetti Date: Thu, 14 Jan 2021 09:17:32 +0100 Subject: drm/sun4i: tcon: fix inverted DCLK polarity During commit 88bc4178568b ("drm: Use new DRM_BUS_FLAG_*_(DRIVE|SAMPLE)_(POS|NEG)EDGE flags") DRM_BUS_FLAG_* macros have been changed to avoid ambiguity but just because of this ambiguity previous DRM_BUS_FLAG_PIXDATA_(POS/NEG)EDGE were used meaning _SAMPLE_ not _DRIVE_. This leads to DLCK inversion and need to fix but instead of swapping phase values, let's adopt an easier approach Maxime suggested: It turned out that bit 26 of SUN4I_TCON0_IO_POL_REG is dedicated to invert DCLK polarity and this makes things really easier than before. So let's handle DCLK polarity by adding SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE as bit 26 and activating according to bus_flags the same way it is done for all the other signals polarity. Fixes: 88bc4178568b ("drm: Use new DRM_BUS_FLAG_*_(DRIVE|SAMPLE)_(POS|NEG)EDGE flags") Suggested-by: Maxime Ripard Signed-off-by: Giulio Benetti Signed-off-by: Maxime Ripard Link: https://patchwork.freedesktop.org/patch/msgid/20210114081732.9386-1-giulio.benetti@benettiengineering.com --- drivers/gpu/drm/sun4i/sun4i_tcon.c | 21 ++------------------- drivers/gpu/drm/sun4i/sun4i_tcon.h | 1 + 2 files changed, 3 insertions(+), 19 deletions(-) (limited to 'drivers/gpu/drm/sun4i') diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index eaaf5d70e352..6b9af4c08cd6 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -569,30 +569,13 @@ static void sun4i_tcon0_mode_set_rgb(struct sun4i_tcon *tcon, if (info->bus_flags & DRM_BUS_FLAG_DE_LOW) val |= SUN4I_TCON0_IO_POL_DE_NEGATIVE; - /* - * On A20 and similar SoCs, the only way to achieve Positive Edge - * (Rising Edge), is setting dclk clock phase to 2/3(240°). - * By default TCON works in Negative Edge(Falling Edge), - * this is why phase is set to 0 in that case. - * Unfortunately there's no way to logically invert dclk through - * IO_POL register. - * The only acceptable way to work, triple checked with scope, - * is using clock phase set to 0° for Negative Edge and set to 240° - * for Positive Edge. - * On A33 and similar SoCs there would be a 90° phase option, - * but it divides also dclk by 2. - * Following code is a way to avoid quirks all around TCON - * and DOTCLOCK drivers. - */ - if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE) - clk_set_phase(tcon->dclk, 240); - if (info->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE) - clk_set_phase(tcon->dclk, 0); + val |= SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE; regmap_update_bits(tcon->regs, SUN4I_TCON0_IO_POL_REG, SUN4I_TCON0_IO_POL_HSYNC_POSITIVE | SUN4I_TCON0_IO_POL_VSYNC_POSITIVE | + SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE | SUN4I_TCON0_IO_POL_DE_NEGATIVE, val); diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h index cfbf4e6c1679..c5ac1b02482c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h @@ -113,6 +113,7 @@ #define SUN4I_TCON0_IO_POL_REG 0x88 #define SUN4I_TCON0_IO_POL_DCLK_PHASE(phase) ((phase & 3) << 28) #define SUN4I_TCON0_IO_POL_DE_NEGATIVE BIT(27) +#define SUN4I_TCON0_IO_POL_DCLK_DRIVE_NEGEDGE BIT(26) #define SUN4I_TCON0_IO_POL_HSYNC_POSITIVE BIT(25) #define SUN4I_TCON0_IO_POL_VSYNC_POSITIVE BIT(24) -- cgit v1.2.3