Commit 2db9ef9d authored by Maxime Ripard's avatar Maxime Ripard

drm/sun4i: frontend: Reuse the ch0 phase for RGB formats

When using the scaler on the A10-like frontend with single-planar formats,
the current code will setup the channel 0 filter (used for the R or Y
component) with a different phase parameter than the channel 1 filter (used
for the G/B or U/V components).

This creates a bleed out that keeps repeating on of the last line of the
RGB plane across the rest of the display. The Allwinner BSP either applies
the same phase parameter over both channels or use a separate one, the
condition being whether the input format is YUV420 or not.

Since YUV420 is both subsampled and multi-planar, and since YUYV is
subsampled but single-planar, we can rule out the subsampling and assume
that the condition is actually whether the format is single or
multi-planar. And it looks like applying the same phase parameter over both
channels for single-planar formats fixes our issue, while we keep the
multi-planar formats working properly.
Reported-by: default avatarTaras Galchenko <tpgalchenko@gmail.com>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Acked-by: default avatarJernej Skrabec <jernej.skrabec@siol.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20201015093642.261440-2-maxime@cerno.tech
parent 84c971b3
...@@ -407,6 +407,7 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend, ...@@ -407,6 +407,7 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend,
struct drm_framebuffer *fb = state->fb; struct drm_framebuffer *fb = state->fb;
const struct drm_format_info *format = fb->format; const struct drm_format_info *format = fb->format;
uint64_t modifier = fb->modifier; uint64_t modifier = fb->modifier;
unsigned int ch1_phase_idx;
u32 out_fmt_val; u32 out_fmt_val;
u32 in_fmt_val, in_mod_val, in_ps_val; u32 in_fmt_val, in_mod_val, in_ps_val;
unsigned int i; unsigned int i;
...@@ -442,18 +443,19 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend, ...@@ -442,18 +443,19 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend,
* I have no idea what this does exactly, but it seems to be * I have no idea what this does exactly, but it seems to be
* related to the scaler FIR filter phase parameters. * related to the scaler FIR filter phase parameters.
*/ */
ch1_phase_idx = (format->num_planes > 1) ? 1 : 0;
regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZPHASE_REG, regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_HORZPHASE_REG,
frontend->data->ch_phase[0]); frontend->data->ch_phase[0]);
regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZPHASE_REG, regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_HORZPHASE_REG,
frontend->data->ch_phase[1]); frontend->data->ch_phase[ch1_phase_idx]);
regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE0_REG, regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE0_REG,
frontend->data->ch_phase[0]); frontend->data->ch_phase[0]);
regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE0_REG, regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE0_REG,
frontend->data->ch_phase[1]); frontend->data->ch_phase[ch1_phase_idx]);
regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE1_REG, regmap_write(frontend->regs, SUN4I_FRONTEND_CH0_VERTPHASE1_REG,
frontend->data->ch_phase[0]); frontend->data->ch_phase[0]);
regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE1_REG, regmap_write(frontend->regs, SUN4I_FRONTEND_CH1_VERTPHASE1_REG,
frontend->data->ch_phase[1]); frontend->data->ch_phase[ch1_phase_idx]);
/* /*
* Checking the input format is sufficient since we currently only * Checking the input format is sufficient since we currently only
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment