Message ID | 20240703105454.41254-3-ryan@testtoast.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm: sun4i: add Display Engine 3.3 (DE33) support | expand |
On Wed, 3 Jul 2024 22:50:52 +1200 Ryan Walklin <ryan@testtoast.com> wrote: Hi, > From: Jernej Skrabec <jernej.skrabec@gmail.com> > > Merging both function into one lets this one decide on it's own if CSC > should be enabled or not. "both functions" is not very specific or telling, and left me a bit clueless, so can we maybe use: "At the moment the colour space conversion is handled by two functions: one to setup the conversion parameters, and another one to enable the conversion. Merging both into one gives more flexibility for upcoming extensions to support whole YUV pipelines, in the DE33." Maybe someone knows the real killer reason why this is required, this could then be added here. > Currently heuristics for that is pretty simple > - enable it for YUV formats and disable for RGB. However, DE3 can have > whole pipeline in RGB or YUV format. YUV pipeline will be supported in > later commits. The actual patch looks like a valid transformation to me, so with an amended commit message: > Signed-off-by: Jernej Skrabec <jernej.skrabec@gmail.com> > Signed-off-by: Ryan Walklin <ryan@testtoast.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Cheers, Andre > --- > drivers/gpu/drm/sun4i/sun8i_csc.c | 89 ++++++++++---------------- > drivers/gpu/drm/sun4i/sun8i_csc.h | 9 ++- > drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 11 +--- > 3 files changed, 40 insertions(+), 69 deletions(-) > > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c > index 6ebd1c3aa3ab5..0dcbc0866ae82 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_csc.c > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c > @@ -107,23 +107,28 @@ static const u32 yuv2rgb_de3[2][3][12] = { > }, > }; > > -static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, > - enum format_type fmt_type, > - enum drm_color_encoding encoding, > - enum drm_color_range range) > +static void sun8i_csc_setup(struct regmap *map, u32 base, > + enum format_type fmt_type, > + enum drm_color_encoding encoding, > + enum drm_color_range range) > { > + u32 base_reg, val; > const u32 *table; > - u32 base_reg; > int i; > > table = yuv2rgb[range][encoding]; > > switch (fmt_type) { > + case FORMAT_TYPE_RGB: > + val = 0; > + break; > case FORMAT_TYPE_YUV: > + val = SUN8I_CSC_CTRL_EN; > base_reg = SUN8I_CSC_COEFF(base, 0); > regmap_bulk_write(map, base_reg, table, 12); > break; > case FORMAT_TYPE_YVU: > + val = SUN8I_CSC_CTRL_EN; > for (i = 0; i < 12; i++) { > if ((i & 3) == 1) > base_reg = SUN8I_CSC_COEFF(base, i + 1); > @@ -135,28 +140,37 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, > } > break; > default: > + val = 0; > DRM_WARN("Wrong CSC mode specified.\n"); > return; > } > + > + regmap_write(map, SUN8I_CSC_CTRL(base), val); > } > > -static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, > - enum format_type fmt_type, > - enum drm_color_encoding encoding, > - enum drm_color_range range) > +static void sun8i_de3_ccsc_setup(struct regmap *map, int layer, > + enum format_type fmt_type, > + enum drm_color_encoding encoding, > + enum drm_color_range range) > { > + u32 addr, val, mask; > const u32 *table; > - u32 addr; > int i; > > + mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); > table = yuv2rgb_de3[range][encoding]; > > switch (fmt_type) { > + case FORMAT_TYPE_RGB: > + val = 0; > + break; > case FORMAT_TYPE_YUV: > + val = mask; > addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); > regmap_bulk_write(map, addr, table, 12); > break; > case FORMAT_TYPE_YVU: > + val = mask; > for (i = 0; i < 12; i++) { > if ((i & 3) == 1) > addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, > @@ -173,67 +187,30 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, > } > break; > default: > + val = 0; > DRM_WARN("Wrong CSC mode specified.\n"); > return; > } > -} > - > -static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable) > -{ > - u32 val; > - > - if (enable) > - val = SUN8I_CSC_CTRL_EN; > - else > - val = 0; > - > - regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN, val); > -} > - > -static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable) > -{ > - u32 val, mask; > - > - mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); > - > - if (enable) > - val = mask; > - else > - val = 0; > > regmap_update_bits(map, SUN50I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE), > mask, val); > } > > -void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, > - enum format_type fmt_type, > - enum drm_color_encoding encoding, > - enum drm_color_range range) > -{ > - u32 base; > - > - if (mixer->cfg->is_de3) { > - sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer, > - fmt_type, encoding, range); > - return; > - } > - > - base = ccsc_base[mixer->cfg->ccsc][layer]; > - > - sun8i_csc_set_coefficients(mixer->engine.regs, base, > - fmt_type, encoding, range); > -} > - > -void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable) > +void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, > + enum format_type fmt_type, > + enum drm_color_encoding encoding, > + enum drm_color_range range) > { > u32 base; > > if (mixer->cfg->is_de3) { > - sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable); > + sun8i_de3_ccsc_setup(mixer->engine.regs, layer, > + fmt_type, encoding, range); > return; > } > > base = ccsc_base[mixer->cfg->ccsc][layer]; > > - sun8i_csc_enable(mixer->engine.regs, base, enable); > + sun8i_csc_setup(mixer->engine.regs, base, > + fmt_type, encoding, range); > } > diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h > index 7322770f39f03..b7546e06e315c 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_csc.h > +++ b/drivers/gpu/drm/sun4i/sun8i_csc.h > @@ -28,10 +28,9 @@ enum format_type { > FORMAT_TYPE_YVU, > }; > > -void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, > - enum format_type fmt_type, > - enum drm_color_encoding encoding, > - enum drm_color_range range); > -void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable); > +void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, > + enum format_type fmt_type, > + enum drm_color_encoding encoding, > + enum drm_color_range range); > > #endif > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c > index 76e2d3ec0a78c..6ee3790a2a812 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c > @@ -281,14 +281,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, > SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val); > > fmt_type = sun8i_vi_layer_get_format_type(fmt); > - if (fmt_type != FORMAT_TYPE_RGB) { > - sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_type, > - state->color_encoding, > - state->color_range); > - sun8i_csc_enable_ccsc(mixer, channel, true); > - } else { > - sun8i_csc_enable_ccsc(mixer, channel, false); > - } > + sun8i_csc_set_ccsc(mixer, channel, fmt_type, > + state->color_encoding, > + state->color_range); > > if (!fmt->is_yuv) > val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE;
diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.c b/drivers/gpu/drm/sun4i/sun8i_csc.c index 6ebd1c3aa3ab5..0dcbc0866ae82 100644 --- a/drivers/gpu/drm/sun4i/sun8i_csc.c +++ b/drivers/gpu/drm/sun4i/sun8i_csc.c @@ -107,23 +107,28 @@ static const u32 yuv2rgb_de3[2][3][12] = { }, }; -static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, - enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range) +static void sun8i_csc_setup(struct regmap *map, u32 base, + enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range) { + u32 base_reg, val; const u32 *table; - u32 base_reg; int i; table = yuv2rgb[range][encoding]; switch (fmt_type) { + case FORMAT_TYPE_RGB: + val = 0; + break; case FORMAT_TYPE_YUV: + val = SUN8I_CSC_CTRL_EN; base_reg = SUN8I_CSC_COEFF(base, 0); regmap_bulk_write(map, base_reg, table, 12); break; case FORMAT_TYPE_YVU: + val = SUN8I_CSC_CTRL_EN; for (i = 0; i < 12; i++) { if ((i & 3) == 1) base_reg = SUN8I_CSC_COEFF(base, i + 1); @@ -135,28 +140,37 @@ static void sun8i_csc_set_coefficients(struct regmap *map, u32 base, } break; default: + val = 0; DRM_WARN("Wrong CSC mode specified.\n"); return; } + + regmap_write(map, SUN8I_CSC_CTRL(base), val); } -static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, - enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range) +static void sun8i_de3_ccsc_setup(struct regmap *map, int layer, + enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range) { + u32 addr, val, mask; const u32 *table; - u32 addr; int i; + mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); table = yuv2rgb_de3[range][encoding]; switch (fmt_type) { + case FORMAT_TYPE_RGB: + val = 0; + break; case FORMAT_TYPE_YUV: + val = mask; addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0); regmap_bulk_write(map, addr, table, 12); break; case FORMAT_TYPE_YVU: + val = mask; for (i = 0; i < 12; i++) { if ((i & 3) == 1) addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, @@ -173,67 +187,30 @@ static void sun8i_de3_ccsc_set_coefficients(struct regmap *map, int layer, } break; default: + val = 0; DRM_WARN("Wrong CSC mode specified.\n"); return; } -} - -static void sun8i_csc_enable(struct regmap *map, u32 base, bool enable) -{ - u32 val; - - if (enable) - val = SUN8I_CSC_CTRL_EN; - else - val = 0; - - regmap_update_bits(map, SUN8I_CSC_CTRL(base), SUN8I_CSC_CTRL_EN, val); -} - -static void sun8i_de3_ccsc_enable(struct regmap *map, int layer, bool enable) -{ - u32 val, mask; - - mask = SUN50I_MIXER_BLEND_CSC_CTL_EN(layer); - - if (enable) - val = mask; - else - val = 0; regmap_update_bits(map, SUN50I_MIXER_BLEND_CSC_CTL(DE3_BLD_BASE), mask, val); } -void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, - enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range) -{ - u32 base; - - if (mixer->cfg->is_de3) { - sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer, - fmt_type, encoding, range); - return; - } - - base = ccsc_base[mixer->cfg->ccsc][layer]; - - sun8i_csc_set_coefficients(mixer->engine.regs, base, - fmt_type, encoding, range); -} - -void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable) +void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, + enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range) { u32 base; if (mixer->cfg->is_de3) { - sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable); + sun8i_de3_ccsc_setup(mixer->engine.regs, layer, + fmt_type, encoding, range); return; } base = ccsc_base[mixer->cfg->ccsc][layer]; - sun8i_csc_enable(mixer->engine.regs, base, enable); + sun8i_csc_setup(mixer->engine.regs, base, + fmt_type, encoding, range); } diff --git a/drivers/gpu/drm/sun4i/sun8i_csc.h b/drivers/gpu/drm/sun4i/sun8i_csc.h index 7322770f39f03..b7546e06e315c 100644 --- a/drivers/gpu/drm/sun4i/sun8i_csc.h +++ b/drivers/gpu/drm/sun4i/sun8i_csc.h @@ -28,10 +28,9 @@ enum format_type { FORMAT_TYPE_YVU, }; -void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer, - enum format_type fmt_type, - enum drm_color_encoding encoding, - enum drm_color_range range); -void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable); +void sun8i_csc_set_ccsc(struct sun8i_mixer *mixer, int layer, + enum format_type fmt_type, + enum drm_color_encoding encoding, + enum drm_color_range range); #endif diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c index 76e2d3ec0a78c..6ee3790a2a812 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c @@ -281,14 +281,9 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK, val); fmt_type = sun8i_vi_layer_get_format_type(fmt); - if (fmt_type != FORMAT_TYPE_RGB) { - sun8i_csc_set_ccsc_coefficients(mixer, channel, fmt_type, - state->color_encoding, - state->color_range); - sun8i_csc_enable_ccsc(mixer, channel, true); - } else { - sun8i_csc_enable_ccsc(mixer, channel, false); - } + sun8i_csc_set_ccsc(mixer, channel, fmt_type, + state->color_encoding, + state->color_range); if (!fmt->is_yuv) val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE;