media: rcar-vin: Add support for RGB formats with alpha component
authorNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Thu, 4 Jul 2019 17:16:01 +0000 (13:16 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Thu, 25 Jul 2019 15:46:58 +0000 (11:46 -0400)
The R-Car VIN module supports V4L2_PIX_FMT_ARGB555 and
V4L2_PIX_FMT_ABGR32 pixel formats. Add the hardware register setup and
allow the alpha component to be changed while streaming using the
V4L2_CID_ALPHA_COMPONENT control.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
[hverkuil-cisco@xs4all.nl: fix checkpatch warning for macro VNDMR_A8BIT]
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/platform/rcar-vin/rcar-dma.c
drivers/media/platform/rcar-vin/rcar-v4l2.c

index 99deed70dc67d6682b1a28d63e05905838d0ebaf..f16f2966f9628b728c5145007f56269aec93d6a7 100644 (file)
 #define VNIE_EFE               (1 << 1)
 
 /* Video n Data Mode Register bits */
+#define VNDMR_A8BIT(n)         (((n) & 0xff) << 24)
+#define VNDMR_A8BIT_MASK       (0xff << 24)
 #define VNDMR_EXRGB            (1 << 8)
 #define VNDMR_BPSM             (1 << 4)
+#define VNDMR_ABIT             (1 << 2)
 #define VNDMR_DTMD_YCSEP       (1 << 1)
 #define VNDMR_DTMD_ARGB                (1 << 0)
 
@@ -730,6 +733,12 @@ static int rvin_setup(struct rvin_dev *vin)
                /* Note: not supported on M1 */
                dmr = VNDMR_EXRGB;
                break;
+       case V4L2_PIX_FMT_ARGB555:
+               dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB;
+               break;
+       case V4L2_PIX_FMT_ABGR32:
+               dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB;
+               break;
        default:
                vin_err(vin, "Invalid pixelformat (0x%x)\n",
                        vin->format.pixelformat);
@@ -1346,5 +1355,31 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
 
 void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha)
 {
+       unsigned long flags;
+       u32 dmr;
+
+       spin_lock_irqsave(&vin->qlock, flags);
+
        vin->alpha = alpha;
+
+       if (vin->state == STOPPED)
+               goto out;
+
+       switch (vin->format.pixelformat) {
+       case V4L2_PIX_FMT_ARGB555:
+               dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT;
+               if (vin->alpha)
+                       dmr |= VNDMR_ABIT;
+               break;
+       case V4L2_PIX_FMT_ABGR32:
+               dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK;
+               dmr |= VNDMR_A8BIT(vin->alpha);
+               break;
+       default:
+               goto out;
+       }
+
+       rvin_write(vin, dmr,  VNDMR_REG);
+out:
+       spin_unlock_irqrestore(&vin->qlock, flags);
 }
index 04d798d8070f912cd87d8160ec67462a67501f8d..192390c784f7d11ddaaa352d8597ecd93b1715c6 100644 (file)
@@ -54,6 +54,14 @@ static const struct rvin_video_format rvin_formats[] = {
                .fourcc                 = V4L2_PIX_FMT_XBGR32,
                .bpp                    = 4,
        },
+       {
+               .fourcc                 = V4L2_PIX_FMT_ARGB555,
+               .bpp                    = 2,
+       },
+       {
+               .fourcc                 = V4L2_PIX_FMT_ABGR32,
+               .bpp                    = 4,
+       },
 };
 
 const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin,