MLK-22600-1 drm/imx: dpu: kms: Support proper default blend mode
authorLiu Ying <victor.liu@nxp.com>
Tue, 3 Sep 2019 19:16:54 +0000 (15:16 -0400)
committerLiu Ying <victor.liu@nxp.com>
Fri, 20 Sep 2019 02:01:30 +0000 (10:01 +0800)
Without the new blend modes("None", "Pre-multiplied" and "Coverage")
introduced in the below commit, the old userspace assumes alpha in
pixel is per-premultiplied by default.  So, let's support the default
blend mode properly.

commit 468dba6432ca ("drm: Add per-plane pixel blend mode property")

Signed-off-by: Liu Ying <victor.liu@nxp.com>
(cherry picked from commit ebb7b4874493a8fb42de636e9421877a54399177)

drivers/gpu/drm/imx/dpu/dpu-plane.c
drivers/gpu/imx/dpu/dpu-fetchdecode.c
drivers/gpu/imx/dpu/dpu-fetchlayer.c
drivers/gpu/imx/dpu/dpu-fetchunit.c
drivers/gpu/imx/dpu/dpu-fetchwarp.c
drivers/gpu/imx/dpu/dpu-layerblend.c
drivers/gpu/imx/dpu/dpu-prv.h
include/video/dpu.h

index 19d6391..e26b8bc 100644 (file)
@@ -664,6 +664,7 @@ again:
        fu->ops->set_src_stride(fu, src_w, src_x, mt_w, bpp, fb->pitches[0],
                                baseaddr, use_prefetch);
        fu->ops->set_src_buf_dimensions(fu, src_w, src_h, 0, fb_is_interlaced);
+       fu->ops->set_pixel_blend_mode(fu, fb->format->format);
        fu->ops->set_fmt(fu, fb->format->format, fb_is_interlaced);
        fu->ops->enable_src_buf(fu);
        fu->ops->set_framedimensions(fu, src_w, src_h, fb_is_interlaced);
@@ -808,7 +809,7 @@ again:
        layerblend_pixengcfg_dynamic_prim_sel(lb, stage);
        layerblend_pixengcfg_dynamic_sec_sel(lb, source);
        layerblend_control(lb, LB_BLEND);
-       layerblend_blendcontrol(lb, need_hscaler || need_vscaler);
+       layerblend_blendcontrol(lb, state->normalized_zpos);
        layerblend_pixengcfg_clken(lb, CLKEN__AUTOMATIC);
        layerblend_position(lb, crtc_x, state->crtc_y);
 
index cf385a7..97685da 100644 (file)
@@ -378,6 +378,33 @@ void fetchdecode_clipoffset(struct dpu_fetchunit *fu, unsigned int x,
 }
 EXPORT_SYMBOL_GPL(fetchdecode_clipoffset);
 
