diff options
author | 2021-03-16 16:45:12 +1000 | |
---|---|---|
committer | 2021-03-16 17:08:46 +1000 | |
commit | 51c3b916a4d7e24b4918925965867fdd9bd8dd59 (patch) | |
tree | 3257e3e0fda7fbb0fe1425177b0c661db1bfee63 /drivers/gpu/drm/sun4i | |
parent | Linux 5.12-rc3 (diff) | |
parent | drm: fix drm_mode_create_blob comment (diff) | |
download | linux-51c3b916a4d7e24b4918925965867fdd9bd8dd59.tar.gz linux-51c3b916a4d7e24b4918925965867fdd9bd8dd59.tar.bz2 linux-51c3b916a4d7e24b4918925965867fdd9bd8dd59.zip |
Merge tag 'drm-misc-next-2021-03-03' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for 5.13:
UAPI Changes:
Cross-subsystem Changes:
Core Changes:
- %p4cc printk format modifier
- atomic: introduce drm_crtc_commit_wait, rework atomic plane state
helpers to take the drm_commit_state structure
- dma-buf: heaps rework to return a struct dma_buf
- simple-kms: Add plate state helpers
- ttm: debugfs support, removal of sysfs
Driver Changes:
- Convert drivers to shadow plane helpers
- arc: Move to drm/tiny
- ast: cursor plane reworks
- gma500: Remove TTM and medfield support
- mxsfb: imx8mm support
- panfrost: MMU IRQ handling rework
- qxl: rework to better handle resources deallocation, locking
- sun4i: Add alpha properties for UI and VI layers
- vc4: RPi4 CEC support
- vmwgfx: doc cleanup
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20210303100600.dgnkadonzuvfnu22@gilmour
Diffstat (limited to 'drivers/gpu/drm/sun4i')
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_backend.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun4i_layer.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun8i_ui_layer.c | 59 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun8i_ui_layer.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun8i_vi_layer.c | 78 | ||||
-rw-r--r-- | drivers/gpu/drm/sun4i/sun8i_vi_layer.h | 11 |
6 files changed, 137 insertions, 37 deletions
diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c index 522e51a404cc..bf8cfefa0365 100644 --- a/drivers/gpu/drm/sun4i/sun4i_backend.c +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c @@ -510,7 +510,6 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(plane_state); struct drm_framebuffer *fb = plane_state->fb; - struct drm_format_name_buf format_name; if (!sun4i_backend_plane_is_supported(plane_state, &layer_state->uses_frontend)) @@ -527,9 +526,8 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine, } } - DRM_DEBUG_DRIVER("Plane FB format is %s\n", - drm_get_format_name(fb->format->format, - &format_name)); + DRM_DEBUG_DRIVER("Plane FB format is %p4cc\n", + &fb->format->format); if (fb->format->has_alpha || (plane_state->alpha != DRM_BLEND_ALPHA_OPAQUE)) num_alpha_planes++; diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index acfbfd4463a1..11771bdd6e7c 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -6,8 +6,9 @@ * Maxime Ripard <maxime.ripard@free-electrons.com> */ +#include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> -#include <drm/drm_gem_framebuffer_helper.h> +#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_plane_helper.h> #include "sun4i_backend.h" @@ -63,8 +64,10 @@ static void sun4i_backend_layer_destroy_state(struct drm_plane *plane, } static void sun4i_backend_layer_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) + struct drm_atomic_state *state) { + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(old_state); struct sun4i_layer *layer = plane_to_sun4i_layer(plane); struct sun4i_backend *backend = layer->backend; @@ -81,9 +84,11 @@ static void sun4i_backend_layer_atomic_disable(struct drm_plane *plane, } static void sun4i_backend_layer_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) + struct drm_atomic_state *state) { - struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(plane->state); + struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, + plane); + struct sun4i_layer_state *layer_state = state_to_sun4i_layer_state(new_state); struct sun4i_layer *layer = plane_to_sun4i_layer(plane); struct sun4i_backend *backend = layer->backend; struct sun4i_frontend *frontend = backend->frontend; @@ -122,7 +127,7 @@ static bool sun4i_layer_format_mod_supported(struct drm_plane *plane, } static const struct drm_plane_helper_funcs sun4i_backend_layer_helper_funcs = { - .prepare_fb = drm_gem_fb_prepare_fb, + .prepare_fb = drm_gem_plane_helper_prepare_fb, .atomic_disable = sun4i_backend_layer_atomic_disable, .atomic_update = sun4i_backend_layer_atomic_update, }; diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c index 816ad4ce8996..0db164a774a1 100644 --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.c @@ -14,8 +14,8 @@ #include <drm/drm_crtc.h> #include <drm/drm_fb_cma_helper.h> #include <drm/drm_fourcc.h> +#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_cma_helper.h> -#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> @@ -72,6 +72,27 @@ static void sun8i_ui_layer_enable(struct sun8i_mixer *mixer, int channel, } } +static void sun8i_ui_layer_update_alpha(struct sun8i_mixer *mixer, int channel, + int overlay, struct drm_plane *plane) +{ + u32 mask, val, ch_base; + + ch_base = sun8i_channel_base(mixer, channel); + + mask = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_MASK | + SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK; + + val = SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA(plane->state->alpha >> 8); + + val |= (plane->state->alpha == DRM_BLEND_ALPHA_OPAQUE) ? + SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_PIXEL : + SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_COMBINED; + + regmap_update_bits(mixer->engine.regs, + SUN8I_MIXER_CHAN_UI_LAYER_ATTR(ch_base, overlay), + mask, val); +} + static int sun8i_ui_layer_update_coord(struct sun8i_mixer *mixer, int channel, int overlay, struct drm_plane *plane, unsigned int zpos) @@ -236,17 +257,20 @@ static int sun8i_ui_layer_update_buffer(struct sun8i_mixer *mixer, int channel, } static int sun8i_ui_layer_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) + struct drm_atomic_state *state) { + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, + plane); struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane); - struct drm_crtc *crtc = state->crtc; + struct drm_crtc *crtc = new_plane_state->crtc; struct drm_crtc_state *crtc_state; int min_scale, max_scale; if (!crtc) return 0; - crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); + crtc_state = drm_atomic_get_existing_crtc_state(state, + crtc); if (WARN_ON(!crtc_state)) return -EINVAL; @@ -258,14 +282,17 @@ static int sun8i_ui_layer_atomic_check(struct drm_plane *plane, max_scale = SUN8I_UI_SCALER_SCALE_MAX; } - return drm_atomic_helper_check_plane_state(state, crtc_state, + return drm_atomic_helper_check_plane_state(new_plane_state, + crtc_state, min_scale, max_scale, true, true); } static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) + struct drm_atomic_state *state) { + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); 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; @@ -275,14 +302,18 @@ static void sun8i_ui_layer_atomic_disable(struct drm_plane *plane, } static void sun8i_ui_layer_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) + struct drm_atomic_state *state) { + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); + struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, + plane); struct sun8i_ui_layer *layer = plane_to_sun8i_ui_layer(plane); - unsigned int zpos = plane->state->normalized_zpos; + unsigned int zpos = new_state->normalized_zpos; unsigned int old_zpos = old_state->normalized_zpos; struct sun8i_mixer *mixer = layer->mixer; - if (!plane->state->visible) { + if (!new_state->visible) { sun8i_ui_layer_enable(mixer, layer->channel, layer->overlay, false, 0, old_zpos); return; @@ -290,6 +321,8 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane, sun8i_ui_layer_update_coord(mixer, layer->channel, layer->overlay, plane, zpos); + sun8i_ui_layer_update_alpha(mixer, layer->channel, + layer->overlay, plane); sun8i_ui_layer_update_formats(mixer, layer->channel, layer->overlay, plane); sun8i_ui_layer_update_buffer(mixer, layer->channel, @@ -299,7 +332,7 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane, } static const struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = { - .prepare_fb = drm_gem_fb_prepare_fb, + .prepare_fb = drm_gem_plane_helper_prepare_fb, .atomic_check = sun8i_ui_layer_atomic_check, .atomic_disable = sun8i_ui_layer_atomic_disable, .atomic_update = sun8i_ui_layer_atomic_update, @@ -367,6 +400,12 @@ struct sun8i_ui_layer *sun8i_ui_layer_init_one(struct drm_device *drm, plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num; + ret = drm_plane_create_alpha_property(&layer->plane); + if (ret) { + dev_err(drm->dev, "Couldn't add alpha property\n"); + return ERR_PTR(ret); + } + ret = drm_plane_create_zpos_property(&layer->plane, channel, 0, plane_cnt - 1); if (ret) { diff --git a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h index f4ab1cf6cded..e3e32ee1178d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_ui_layer.h +++ b/drivers/gpu/drm/sun4i/sun8i_ui_layer.h @@ -40,6 +40,11 @@ #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_MASK GENMASK(12, 8) #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_FBFMT_OFFSET 8 #define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MASK GENMASK(31, 24) +#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA(x) ((x) << 24) + +#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_PIXEL ((0) << 1) +#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_LAYER ((1) << 1) +#define SUN8I_MIXER_CHAN_UI_LAYER_ATTR_ALPHA_MODE_COMBINED ((2) << 1) struct sun8i_mixer; diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c index 8cc294a9969d..46420780db59 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.c +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.c @@ -7,8 +7,8 @@ #include <drm/drm_atomic_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_fb_cma_helper.h> +#include <drm/drm_gem_atomic_helper.h> #include <drm/drm_gem_cma_helper.h> -#include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> @@ -66,6 +66,36 @@ static void sun8i_vi_layer_enable(struct sun8i_mixer *mixer, int channel, } } +static void sun8i_vi_layer_update_alpha(struct sun8i_mixer *mixer, int channel, + int overlay, struct drm_plane *plane) +{ + u32 mask, val, ch_base; + + ch_base = sun8i_channel_base(mixer, channel); + + if (mixer->cfg->is_de3) { + mask = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK | + SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_MASK; + val = SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA + (plane->state->alpha >> 8); + + val |= (plane->state->alpha == DRM_BLEND_ALPHA_OPAQUE) ? + SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_PIXEL : + SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_COMBINED; + + regmap_update_bits(mixer->engine.regs, + SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, + overlay), + mask, val); + } else if (mixer->cfg->vi_num == 1) { + regmap_update_bits(mixer->engine.regs, + SUN8I_MIXER_FCC_GLOBAL_ALPHA_REG, + SUN8I_MIXER_FCC_GLOBAL_ALPHA_MASK, + SUN8I_MIXER_FCC_GLOBAL_ALPHA + (plane->state->alpha >> 8)); + } +} + static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel, int overlay, struct drm_plane *plane, unsigned int zpos) @@ -268,14 +298,6 @@ static int sun8i_vi_layer_update_formats(struct sun8i_mixer *mixer, int channel, SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, overlay), SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE, val); - /* It seems that YUV formats use global alpha setting. */ - if (mixer->cfg->is_de3) - regmap_update_bits(mixer->engine.regs, - SUN8I_MIXER_CHAN_VI_LAYER_ATTR(ch_base, - overlay), - SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK, - SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(0xff)); - return 0; } @@ -339,17 +361,20 @@ static int sun8i_vi_layer_update_buffer(struct sun8i_mixer *mixer, int channel, } static int sun8i_vi_layer_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) + struct drm_atomic_state *state) { + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state, + plane); struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane); - struct drm_crtc *crtc = state->crtc; + struct drm_crtc *crtc = new_plane_state->crtc; struct drm_crtc_state *crtc_state; int min_scale, max_scale; if (!crtc) return 0; - crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc); + crtc_state = drm_atomic_get_existing_crtc_state(state, + crtc); if (WARN_ON(!crtc_state)) return -EINVAL; @@ -361,14 +386,17 @@ static int sun8i_vi_layer_atomic_check(struct drm_plane *plane, max_scale = SUN8I_VI_SCALER_SCALE_MAX; } - return drm_atomic_helper_check_plane_state(state, crtc_state, + return drm_atomic_helper_check_plane_state(new_plane_state, + crtc_state, min_scale, max_scale, true, true); } static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) + struct drm_atomic_state *state) { + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); 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; @@ -378,14 +406,18 @@ static void sun8i_vi_layer_atomic_disable(struct drm_plane *plane, } static void sun8i_vi_layer_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) + struct drm_atomic_state *state) { + struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, + plane); + struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, + plane); struct sun8i_vi_layer *layer = plane_to_sun8i_vi_layer(plane); - unsigned int zpos = plane->state->normalized_zpos; + unsigned int zpos = new_state->normalized_zpos; unsigned int old_zpos = old_state->normalized_zpos; struct sun8i_mixer *mixer = layer->mixer; - if (!plane->state->visible) { + if (!new_state->visible) { sun8i_vi_layer_enable(mixer, layer->channel, layer->overlay, false, 0, old_zpos); return; @@ -393,6 +425,8 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane, sun8i_vi_layer_update_coord(mixer, layer->channel, layer->overlay, plane, zpos); + sun8i_vi_layer_update_alpha(mixer, layer->channel, + layer->overlay, plane); sun8i_vi_layer_update_formats(mixer, layer->channel, layer->overlay, plane); sun8i_vi_layer_update_buffer(mixer, layer->channel, @@ -402,7 +436,7 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane, } static const struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = { - .prepare_fb = drm_gem_fb_prepare_fb, + .prepare_fb = drm_gem_plane_helper_prepare_fb, .atomic_check = sun8i_vi_layer_atomic_check, .atomic_disable = sun8i_vi_layer_atomic_disable, .atomic_update = sun8i_vi_layer_atomic_update, @@ -534,6 +568,14 @@ struct sun8i_vi_layer *sun8i_vi_layer_init_one(struct drm_device *drm, plane_cnt = mixer->cfg->ui_num + mixer->cfg->vi_num; + if (mixer->cfg->vi_num == 1 || mixer->cfg->is_de3) { + ret = drm_plane_create_alpha_property(&layer->plane); + if (ret) { + dev_err(drm->dev, "Couldn't add alpha property\n"); + return ERR_PTR(ret); + } + } + ret = drm_plane_create_zpos_property(&layer->plane, index, 0, plane_cnt - 1); if (ret) { diff --git a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h index eaa6076f5dbc..48c399e1c86d 100644 --- a/drivers/gpu/drm/sun4i/sun8i_vi_layer.h +++ b/drivers/gpu/drm/sun4i/sun8i_vi_layer.h @@ -29,14 +29,25 @@ #define SUN8I_MIXER_CHAN_VI_VDS_UV(base) \ ((base) + 0xfc) +#define SUN8I_MIXER_FCC_GLOBAL_ALPHA_REG \ + (0xAA000 + 0x90) + +#define SUN8I_MIXER_FCC_GLOBAL_ALPHA(x) ((x) << 24) +#define SUN8I_MIXER_FCC_GLOBAL_ALPHA_MASK GENMASK(31, 24) + #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_EN BIT(0) /* RGB mode should be set for RGB formats and cleared for YCbCr */ #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_RGB_MODE BIT(15) #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_OFFSET 8 #define SUN8I_MIXER_CHAN_VI_LAYER_ATTR_FBFMT_MASK GENMASK(12, 8) +#define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_MASK GENMASK(2, 1) #define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MASK GENMASK(31, 24) #define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA(x) ((x) << 24) +#define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_PIXEL ((0) << 1) +#define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_LAYER ((1) << 1) +#define SUN50I_MIXER_CHAN_VI_LAYER_ATTR_ALPHA_MODE_COMBINED ((2) << 1) + #define SUN8I_MIXER_CHAN_VI_DS_N(x) ((x) << 16) #define SUN8I_MIXER_CHAN_VI_DS_M(x) ((x) << 0) |