Always enable pixel-level alpha blending with the background, so that
buffers which include an alpha channel are displayed correctly.

Signed-off-by: Brian Starkey <brian.starkey at arm.com>
---
 drivers/gpu/drm/arm/malidp_planes.c |   32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/arm/malidp_planes.c 
b/drivers/gpu/drm/arm/malidp_planes.c
index a17d24b..667b9ca 100644
--- a/drivers/gpu/drm/arm/malidp_planes.c
+++ b/drivers/gpu/drm/arm/malidp_planes.c
@@ -27,6 +27,10 @@
 #define   LAYER_H_FLIP                 (1 << 10)
 #define   LAYER_V_FLIP                 (1 << 11)
 #define   LAYER_ROT_MASK               (0xf << 8)
+#define   LAYER_COMP_MASK              (0x3 << 12)
+#define   LAYER_COMP_PIXEL             (0x3 << 12)
+#define   LAYER_COMP_PLANE             (0x2 << 12)
+#define MALIDP_LAYER_COMPOSE           0x008
 #define MALIDP_LAYER_SIZE              0x00c
 #define   LAYER_H_VAL(x)               (((x) & 0x1fff) << 0)
 #define   LAYER_V_VAL(x)               (((x) & 0x1fff) << 16)
@@ -34,6 +38,14 @@
 #define MALIDP_LAYER_OFFSET            0x014
 #define MALIDP_LAYER_STRIDE            0x018

+/*
+ * This 4-entry look-up-table is used to determine the full 8-bit alpha value
+ * for formats with 1- or 2-bit alpha channels.
+ * We set it to give 100%/0% opacity for 1-bit formats and 100%/66%/33%/0%
+ * opacity for 2-bit formats.
+ */
+#define MALIDP_ALPHA_LUT 0xffaa5500
+
 static void malidp_de_plane_destroy(struct drm_plane *plane)
 {
        struct malidp_plane *mp = to_malidp_plane(plane);
@@ -150,7 +162,7 @@ static void malidp_de_plane_update(struct drm_plane *plane,
        const struct malidp_hw_regmap *map;
        u8 format_id;
        u16 ptr;
-       u32 format, src_w, src_h, dest_w, dest_h, val = 0;
+       u32 format, src_w, src_h, dest_w, dest_h, val;
        int num_planes, i;

        mp = to_malidp_plane(plane);
@@ -194,10 +206,9 @@ static void malidp_de_plane_update(struct drm_plane *plane,
                        LAYER_V_VAL(plane->state->crtc_y),
                        mp->layer->base + MALIDP_LAYER_OFFSET);

-       /* first clear the rotation bits in the register */
-       malidp_hw_clearbits(mp->hwdev, LAYER_ROT_MASK,
-                           mp->layer->base + MALIDP_LAYER_CONTROL);
+       val = malidp_hw_read(mp->hwdev, mp->layer->base + MALIDP_LAYER_CONTROL);

+       val &= ~LAYER_ROT_MASK;
        /* setup the rotation and axis flip bits */
        if (plane->state->rotation & DRM_ROTATE_MASK)
                val = ilog2(plane->state->rotation & DRM_ROTATE_MASK) << 
LAYER_ROT_OFFSET;
@@ -206,11 +217,18 @@ static void malidp_de_plane_update(struct drm_plane 
*plane,
        if (plane->state->rotation & DRM_REFLECT_Y)
                val |= LAYER_H_FLIP;

+       /*
+        * always enable pixel alpha blending until we have a way to change
+        * blend modes
+        */
+       val &= ~LAYER_COMP_MASK;
+       val |= LAYER_COMP_PIXEL;
+
        /* set the 'enable layer' bit */
        val |= LAYER_ENABLE;

-       malidp_hw_setbits(mp->hwdev, val,
-                         mp->layer->base + MALIDP_LAYER_CONTROL);
+       malidp_hw_write(mp->hwdev, val,
+                       mp->layer->base + MALIDP_LAYER_CONTROL);
 }

 static void malidp_de_plane_disable(struct drm_plane *plane,
@@ -292,6 +310,8 @@ int malidp_de_planes_init(struct drm_device *drm)
                                                   
drm->mode_config.rotation_property,
                                                   DRM_ROTATE_0);

+               malidp_hw_write(malidp->dev, MALIDP_ALPHA_LUT,
+                               plane->layer->base + MALIDP_LAYER_COMPOSE);
        }

        kfree(formats);
-- 
1.7.9.5

Reply via email to