Commit 870e3cf4 authored by Jernej Skrabec's avatar Jernej Skrabec Committed by Chen-Yu Tsai
Browse files

drm/sun4i: de2/de3: Simplify CSC config interface



Merging both function into one lets this one decide on it's own if CSC
should be enabled or not. Currently heuristics for that is pretty simple
- enable it for YUV formats and disable for RGB. DE3 and newer allows
YUV pipeline, which will be easier to implement these way.

Reviewed-by: default avatarChen-Yu Tsai <wens@kernel.org>
Tested-by: default avatarRyan Walklin <ryan@testtoast.com>
Signed-off-by: default avatarJernej Skrabec <jernej.skrabec@gmail.com>
Link: https://patch.msgid.link/20251104180942.61538-12-jernej.skrabec@gmail.com


Signed-off-by: default avatarChen-Yu Tsai <wens@kernel.org>
parent fc9b4e3b
Loading
Loading
Loading
Loading
+33 −56
Original line number Diff line number Diff line
@@ -107,23 +107,28 @@ static const u32 yuv2rgb_de3[2][3][12] = {
	},
};

static void sun8i_csc_set_coefficients(struct regmap *map, u32 base,
static void sun8i_csc_setup(struct regmap *map, u32 base,
			    enum sun8i_csc_mode mode,
			    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 (mode) {
	case SUN8I_CSC_MODE_OFF:
		val = 0;
		break;
	case SUN8I_CSC_MODE_YUV2RGB:
		val = SUN8I_CSC_CTRL_EN;
		base_reg = SUN8I_CSC_COEFF(base, 0);
		regmap_bulk_write(map, base_reg, table, 12);
		break;
	case SUN8I_CSC_MODE_YVU2RGB:
		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,
static void sun8i_de3_ccsc_setup(struct regmap *map, int layer,
				 enum sun8i_csc_mode mode,
				 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 (mode) {
	case SUN8I_CSC_MODE_OFF:
		val = 0;
		break;
	case SUN8I_CSC_MODE_YUV2RGB:
		val = mask;
		addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE, layer, 0);
		regmap_bulk_write(map, addr, table, 12);
		break;
	case SUN8I_CSC_MODE_YVU2RGB:
		val = mask;
		for (i = 0; i < 12; i++) {
			if ((i & 3) == 1)
				addr = SUN50I_MIXER_BLEND_CSC_COEFF(DE3_BLD_BASE,
@@ -173,39 +187,16 @@ 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,
void sun8i_csc_config(struct sun8i_mixer *mixer, int layer,
		      enum sun8i_csc_mode mode,
		      enum drm_color_encoding encoding,
		      enum drm_color_range range)
@@ -213,27 +204,13 @@ void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
	u32 base;

	if (mixer->cfg->de_type == SUN8I_MIXER_DE3) {
		sun8i_de3_ccsc_set_coefficients(mixer->engine.regs, layer,
		sun8i_de3_ccsc_setup(mixer->engine.regs, layer,
				     mode, encoding, range);
		return;
	}

	base = ccsc_base[mixer->cfg->ccsc][layer];

	sun8i_csc_set_coefficients(mixer->engine.regs, base,
	sun8i_csc_setup(mixer->engine.regs, base,
			mode, encoding, range);
}

void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable)
{
	u32 base;

	if (mixer->cfg->de_type == SUN8I_MIXER_DE3) {
		sun8i_de3_ccsc_enable(mixer->engine.regs, layer, enable);
		return;
	}

	base = ccsc_base[mixer->cfg->ccsc][layer];

	sun8i_csc_enable(mixer->engine.regs, base, enable);
}
+4 −5
Original line number Diff line number Diff line
@@ -28,10 +28,9 @@ enum sun8i_csc_mode {
	SUN8I_CSC_MODE_YVU2RGB,
};

void sun8i_csc_set_ccsc_coefficients(struct sun8i_mixer *mixer, int layer,
void sun8i_csc_config(struct sun8i_mixer *mixer, int layer,
		      enum sun8i_csc_mode mode,
		      enum drm_color_encoding encoding,
		      enum drm_color_range range);
void sun8i_csc_enable_ccsc(struct sun8i_mixer *mixer, int layer, bool enable);

#endif
+3 −8
Original line number Diff line number Diff line
@@ -214,14 +214,9 @@ static void sun8i_vi_layer_update_colors(struct sun8i_mixer *mixer, int channel,

	fmt = state->fb->format;
	csc_mode = sun8i_vi_layer_get_csc_mode(fmt);
	if (csc_mode != SUN8I_CSC_MODE_OFF) {
		sun8i_csc_set_ccsc_coefficients(mixer, channel, csc_mode,
	sun8i_csc_config(mixer, channel, csc_mode,
			 state->color_encoding,
			 state->color_range);
		sun8i_csc_enable_ccsc(mixer, channel, true);
	} else {
		sun8i_csc_enable_ccsc(mixer, channel, false);
	}
}

static void sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel,