[PATCH] drm/sun4i: Implement zpos for DE2
Paul Kocialkowski
paul.kocialkowski at bootlin.com
Tue Jul 3 15:43:14 UTC 2018
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 at bootlin.com>
> Signed-off-by: Jernej Skrabec <jernej.skrabec at siol.net>
> ---
> 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: This is a digitally signed message part
URL: <https://lists.freedesktop.org/archives/dri-devel/attachments/20180703/1da698be/attachment-0001.sig>
More information about the dri-devel
mailing list