drm: sun8i-ui/vi: Fix layer zpos change/atomic modesetting
This also speeds up mouse selection in a major way. No more stuttering. Also various blinking artifacts are gone. Signed-off-by: Ondrej Jirman <megous@megous.com>alistair/sunxi64-5.5-dsi
parent
b02e15455c
commit
9eef35ced9
|
@ -24,10 +24,11 @@
|
|||
#include "sun8i_ui_scaler.h"
|
||||
|
||||
static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
|
||||
int overlay, bool enable, unsigned int zpos,
|
||||
unsigned int old_zpos)
|
||||
int overlay, bool was_enabled, bool enable,
|
||||
unsigned int zpos, unsigned int old_zpos)
|
||||
{
|
||||
u32 val, bld_base, ch_base;
|
||||
unsigned int old_pipe_ch;
|
||||
|
||||
bld_base = sun8i_blender_base(mixer);
|
||||
ch_base = sun8i_channel_base(mixer, channel);
|
||||
|
@ -35,28 +36,57 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
|
|||
DRM_DEBUG_DRIVER("%sabling channel %d overlay %d\n",
|
||||
enable ? "En" : "Dis", channel, overlay);
|
||||
|
||||
if (enable)
|
||||
val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN;
|
||||
else
|
||||
val = 0;
|
||||
if (!was_enabled != !enable) {
|
||||
val = enable ? SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN : 0;
|
||||
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay),
|
||||
SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val);
|
||||
}
|
||||
|
||||
if (!enable || zpos != old_zpos) {
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
|
||||
SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
|
||||
0);
|
||||
/*
|
||||
* If this layer was enabled and is being disabled or if it is
|
||||
* enabled and just changing zpos, clear the old route, if it is
|
||||
* still configured to this layer in HW.
|
||||
*/
|
||||
if ((was_enabled && !enable) || (enable && zpos != old_zpos)) {
|
||||
/* get channel the pipe for old_zpos is routed to from the HW */
|
||||
regmap_read(mixer->engine.regs,
|
||||
SUN8I_MIXER_BLEND_ROUTE(bld_base),
|
||||
&old_pipe_ch);
|
||||
old_pipe_ch &= SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos);
|
||||
old_pipe_ch >>= SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(old_zpos);
|
||||
|
||||
/*
|
||||
* Check that pipe for old_zpos is still routed to our layer,
|
||||
* and clear/disable it if it is.
|
||||
*/
|
||||
|
||||
if (old_pipe_ch == channel) {
|
||||
DRM_DEBUG_DRIVER("chan=%d en=%d->%d zpos=%d->%d\n",
|
||||
channel, was_enabled, enable, old_zpos, zpos);
|
||||
|
||||
DRM_DEBUG_DRIVER(" disable pipe %d\n", old_zpos);
|
||||
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
SUN8I_MIXER_BLEND_ROUTE(bld_base),
|
||||
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
|
||||
0);
|
||||
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
|
||||
SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
* If enabling this layer or changin zpos, set route to this layer.
|
||||
*/
|
||||
if ((enable && !was_enabled) || (enable && zpos != old_zpos)) {
|
||||
DRM_DEBUG_DRIVER("chan=%d en=%d->%d zpos=%d->%d\n",
|
||||
channel, was_enabled, enable, old_zpos, zpos);
|
||||
|
||||
val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
|
||||
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
|
@ -69,6 +99,8 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel,
|
|||
SUN8I_MIXER_BLEND_ROUTE(bld_base),
|
||||
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
|
||||
val);
|
||||
|
||||
DRM_DEBUG_DRIVER(" enable pipe %d <- ch %d\n", zpos, channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,17 +293,6 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane,
|
|||
true, true);
|
||||
}
|
||||
|
||||
static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
|
||||
unsigned int old_zpos = old_state->normalized_zpos;
|
||||
struct sun8i_mixer *mixer = layer->mixer;
|
||||
|
||||
sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
|
||||
old_zpos);
|
||||
}
|
||||
|
||||
static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
|
@ -279,27 +300,36 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane,
|
|||
unsigned int zpos = plane->state->normalized_zpos;
|
||||
unsigned int old_zpos = old_state->normalized_zpos;
|
||||
struct sun8i_mixer *mixer = layer->mixer;
|
||||
bool was_enabled = old_state->crtc && old_state->visible;
|
||||
bool enable = plane->state->crtc && plane->state->visible;
|
||||
|
||||
if (!plane->state->visible) {
|
||||
sun8i_ui_layer_enable(mixer, layer->channel,
|
||||
layer->overlay, false, 0, old_zpos);
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
sun8i_ui_layer_update_coord(mixer, layer->channel,
|
||||
layer->overlay, plane, zpos);
|
||||
sun8i_ui_layer_update_formats(mixer, layer->channel,
|
||||
layer->overlay, plane);
|
||||
sun8i_ui_layer_update_buffer(mixer, layer->channel,
|
||||
layer->overlay, plane);
|
||||
}
|
||||
|
||||
sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay,
|
||||
true, zpos, old_zpos);
|
||||
was_enabled, enable, zpos, old_zpos);
|
||||
}
|
||||
|
||||
void sun8i_ui_layer_plane_reset(struct drm_plane *plane)
|
||||
{
|
||||
struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane);
|
||||
|
||||
drm_atomic_helper_plane_reset(plane);
|
||||
if (!plane->state)
|
||||
return;
|
||||
|
||||
plane->state->zpos = layer->channel;
|
||||
}
|
||||
|
||||
static struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = {
|
||||
.prepare_fb = drm_gem_fb_prepare_fb,
|
||||
.atomic_check = sun8i_ui_layer_atomic_check,
|
||||
.atomic_disable = sun8i_ui_layer_atomic_disable,
|
||||
.atomic_update = sun8i_ui_layer_atomic_update,
|
||||
};
|
||||
|
||||
|
@ -308,7 +338,7 @@ static const struct drm_plane_funcs sun8i_ui_layer_funcs = {
|
|||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||
.destroy = drm_plane_cleanup,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.reset = drm_atomic_helper_plane_reset,
|
||||
.reset = sun8i_ui_layer_plane_reset,
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
};
|
||||
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
#include "sun8i_vi_scaler.h"
|
||||
|
||||
static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
|
||||
int overlay, bool enable, unsigned int zpos,
|
||||
unsigned int old_zpos)
|
||||
int overlay, bool was_enabled, bool enable,
|
||||
unsigned int zpos, unsigned int old_zpos)
|
||||
{
|
||||
u32 val, bld_base, ch_base;
|
||||
unsigned int old_pipe_ch;
|
||||
|
||||
bld_base = sun8i_blender_base(mixer);
|
||||
ch_base = sun8i_channel_base(mixer, channel);
|
||||
|
@ -28,28 +29,57 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
|
|||
DRM_DEBUG_DRIVER("%sabling VI channel %d overlay %d\n",
|
||||
enable ? "En" : "Dis", channel, overlay);
|
||||
|
||||
if (enable)
|
||||
val = SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN;
|
||||
else
|
||||
val = 0;
|
||||
if (!was_enabled != !enable) {
|
||||
val = enable ? SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN : 0;
|
||||
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay),
|
||||
SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val);
|
||||
}
|
||||
|
||||
if (!enable || zpos != old_zpos) {
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
|
||||
SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
|
||||
0);
|
||||
/*
|
||||
* If this layer was enabled and is being disabled or if it is
|
||||
* enabled and just changing zpos, clear the old route, if it is
|
||||
* still configured to this layer in HW.
|
||||
*/
|
||||
if ((was_enabled && !enable) || (enable && zpos != old_zpos)) {
|
||||
/* get channel the pipe for old_zpos is routed to from the HW */
|
||||
regmap_read(mixer->engine.regs,
|
||||
SUN8I_MIXER_BLEND_ROUTE(bld_base),
|
||||
&old_pipe_ch);
|
||||
old_pipe_ch &= SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos);
|
||||
old_pipe_ch >>= SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(old_zpos);
|
||||
|
||||
/*
|
||||
* Check that pipe for old_zpos is still routed to our layer,
|
||||
* and clear/disable it if it is.
|
||||
*/
|
||||
|
||||
if (old_pipe_ch == channel) {
|
||||
DRM_DEBUG_DRIVER("chan=%d en=%d->%d zpos=%d->%d\n",
|
||||
channel, was_enabled, enable, old_zpos, zpos);
|
||||
|
||||
DRM_DEBUG_DRIVER(" disable pipe %d\n", old_zpos);
|
||||
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
SUN8I_MIXER_BLEND_ROUTE(bld_base),
|
||||
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(old_zpos),
|
||||
0);
|
||||
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
SUN8I_MIXER_BLEND_PIPE_CTL(bld_base),
|
||||
SUN8I_MIXER_BLEND_PIPE_CTL_EN(old_zpos),
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
* If enabling this layer or changin zpos, set route to this layer.
|
||||
*/
|
||||
if ((enable && !was_enabled) || (enable && zpos != old_zpos)) {
|
||||
DRM_DEBUG_DRIVER("chan=%d en=%d->%d zpos=%d->%d\n",
|
||||
channel, was_enabled, enable, old_zpos, zpos);
|
||||
|
||||
val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos);
|
||||
|
||||
regmap_update_bits(mixer->engine.regs,
|
||||
|
@ -62,6 +92,8 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel,
|
|||
SUN8I_MIXER_BLEND_ROUTE(bld_base),
|
||||
SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos),
|
||||
val);
|
||||
|
||||
DRM_DEBUG_DRIVER(" enable pipe %d <- ch %d\n", zpos, channel);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,17 +378,6 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane,
|
|||
true, true);
|
||||
}
|
||||
|
||||
static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
|
||||
unsigned int old_zpos = old_state->normalized_zpos;
|
||||
struct sun8i_mixer *mixer = layer->mixer;
|
||||
|
||||
sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, false, 0,
|
||||
old_zpos);
|
||||
}
|
||||
|
||||
static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
|
||||
struct drm_plane_state *old_state)
|
||||
{
|
||||
|
@ -364,27 +385,36 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane,
|
|||
unsigned int zpos = plane->state->normalized_zpos;
|
||||
unsigned int old_zpos = old_state->normalized_zpos;
|
||||
struct sun8i_mixer *mixer = layer->mixer;
|
||||
bool was_enabled = old_state->crtc && old_state->visible;
|
||||
bool enable = plane->state->crtc && plane->state->visible;
|
||||
|
||||
if (!plane->state->visible) {
|
||||
sun8i_vi_layer_enable(mixer, layer->channel,
|
||||
layer->overlay, false, 0, old_zpos);
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
sun8i_vi_layer_update_coord(mixer, layer->channel,
|
||||
layer->overlay, plane, zpos);
|
||||
sun8i_vi_layer_update_formats(mixer, layer->channel,
|
||||
layer->overlay, plane);
|
||||
sun8i_vi_layer_update_buffer(mixer, layer->channel,
|
||||
layer->overlay, plane);
|
||||
}
|
||||
|
||||
sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay,
|
||||
true, zpos, old_zpos);
|
||||
was_enabled, enable, zpos, old_zpos);
|
||||
}
|
||||
|
||||
void sun8i_vi_layer_plane_reset(struct drm_plane *plane)
|
||||
{
|
||||
struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane);
|
||||
|
||||
drm_atomic_helper_plane_reset(plane);
|
||||
if (!plane->state)
|
||||
return;
|
||||
|
||||
plane->state->zpos = layer->channel;
|
||||
}
|
||||
|
||||
static struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = {
|
||||
.prepare_fb = drm_gem_fb_prepare_fb,
|
||||
.atomic_check = sun8i_vi_layer_atomic_check,
|
||||
.atomic_disable = sun8i_vi_layer_atomic_disable,
|
||||
.atomic_update = sun8i_vi_layer_atomic_update,
|
||||
};
|
||||
|
||||
|
@ -393,7 +423,7 @@ static const struct drm_plane_funcs sun8i_vi_layer_funcs = {
|
|||
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
|
||||
.destroy = drm_plane_cleanup,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.reset = drm_atomic_helper_plane_reset,
|
||||
.reset = sun8i_vi_layer_plane_reset,
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue