aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/rcar-vin/rcar-dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/rcar-vin/rcar-dma.c')
-rw-r--r--drivers/media/platform/rcar-vin/rcar-dma.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index 91ab064404a1..3cb29b2e0b2b 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -111,10 +111,13 @@
#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_ARGB1555 (1 << 0)
+#define VNDMR_DTMD_ARGB (1 << 0)
/* Video n Data Mode Register 2 bits */
#define VNDMR2_VPS (1 << 30)
@@ -574,6 +577,9 @@ static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin)
void rvin_crop_scale_comp(struct rvin_dev *vin)
{
+ const struct rvin_video_format *fmt;
+ u32 stride;
+
/* Set Start/End Pixel/Line Pre-Clip */
rvin_write(vin, vin->crop.left, VNSPPRC_REG);
rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG);
@@ -597,10 +603,9 @@ void rvin_crop_scale_comp(struct rvin_dev *vin)
if (vin->info->model != RCAR_GEN3)
rvin_crop_scale_comp_gen2(vin);
- if (vin->format.pixelformat == V4L2_PIX_FMT_NV16)
- rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG);
- else
- rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG);
+ fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
+ stride = vin->format.bytesperline / fmt->bpp;
+ rvin_write(vin, stride, VNIS_REG);
}
/* -----------------------------------------------------------------------------
@@ -721,7 +726,7 @@ static int rvin_setup(struct rvin_dev *vin)
output_is_yuv = true;
break;
case V4L2_PIX_FMT_XRGB555:
- dmr = VNDMR_DTMD_ARGB1555;
+ dmr = VNDMR_DTMD_ARGB;
break;
case V4L2_PIX_FMT_RGB565:
dmr = 0;
@@ -730,6 +735,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);
@@ -794,7 +805,7 @@ static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr)
int offsetx, offsety;
dma_addr_t offset;
- fmt = rvin_format_from_pixel(vin->format.pixelformat);
+ fmt = rvin_format_from_pixel(vin, vin->format.pixelformat);
/*
* There is no HW support for composition do the beast we can
@@ -1343,3 +1354,34 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
return 0;
}
+
+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);
+}