summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorMaxime Ripard <maxime@cerno.tech>2020-10-15 11:36:41 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-11-10 12:37:29 +0100
commitf743f73f42a77deb4832ec76a2403452429067f2 (patch)
treef24b2e5137122f4d989e972b0d795940153d85e2 /drivers
parent6d7b41a67687ba3691c7f5057f254743258f4205 (diff)
drm/sun4i: frontend: Reuse the ch0 phase for RGB formats
[ Upstream commit 2db9ef9d9e6ea89a9feb5338f58d1f8f83875577 ] 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: Taras Galchenko <tpgalchenko@gmail.com> Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Jernej Skrabec <jernej.skrabec@siol.net> Link: https://patchwork.freedesktop.org/patch/msgid/20201015093642.261440-2-maxime@cerno.tech Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_frontend.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_frontend.c b/drivers/gpu/drm/sun4i/sun4i_frontend.c
index 7462801b1fa8..c4959d9e1639 100644
--- a/drivers/gpu/drm/sun4i/sun4i_frontend.c
+++ b/drivers/gpu/drm/sun4i/sun4i_frontend.c
@@ -407,6 +407,7 @@ int sun4i_frontend_update_formats(struct sun4i_frontend *frontend,
struct drm_framebuffer *fb = state->fb;
const struct drm_format_info *format = fb->format;
uint64_t modifier = fb->modifier;
+ unsigned int ch1_phase_idx;
u32 out_fmt_val;
u32 in_fmt_val, in_mod_val, in_ps_val;
unsigned int i;
@@ -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
* 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,
frontend->data->ch_phase[0]);
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,
frontend->data->ch_phase[0]);
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,
frontend->data->ch_phase[0]);
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