+static void
+fetchdecode_set_pixel_blend_mode(struct dpu_fetchunit *fu, u32 fb_format)
+{
+       u32 val, mode = ALPHACONSTENABLE;
+
+       switch (fb_format) {
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_ABGR8888:
+       case DRM_FORMAT_RGBA8888:
+       case DRM_FORMAT_BGRA8888:
+               mode |= ALPHASRCENABLE;
+               break;
+       }
+
+       mutex_lock(&fu->mutex);
+       val = dpu_fu_read(fu, LAYERPROPERTY0);
+       val &= ~(PREMULCONSTRGB | ALPHA_ENABLE_MASK | RGB_ENABLE_MASK);
+       val |= mode;
+       dpu_fu_write(fu, val, LAYERPROPERTY0);
+
+       val = dpu_fu_read(fu, CONSTANTCOLOR0);
+       val &= ~CONSTANTALPHA_MASK;
+       val |= CONSTANTALPHA(0xff);
+       dpu_fu_write(fu, val, CONSTANTCOLOR0);
+       mutex_unlock(&fu->mutex);
+}
+
 static void fetchdecode_enable_src_buf(struct dpu_fetchunit *fu)
 {
        u32 val;
@@ -693,6 +720,7 @@ static const struct dpu_fetchunit_ops fd_ops = {
        .set_src_stride         = fetchdecode_set_src_stride,
        .set_src_buf_dimensions = fetchdecode_set_src_buf_dimensions,
        .set_fmt                = fetchdecode_set_fmt,
+       .set_pixel_blend_mode   = fetchdecode_set_pixel_blend_mode,
        .enable_src_buf         = fetchdecode_enable_src_buf,
        .disable_src_buf        = fetchdecode_disable_src_buf,
        .is_enabled             = fetchdecode_is_enabled,
index aedbab1..b6e64a7 100644 (file)
@@ -247,6 +247,7 @@ static const struct dpu_fetchunit_ops fl_ops = {
        .set_src_stride         = fetchunit_set_src_stride,
        .set_src_buf_dimensions = fetchlayer_set_src_buf_dimensions,
        .set_fmt                = fetchlayer_set_fmt,
+       .set_pixel_blend_mode   = fetchunit_set_pixel_blend_mode,
        .enable_src_buf         = fetchunit_enable_src_buf,
        .disable_src_buf        = fetchunit_disable_src_buf,
        .is_enabled             = fetchunit_is_enabled,
index cae8ff0..7c55909 100644 (file)
@@ -213,6 +213,33 @@ void fetchunit_set_src_stride(struct dpu_fetchunit *fu,
 }
 EXPORT_SYMBOL_GPL(fetchunit_set_src_stride);
 
+void fetchunit_set_pixel_blend_mode(struct dpu_fetchunit *fu, u32 fb_format)
+{
+       u32 val, mode = ALPHACONSTENABLE;
+
+       switch (fb_format) {
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_ABGR8888:
+       case DRM_FORMAT_RGBA8888:
+       case DRM_FORMAT_BGRA8888:
+               mode |= ALPHASRCENABLE;
+               break;
+       }
+
+       mutex_lock(&fu->mutex);
+       val = dpu_fu_read(fu, LAYERPROPERTY(fu->sub_id));
+       val &= ~(PREMULCONSTRGB | ALPHA_ENABLE_MASK | RGB_ENABLE_MASK);
+       val |= mode;
+       dpu_fu_write(fu, val, LAYERPROPERTY(fu->sub_id));
+
+       val = dpu_fu_read(fu, CONSTANTCOLOR(fu->sub_id));
+       val &= ~CONSTANTALPHA_MASK;
+       val |= CONSTANTALPHA(0xff);
+       dpu_fu_write(fu, val, CONSTANTCOLOR(fu->sub_id));
+       mutex_unlock(&fu->mutex);
+}
+EXPORT_SYMBOL_GPL(fetchunit_set_pixel_blend_mode);
+
 void fetchunit_enable_src_buf(struct dpu_fetchunit *fu)
 {
        u32 val;
index fc9eb70..ff0f318 100644 (file)
@@ -247,6 +247,7 @@ static const struct dpu_fetchunit_ops fw_ops = {
        .set_src_stride         = fetchunit_set_src_stride,
        .set_src_buf_dimensions = fetchwarp_set_src_buf_dimensions,
        .set_fmt                = fetchwarp_set_fmt,
+       .set_pixel_blend_mode   = fetchunit_set_pixel_blend_mode,
        .enable_src_buf         = fetchunit_enable_src_buf,
        .disable_src_buf        = fetchunit_disable_src_buf,
        .is_enabled             = fetchunit_is_enabled,
index e024599..66d0816 100644 (file)
@@ -58,12 +58,9 @@ static const lb_prim_sel_t prim_sels[] = {
 #define BLENDCONTROL                           0x10
 #define ALPHA(a)                               (((a) & 0xFF) << 16)
 #define PRIM_C_BLD_FUNC__ONE_MINUS_SEC_ALPHA   0x5
-#define PRIM_C_BLD_FUNC__PRIM_ALPHA            0x2
+#define PRIM_C_BLD_FUNC__ZERO                  0x0
 #define SEC_C_BLD_FUNC__CONST_ALPHA            (0x6 << 4)
-#define SEC_C_BLD_FUNC__ONE_MINUS_PRIM_ALPHA   (0x3 << 4)
-#define PRIM_A_BLD_FUNC__ONE_MINUS_SEC_ALPHA   (0x5 << 8)
 #define PRIM_A_BLD_FUNC__ZERO                  (0x0 << 8)
-#define SEC_A_BLD_FUNC__ONE                    (0x1 << 12)
 #define SEC_A_BLD_FUNC__ZERO                   (0x0 << 12)
 #define POSITION                               0x14
 #define XPOS(x)                                        ((x) & 0x7FFF)
@@ -223,16 +220,17 @@ void layerblend_control(struct dpu_layerblend *lb, lb_mode_t mode)
 }
 EXPORT_SYMBOL_GPL(layerblend_control);
 
-void layerblend_blendcontrol(struct dpu_layerblend *lb, bool sec_from_scaler)
+void layerblend_blendcontrol(struct dpu_layerblend *lb, unsigned int zpos)
 {
        u32 val;
 
-       val = ALPHA(0xff) |
-             PRIM_C_BLD_FUNC__PRIM_ALPHA |
-             SEC_C_BLD_FUNC__ONE_MINUS_PRIM_ALPHA |
-             PRIM_A_BLD_FUNC__ZERO;
+       val = ALPHA(0xff) | PRIM_A_BLD_FUNC__ZERO | SEC_A_BLD_FUNC__ZERO |
+             SEC_C_BLD_FUNC__CONST_ALPHA;
 
-       val |= sec_from_scaler ? SEC_A_BLD_FUNC__ZERO : SEC_A_BLD_FUNC__ONE;
+       if (zpos == 0)
+               val |= PRIM_C_BLD_FUNC__ZERO;
+       else
+               val |= PRIM_C_BLD_FUNC__ONE_MINUS_SEC_ALPHA;
 
        mutex_lock(&lb->mutex);
        dpu_lb_write(lb, val, BLENDCONTROL);
index 42cf8a4..3ac6c34 100644 (file)
@@ -73,6 +73,8 @@ enum linemode {
 #define CLIPWINDOWYOFFSET(y)           (((y) & 0x7FFF) << 16)
 #define CLIPWINDOWWIDTH(w)             (((w) - 1) & 0x3FFF)
 #define CLIPWINDOWHEIGHT(h)            ((((h) - 1) & 0x3FFF) << 16)
+#define CONSTANTALPHA_MASK             0xFF
+#define CONSTANTALPHA(n)               ((n) & CONSTANTALPHA_MASK)
 #define        PALETTEENABLE                   BIT(0)
 typedef enum {
        TILE_FILL_ZERO,
@@ -84,10 +86,16 @@ typedef enum {
 #define ALPHACONSTENABLE               BIT(9)
 #define ALPHAMASKENABLE                        BIT(10)
 #define ALPHATRANSENABLE               BIT(11)
+#define ALPHA_ENABLE_MASK              (ALPHASRCENABLE  | ALPHACONSTENABLE | \
+                                        ALPHAMASKENABLE | ALPHATRANSENABLE)
 #define RGBALPHASRCENABLE              BIT(12)
 #define RGBALPHACONSTENABLE            BIT(13)
 #define RGBALPHAMASKENABLE             BIT(14)
 #define RGBALPHATRANSENABLE            BIT(15)
+#define RGB_ENABLE_MASK                        (RGBALPHASRCENABLE   | \
+                                        RGBALPHACONSTENABLE | \
+                                        RGBALPHAMASKENABLE  | \
+                                        RGBALPHATRANSENABLE)
 #define PREMULCONSTRGB                 BIT(16)
 typedef enum {
        YUVCONVERSIONMODE__OFF,
index a5ad500..1fc5b2c 100644 (file)
@@ -477,6 +477,8 @@ struct dpu_fetchunit_ops {
 
        void (*set_fmt)(struct dpu_fetchunit *fu, u32 fmt, bool deinterlace);
 
+       void (*set_pixel_blend_mode)(struct dpu_fetchunit *fu, u32 fb_format);
+
        void (*enable_src_buf)(struct dpu_fetchunit *fu);
        void (*disable_src_buf)(struct dpu_fetchunit *fu);
        bool (*is_enabled)(struct dpu_fetchunit *fu);
@@ -678,7 +680,7 @@ void layerblend_shden(struct dpu_layerblend *lb, bool enable);
 void layerblend_shdtoksel(struct dpu_layerblend *lb, lb_shadow_sel_t sel);
 void layerblend_shdldsel(struct dpu_layerblend *lb, lb_shadow_sel_t sel);
 void layerblend_control(struct dpu_layerblend *lb, lb_mode_t mode);
-void layerblend_blendcontrol(struct dpu_layerblend *lb, bool sec_from_scaler);
+void layerblend_blendcontrol(struct dpu_layerblend *lb, unsigned int zpos);
 void layerblend_position(struct dpu_layerblend *lb, int x, int y);
 struct dpu_layerblend *dpu_lb_get(struct dpu_soc *dpu, int id);
 void dpu_lb_put(struct dpu_layerblend *lb);
@@ -790,6 +792,7 @@ void fetchunit_set_src_stride(struct dpu_fetchunit *fu,
                              unsigned int width, unsigned int x_offset,
                              unsigned int mt_w, int bpp, unsigned int stride,
                              dma_addr_t baddr, bool use_prefetch);
+void fetchunit_set_pixel_blend_mode(struct dpu_fetchunit *fu, u32 fb_format);
 void fetchunit_enable_src_buf(struct dpu_fetchunit *fu);
 void fetchunit_disable_src_buf(struct dpu_fetchunit *fu);
 bool fetchunit_is_enabled(struct dpu_fetchunit *fu);