This patchset fixes corrupted display picture when primary plane isn't full-screen.
Please review/merge.
v2: - Split commit in 2 parts - Add Fixes line to the commit message
v3: - Address review comments of v2 + removed 3 local varibles - Change 'Fixes' line
v4: Resend (author's email changed). Reword commit message. Drop fixes line to allow more testing before back-porting.
drivers/gpu/drm/sun4i/sun4i_crtc.c | 3 +++ drivers/gpu/drm/sun4i/sun8i_mixer.c | 28 ++++++++++++++++++++++++++++ drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 30 ------------------------------ drivers/gpu/drm/sun4i/sunxi_engine.h | 12 ++++++++++++ 4 files changed, 43 insertions(+), 30 deletions(-)
Create callback to allow updating engine's registers on mode change.
Signed-off-by: Roman Stratiienko r.stratiienko@gmail.com Reviewed-by: Jernej Skrabec jernej.skrabec@siol.net --- drivers/gpu/drm/sun4i/sun4i_crtc.c | 3 +++ drivers/gpu/drm/sun4i/sunxi_engine.h | 12 ++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index 45d9eb552d86..8f01a6b2bbef 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -146,6 +146,9 @@ static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc) struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
sun4i_tcon_mode_set(scrtc->tcon, encoder, mode); + + if (scrtc->engine->ops->mode_set) + scrtc->engine->ops->mode_set(scrtc->engine, mode); }
static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h index 548710a936d5..7faa844646ff 100644 --- a/drivers/gpu/drm/sun4i/sunxi_engine.h +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h @@ -9,6 +9,7 @@ struct drm_plane; struct drm_device; struct drm_crtc_state; +struct drm_display_mode;
struct sunxi_engine;
@@ -108,6 +109,17 @@ struct sunxi_engine_ops { * This function is optional. */ void (*vblank_quirk)(struct sunxi_engine *engine); + + /** + * @mode_set: + * + * This callback is used to update engine registers that + * responsible for display frame size and other mode attributes. + * + * This function is optional. + */ + void (*mode_set)(struct sunxi_engine *engine, + struct drm_display_mode *mode); };
/**
On Fri, May 28, 2021 at 11:30:35PM +0300, Roman Stratiienko wrote:
Create callback to allow updating engine's registers on mode change.
Signed-off-by: Roman Stratiienko r.stratiienko@gmail.com Reviewed-by: Jernej Skrabec jernej.skrabec@siol.net
drivers/gpu/drm/sun4i/sun4i_crtc.c | 3 +++ drivers/gpu/drm/sun4i/sunxi_engine.h | 12 ++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c index 45d9eb552d86..8f01a6b2bbef 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -146,6 +146,9 @@ static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc) struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
sun4i_tcon_mode_set(scrtc->tcon, encoder, mode);
- if (scrtc->engine->ops->mode_set)
scrtc->engine->ops->mode_set(scrtc->engine, mode);
}
static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h index 548710a936d5..7faa844646ff 100644 --- a/drivers/gpu/drm/sun4i/sunxi_engine.h +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h @@ -9,6 +9,7 @@ struct drm_plane; struct drm_device; struct drm_crtc_state; +struct drm_display_mode;
struct sunxi_engine;
@@ -108,6 +109,17 @@ struct sunxi_engine_ops { * This function is optional. */ void (*vblank_quirk)(struct sunxi_engine *engine);
- /**
* @mode_set:
*
* This callback is used to update engine registers that
* responsible for display frame size and other mode attributes.
This sentence needs a little grammatical fixup.
*
* This function is optional.
*/
- void (*mode_set)(struct sunxi_engine *engine,
struct drm_display_mode *mode);
};
/**
2.30.2
-- You received this message because you are subscribed to the Google Groups "linux-sunxi" group. To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/linux-sunxi/20210528203036.17999-2-r.strat....
Hi!
Dne petek, 28. maj 2021 ob 22:30:35 CEST je Roman Stratiienko napisal(a):
Create callback to allow updating engine's registers on mode change.
Signed-off-by: Roman Stratiienko r.stratiienko@gmail.com Reviewed-by: Jernej Skrabec jernej.skrabec@siol.net
drivers/gpu/drm/sun4i/sun4i_crtc.c | 3 +++ drivers/gpu/drm/sun4i/sunxi_engine.h | 12 ++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/
sun4i_crtc.c
index 45d9eb552d86..8f01a6b2bbef 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -146,6 +146,9 @@ static void sun4i_crtc_mode_set_nofb(struct drm_crtc
*crtc)
struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
sun4i_tcon_mode_set(scrtc->tcon, encoder, mode);
- if (scrtc->engine->ops->mode_set)
scrtc->engine->ops->mode_set(scrtc->engine, mode);
}
static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/
sunxi_engine.h
index 548710a936d5..7faa844646ff 100644 --- a/drivers/gpu/drm/sun4i/sunxi_engine.h +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h @@ -9,6 +9,7 @@ struct drm_plane; struct drm_device; struct drm_crtc_state; +struct drm_display_mode;
struct sunxi_engine;
@@ -108,6 +109,17 @@ struct sunxi_engine_ops { * This function is optional. */ void (*vblank_quirk)(struct sunxi_engine *engine);
- /**
* @mode_set:
*
* This callback is used to update engine registers that
* responsible for display frame size and other mode attributes.
*
* This function is optional.
*/
- void (*mode_set)(struct sunxi_engine *engine,
struct drm_display_mode *mode);
Mark mode as const.
Best regards, Jernej
};
/**
Dne ponedeljek, 31. maj 2021 ob 19:24:40 CEST je Jernej Škrabec napisal(a):
Hi!
Dne petek, 28. maj 2021 ob 22:30:35 CEST je Roman Stratiienko napisal(a):
Create callback to allow updating engine's registers on mode change.
Signed-off-by: Roman Stratiienko r.stratiienko@gmail.com Reviewed-by: Jernej Skrabec jernej.skrabec@siol.net
BTW, update my R-B tag with gmail address and fix issues pointed out by Plaes and me in order to use it.
drivers/gpu/drm/sun4i/sun4i_crtc.c | 3 +++ drivers/gpu/drm/sun4i/sunxi_engine.h | 12 ++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/
sun4i_crtc.c
index 45d9eb552d86..8f01a6b2bbef 100644 --- a/drivers/gpu/drm/sun4i/sun4i_crtc.c +++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c @@ -146,6 +146,9 @@ static void sun4i_crtc_mode_set_nofb(struct drm_crtc
*crtc)
struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
sun4i_tcon_mode_set(scrtc->tcon, encoder, mode);
- if (scrtc->engine->ops->mode_set)
scrtc->engine->ops->mode_set(scrtc->engine, mode);
}
static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/
sunxi_engine.h
index 548710a936d5..7faa844646ff 100644 --- a/drivers/gpu/drm/sun4i/sunxi_engine.h +++ b/drivers/gpu/drm/sun4i/sunxi_engine.h @@ -9,6 +9,7 @@ struct drm_plane; struct drm_device; struct drm_crtc_state; +struct drm_display_mode;
struct sunxi_engine;
@@ -108,6 +109,17 @@ struct sunxi_engine_ops { * This function is optional. */ void (*vblank_quirk)(struct sunxi_engine *engine);
- /**
* @mode_set:
*
* This callback is used to update engine registers that
* responsible for display frame size and other mode attributes.
*
* This function is optional.
*/
- void (*mode_set)(struct sunxi_engine *engine,
struct drm_display_mode *mode);
Mark mode as const.
Best regards, Jernej
};
/**
Fixes corrupted display picture when primary plane isn't full-screen.
Signed-off-by: Roman Stratiienko r.stratiienko@gmail.com --- drivers/gpu/drm/sun4i/sun8i_mixer.c | 28 ++++++++++++++++++++++++ drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 30 -------------------------- 2 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 5b42cf25cc86..810c731566c0 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -248,6 +248,33 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format) return -EINVAL; }
+static void sun8i_mode_set(struct sunxi_engine *engine, + struct drm_display_mode *mode) +{ + u32 size = SUN8I_MIXER_SIZE(mode->crtc_hdisplay, mode->crtc_vdisplay); + struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine); + u32 bld_base = sun8i_blender_base(mixer); + u32 val; + + DRM_DEBUG_DRIVER("Mode change, updating global size W: %u H: %u\n", + mode->crtc_hdisplay, mode->crtc_vdisplay); + regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, size); + regmap_write(mixer->engine.regs, + SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size); + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED; + else + val = 0; + + regmap_update_bits(mixer->engine.regs, + SUN8I_MIXER_BLEND_OUTCTL(bld_base), + SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, + val); + DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", + val ? "on" : "off"); +} + static void sun8i_mixer_commit(struct sunxi_engine *engine) { DRM_DEBUG_DRIVER("Committing changes\n"); @@ -301,6 +328,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm, static const struct sunxi_engine_ops sun8i_engine_ops = { .commit = sun8i_mixer_commit, .layers_init = sun8i_layers_init, + .mode_set = sun8i_mode_set, };
static const struct regmap_config sun8i_mixer_regmap_config = { diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c index 0db164a774a1..d66fff582278 100644 --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c @@ -120,36 +120,6 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, insize = SUN8I_MIXER_SIZE(src_w, src_h); outsize = SUN8I_MIXER_SIZE(dst_w, dst_h);
- if (plane->type == DRM_PLANE_TYPE_PRIMARY) { - bool interlaced = false; - u32 val; - - DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", - dst_w, dst_h); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_GLOBAL_SIZE, - outsize); - regmap_write(mixer->engine.regs, - SUN8I_MIXER_BLEND_OUTSIZE(bld_base), outsize); - - if (state->crtc) - interlaced = state->crtc->state->adjusted_mode.flags - & DRM_MODE_FLAG_INTERLACE; - - if (interlaced) - val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED; - else - val = 0; - - regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_BLEND_OUTCTL(bld_base), - SUN8I_MIXER_BLEND_OUTCTL_INTERLACED, - val); - - DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n", - interlaced ? "on" : "off"); - } - /* Set height and width */ DRM_DEBUG_DRIVER("Layer source offset X: %d Y: %d\n", state->src.x1 >> 16, state->src.y1 >> 16);
+CC: jernej.skrabec@gmail.com
пт, 28 мая 2021 г. в 23:31, Roman Stratiienko r.stratiienko@gmail.com:
Fixes corrupted display picture when primary plane isn't full-screen.
Signed-off-by: Roman Stratiienko r.stratiienko@gmail.com
drivers/gpu/drm/sun4i/sun8i_mixer.c | 28 ++++++++++++++++++++++++ drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 30 -------------------------- 2 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c index 5b42cf25cc86..810c731566c0 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -248,6 +248,33 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32 *hw_format) return -EINVAL; }
+static void sun8i_mode_set(struct sunxi_engine *engine,
struct drm_display_mode *mode)
+{
u32 size = SUN8I_MIXER_SIZE(mode->crtc_hdisplay, mode->crtc_vdisplay);
struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
u32 bld_base = sun8i_blender_base(mixer);
u32 val;
DRM_DEBUG_DRIVER("Mode change, updating global size W: %u H: %u\n",
mode->crtc_hdisplay, mode->crtc_vdisplay);
regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, size);
regmap_write(mixer->engine.regs,
SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size);
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED;
else
val = 0;
regmap_update_bits(mixer->engine.regs,
SUN8I_MIXER_BLEND_OUTCTL(bld_base),
SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
val);
DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
val ? "on" : "off");
+}
static void sun8i_mixer_commit(struct sunxi_engine *engine) { DRM_DEBUG_DRIVER("Committing changes\n"); @@ -301,6 +328,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm, static const struct sunxi_engine_ops sun8i_engine_ops = { .commit = sun8i_mixer_commit, .layers_init = sun8i_layers_init,
.mode_set = sun8i_mode_set,
};
static const struct regmap_config sun8i_mixer_regmap_config = { diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c index 0db164a774a1..d66fff582278 100644 --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c @@ -120,36 +120,6 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, insize = SUN8I_MIXER_SIZE(src_w, src_h); outsize = SUN8I_MIXER_SIZE(dst_w, dst_h);
if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
bool interlaced = false;
u32 val;
DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n",
dst_w, dst_h);
regmap_write(mixer->engine.regs,
SUN8I_MIXER_GLOBAL_SIZE,
outsize);
regmap_write(mixer->engine.regs,
SUN8I_MIXER_BLEND_OUTSIZE(bld_base), outsize);
if (state->crtc)
interlaced = state->crtc->state->adjusted_mode.flags
& DRM_MODE_FLAG_INTERLACE;
if (interlaced)
val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED;
else
val = 0;
regmap_update_bits(mixer->engine.regs,
SUN8I_MIXER_BLEND_OUTCTL(bld_base),
SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
val);
DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
interlaced ? "on" : "off");
}
/* Set height and width */ DRM_DEBUG_DRIVER("Layer source offset X: %d Y: %d\n", state->src.x1 >> 16, state->src.y1 >> 16);
-- 2.30.2
Hi!
General note, you should send Allwinner specific patches to linux- sunxi@lists.linux.dev too. It's already in MAINTAINERS, but probably it's not yet propagated in all trees.
Dne petek, 28. maj 2021 ob 22:30:36 CEST je Roman Stratiienko napisal(a):
Fixes corrupted display picture when primary plane isn't full-screen.
You should expand this a bit more. Most importantly why this fixes a bug? Rule of thumb - if you used word "fix" in commit message, most of the time you should add Fixes tag too.
Signed-off-by: Roman Stratiienko r.stratiienko@gmail.com
drivers/gpu/drm/sun4i/sun8i_mixer.c | 28 ++++++++++++++++++++++++ drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 30 -------------------------- 2 files changed, 28 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/
sun8i_mixer.c
index 5b42cf25cc86..810c731566c0 100644 --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c @@ -248,6 +248,33 @@ int sun8i_mixer_drm_format_to_hw(u32 format, u32
*hw_format)
return -EINVAL; }
+static void sun8i_mode_set(struct sunxi_engine *engine,
struct drm_display_mode *mode)
+{
- u32 size = SUN8I_MIXER_SIZE(mode->crtc_hdisplay, mode-
crtc_vdisplay);
CRTC variants are not appropriate here. These are adjusted for interlacing and other stuff. This is important during TCON configuration, not here. Just drop "crtc_" prefix.
Best regards, Jernej
- struct sun8i_mixer *mixer = engine_to_sun8i_mixer(engine);
- u32 bld_base = sun8i_blender_base(mixer);
- u32 val;
- DRM_DEBUG_DRIVER("Mode change, updating global size W: %u H: %u\n",
mode->crtc_hdisplay, mode->crtc_vdisplay);
- regmap_write(mixer->engine.regs, SUN8I_MIXER_GLOBAL_SIZE, size);
- regmap_write(mixer->engine.regs,
SUN8I_MIXER_BLEND_OUTSIZE(bld_base), size);
- if (mode->flags & DRM_MODE_FLAG_INTERLACE)
val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED;
- else
val = 0;
- regmap_update_bits(mixer->engine.regs,
SUN8I_MIXER_BLEND_OUTCTL(bld_base),
SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
val);
- DRM_DEBUG_DRIVER("Switching display mixer interlaced mode %s\n",
val ? "on" : "off");
+}
static void sun8i_mixer_commit(struct sunxi_engine *engine) { DRM_DEBUG_DRIVER("Committing changes\n"); @@ -301,6 +328,7 @@ static struct drm_plane **sun8i_layers_init(struct
drm_device *drm,
static const struct sunxi_engine_ops sun8i_engine_ops = { .commit = sun8i_mixer_commit, .layers_init = sun8i_layers_init,
- .mode_set = sun8i_mode_set,
};
static const struct regmap_config sun8i_mixer_regmap_config = { diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/
sun8i_ui_layer.c
index 0db164a774a1..d66fff582278 100644 --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c @@ -120,36 +120,6 @@ static int sun8i_ui_layer_update_coord(struct
sun8i_mixer *mixer, int channel,
insize = SUN8I_MIXER_SIZE(src_w, src_h); outsize = SUN8I_MIXER_SIZE(dst_w, dst_h);
- if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
bool interlaced = false;
u32 val;
DRM_DEBUG_DRIVER("Primary layer, updating global size
W: %u H: %u\n",
dst_w, dst_h);
regmap_write(mixer->engine.regs,
SUN8I_MIXER_GLOBAL_SIZE,
outsize);
regmap_write(mixer->engine.regs,
SUN8I_MIXER_BLEND_OUTSIZE(bld_base),
outsize);
if (state->crtc)
interlaced = state->crtc->state-
adjusted_mode.flags
& DRM_MODE_FLAG_INTERLACE;
if (interlaced)
val = SUN8I_MIXER_BLEND_OUTCTL_INTERLACED;
else
val = 0;
regmap_update_bits(mixer->engine.regs,
SUN8I_MIXER_BLEND_OUTCTL(bld_base),
SUN8I_MIXER_BLEND_OUTCTL_INTERLACED,
val);
DRM_DEBUG_DRIVER("Switching display mixer interlaced
mode %s\n",
interlaced ? "on" : "off");
- }
- /* Set height and width */ DRM_DEBUG_DRIVER("Layer source offset X: %d Y: %d\n", state->src.x1 >> 16, state->src.y1 >> 16);
dri-devel@lists.freedesktop.org