On Wed, 2018-06-27 at 18:45 +0200, Jernej Skrabec wrote: > Initial implementation of DE2 planes only supported fixed zpos. > > Expand implementation with configurable zpos property. Thanks for adding support for this! Tested with the Sunxi-Cedrus VPU driver on H3 with: https://github.com/free-electrons/cedrus-frame-test/commit/9f46aa83cae1b9fa4d4901d3d2999c8d41265532 Tested-by: Paul Kocialkowski <paul.kocialkowski@xxxxxxxxxxx> > Signed-off-by: Jernej Skrabec <jernej.skrabec@xxxxxxxx> > --- > drivers/gpu/drm/sun4i/sun8i_mixer.c | 15 +++++++-- > drivers/gpu/drm/sun4i/sun8i_mixer.h | 4 +++ > drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 45 ++++++++++++++++---------- > drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 45 ++++++++++++++++---------- > 4 files changed, 72 insertions(+), 37 deletions(-) > > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c > index ee8febb25903..0747a9a69654 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.c > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c > @@ -260,6 +260,17 @@ const struct de2_fmt_info *sun8i_mixer_format_info(u32 format) > return NULL; > } > > +static void sun8i_mixer_atomic_begin(struct sunxi_engine *engine, > + struct drm_crtc_state *old_state) > +{ > + /* > + * Disable all pipes at the beginning. They will be enabled > + * again if needed in plane update callback. > + */ > + regmap_update_bits(engine->regs, SUN8I_MIXER_BLEND_PIPE_CTL, > + SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK, 0); > +} > + > static void sun8i_mixer_commit(struct sunxi_engine *engine) > { > DRM_DEBUG_DRIVER("Committing changes\n"); > @@ -311,6 +322,7 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm, > } > > static const struct sunxi_engine_ops sun8i_engine_ops = { > + .atomic_begin = sun8i_mixer_atomic_begin, > .commit = sun8i_mixer_commit, > .layers_init = sun8i_layers_init, > }; > @@ -432,9 +444,6 @@ static int sun8i_mixer_bind(struct device *dev, struct device *master, > regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ATTR_FCOLOR(0), > SUN8I_MIXER_BLEND_COLOR_BLACK); > > - /* Fixed zpos for now */ > - regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_ROUTE, 0x43210); > - > plane_cnt = mixer->cfg->vi_num + mixer->cfg->ui_num; > for (i = 0; i < plane_cnt; i++) > regmap_write(mixer->engine.regs, SUN8I_MIXER_BLEND_MODE(i), > diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.h b/drivers/gpu/drm/sun4i/sun8i_mixer.h > index f34e70c42adf..406c42e752d7 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_mixer.h > +++ b/drivers/gpu/drm/sun4i/sun8i_mixer.h > @@ -44,6 +44,7 @@ > #define SUN8I_MIXER_BLEND_CK_MIN(x) (0x10e0 + 0x04 * (x)) > #define SUN8I_MIXER_BLEND_OUTCTL 0x10fc > > +#define SUN8I_MIXER_BLEND_PIPE_CTL_EN_MSK GENMASK(12, 8) > #define SUN8I_MIXER_BLEND_PIPE_CTL_EN(pipe) BIT(8 + pipe) > #define SUN8I_MIXER_BLEND_PIPE_CTL_FC_EN(pipe) BIT(pipe) > /* colors are always in AARRGGBB format */ > @@ -51,6 +52,9 @@ > /* The following numbers are some still unknown magic numbers */ > #define SUN8I_MIXER_BLEND_MODE_DEF 0x03010301 > > +#define SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(n) (0xf << ((n) << 2)) > +#define SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(n) ((n) << 2) > + > #define SUN8I_MIXER_BLEND_OUTCTL_INTERLACED BIT(1) > > #define SUN8I_MIXER_FBFMT_ARGB8888 0 > diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c > index 9a540330cb79..518e1921f47e 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c > +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c > @@ -27,7 +27,7 @@ > #include "sun8i_ui_scaler.h" > > static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel, > - int overlay, bool enable) > + int overlay, bool enable, unsigned int zpos) > { > u32 val; > > @@ -43,18 +43,24 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel, > SUN8I_MIXER_CHAN_UI_LAYER_ATTR(channel, overlay), > SUN8I_MIXER_CHAN_UI_LAYER_ATTR_EN, val); > > - if (enable) > - val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel); > - else > - val = 0; > + if (enable) { > + val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos); > > - regmap_update_bits(mixer->engine.regs, > - SUN8I_MIXER_BLEND_PIPE_CTL, > - SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel), val); > + regmap_update_bits(mixer->engine.regs, > + SUN8I_MIXER_BLEND_PIPE_CTL, val, val); > + > + val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos); > + > + regmap_update_bits(mixer->engine.regs, > + SUN8I_MIXER_BLEND_ROUTE, > + SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos), > + val); > + } > } > > static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, > - int overlay, struct drm_plane *plane) > + int overlay, struct drm_plane *plane, > + unsigned int zpos) > { > struct drm_plane_state *state = plane->state; > u32 src_w, src_h, dst_w, dst_h; > @@ -137,10 +143,10 @@ static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, > state->dst.x1, state->dst.y1); > DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h); > regmap_write(mixer->engine.regs, > - SUN8I_MIXER_BLEND_ATTR_COORD(channel), > + SUN8I_MIXER_BLEND_ATTR_COORD(zpos), > SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); > regmap_write(mixer->engine.regs, > - SUN8I_MIXER_BLEND_ATTR_INSIZE(channel), > + SUN8I_MIXER_BLEND_ATTR_INSIZE(zpos), > outsize); > > return 0; > @@ -238,28 +244,30 @@ static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane, > struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane); > struct sun8i_mixer *mixer = layer->mixer; > > - sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, false); > + sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, false, 0); > } > > static void sun8i_ui_layer_atomic_update(struct drm_plane *plane, > struct drm_plane_state *old_state) > { > struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane); > + unsigned int zpos = plane->state->normalized_zpos; > struct sun8i_mixer *mixer = layer->mixer; > > if (!plane->state->visible) { > sun8i_ui_layer_enable(mixer, layer->channel, > - layer->overlay, false); > + layer->overlay, false, 0); > return; > } > > sun8i_ui_layer_update_coord(mixer, layer->channel, > - layer->overlay, plane); > + 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); > + sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, > + true, zpos); > } > > static struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = { > @@ -307,6 +315,7 @@ struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm, > enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY; > int channel = mixer->cfg->vi_num + index; > struct sun8i_ui_layer *layer; > + unsigned int plane_cnt; > int ret; > > layer = devm_kzalloc(drm->dev, sizeof(*layer), GFP_KERNEL); > @@ -327,8 +336,10 @@ struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm, > return ERR_PTR(ret); > } > > - /* fixed zpos for now */ > - ret = drm_plane_create_zpos_immutable_property(&layer->plane, channel); > + plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num; > + > + ret = drm_plane_create_zpos_property(&layer->plane, channel, > + 0, plane_cnt - 1); > if (ret) { > dev_err(drm->dev, "Couldn't add zpos property\n"); > return ERR_PTR(ret); > diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c > index 5877f8ef5895..17e0d00cfd8a 100644 > --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c > +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c > @@ -21,7 +21,7 @@ > #include "sun8i_vi_scaler.h" > > static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel, > - int overlay, bool enable) > + int overlay, bool enable, unsigned int zpos) > { > u32 val; > > @@ -37,18 +37,24 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel, > SUN8I_MIXER_CHAN_VI_LAYER_ATTR(channel, overlay), > SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN, val); > > - if (enable) > - val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel); > - else > - val = 0; > + if (enable) { > + val = SUN8I_MIXER_BLEND_PIPE_CTL_EN(zpos); > > - regmap_update_bits(mixer->engine.regs, > - SUN8I_MIXER_BLEND_PIPE_CTL, > - SUN8I_MIXER_BLEND_PIPE_CTL_EN(channel), val); > + regmap_update_bits(mixer->engine.regs, > + SUN8I_MIXER_BLEND_PIPE_CTL, val, val); > + > + val = channel << SUN8I_MIXER_BLEND_ROUTE_PIPE_SHIFT(zpos); > + > + regmap_update_bits(mixer->engine.regs, > + SUN8I_MIXER_BLEND_ROUTE, > + SUN8I_MIXER_BLEND_ROUTE_PIPE_MSK(zpos), > + val); > + } > } > > static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, > - int overlay, struct drm_plane *plane) > + int overlay, struct drm_plane *plane, > + unsigned int zpos) > { > struct drm_plane_state *state = plane->state; > const struct drm_format_info *format = state->fb->format; > @@ -130,10 +136,10 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, > state->dst.x1, state->dst.y1); > DRM_DEBUG_DRIVER("Layer destination size W: %d H: %d\n", dst_w, dst_h); > regmap_write(mixer->engine.regs, > - SUN8I_MIXER_BLEND_ATTR_COORD(channel), > + SUN8I_MIXER_BLEND_ATTR_COORD(zpos), > SUN8I_MIXER_COORD(state->dst.x1, state->dst.y1)); > regmap_write(mixer->engine.regs, > - SUN8I_MIXER_BLEND_ATTR_INSIZE(channel), > + SUN8I_MIXER_BLEND_ATTR_INSIZE(zpos), > outsize); > > return 0; > @@ -266,28 +272,30 @@ static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane, > struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane); > struct sun8i_mixer *mixer = layer->mixer; > > - sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, false); > + sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, false, 0); > } > > static void sun8i_vi_layer_atomic_update(struct drm_plane *plane, > struct drm_plane_state *old_state) > { > struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane); > + unsigned int zpos = plane->state->normalized_zpos; > struct sun8i_mixer *mixer = layer->mixer; > > if (!plane->state->visible) { > sun8i_vi_layer_enable(mixer, layer->channel, > - layer->overlay, false); > + layer->overlay, false, 0); > return; > } > > sun8i_vi_layer_update_coord(mixer, layer->channel, > - layer->overlay, plane); > + 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); > + sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, > + true, zpos); > } > > static struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = { > @@ -351,6 +359,7 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, > int index) > { > struct sun8i_vi_layer *layer; > + unsigned int plane_cnt; > int ret; > > layer = devm_kzalloc(drm->dev, sizeof(*layer), GFP_KERNEL); > @@ -368,8 +377,10 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, > return ERR_PTR(ret); > } > > - /* fixed zpos for now */ > - ret = drm_plane_create_zpos_immutable_property(&layer->plane, index); > + plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num; > + > + ret = drm_plane_create_zpos_property(&layer->plane, index, > + 0, plane_cnt - 1); > if (ret) { > dev_err(drm->dev, "Couldn't add zpos property\n"); > return ERR_PTR(ret); -- Paul Kocialkowski, Bootlin (formerly Free Electrons) Embedded Linux and kernel engineering https://bootlin.com
Attachment:
signature.asc
Description: This is a digitally signed message part
_______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel