summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/sun4i/sun8i_ui_layer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/sun4i/sun8i_ui_layer.c')
-rw-r--r--drivers/gpu/drm/sun4i/sun8i_ui_layer.c59
1 files changed, 49 insertions, 10 deletions
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) {