blob: a13ccc1ceb17af2bb63cadae22ac5c9ce76dc376 [file] [log] [blame]
From 1a6c2cd3b97eecba6327770092ab5841bcce0208 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niklas=20S=C3=B6derlund?=
<niklas.soderlund+renesas@ragnatech.se>
Date: Sat, 14 Apr 2018 07:57:13 -0400
Subject: [PATCH 1299/1795] media: rcar-vin: add function to manipulate Gen3
chsel value
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On Gen3 the CSI-2 routing is controlled by the VnCSI_IFMD register. One
feature of this register is that it's only present in the VIN0 and VIN4
instances. The register in VIN0 controls the routing for VIN0-3 and the
register in VIN4 controls routing for VIN4-7.
To be able to control routing from a media device this function is need
to control runtime PM for the subgroup master (VIN0 and VIN4). The
subgroup master must be switched on before the register is manipulated,
once the operation is complete it's safe to switch the master off and
the new routing will still be in effect.
Signed-off-by: Niklas Sรถderlund <niklas.soderlund+renesas@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
(cherry picked from commit 90dedce9bc5446411fde1229e212a9d2b07cd263)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
drivers/media/platform/rcar-vin/rcar-dma.c | 37 ++++++++++++++++++++++
drivers/media/platform/rcar-vin/rcar-vin.h | 2 ++
2 files changed, 39 insertions(+)
diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c
index 482d89bae657..905d975b2909 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -16,6 +16,7 @@
#include <linux/delay.h>
#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
#include <media/videobuf2-dma-contig.h>
@@ -1157,3 +1158,39 @@ int rvin_dma_register(struct rvin_dev *vin, int irq)
return ret;
}
+
+/* -----------------------------------------------------------------------------
+ * Gen3 CHSEL manipulation
+ */
+
+/*
+ * There is no need to have locking around changing the routing
+ * as it's only possible to do so when no VIN in the group is
+ * streaming so nothing can race with the VNMC register.
+ */
+int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel)
+{
+ u32 ifmd, vnmc;
+ int ret;
+
+ ret = pm_runtime_get_sync(vin->dev);
+ if (ret < 0)
+ return ret;
+
+ /* Make register writes take effect immediately. */
+ vnmc = rvin_read(vin, VNMC_REG);
+ rvin_write(vin, vnmc & ~VNMC_VUP, VNMC_REG);
+
+ ifmd = VNCSI_IFMD_DES1 | VNCSI_IFMD_DES0 | VNCSI_IFMD_CSI_CHSEL(chsel);
+
+ rvin_write(vin, ifmd, VNCSI_IFMD_REG);
+
+ vin_dbg(vin, "Set IFMD 0x%x\n", ifmd);
+
+ /* Restore VNMC. */
+ rvin_write(vin, vnmc, VNMC_REG);
+
+ pm_runtime_put(vin->dev);
+
+ return ret;
+}
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 321283f1618a..c19ddc5e08cb 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -169,4 +169,6 @@ const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat);
/* Cropping, composing and scaling */
void rvin_crop_scale_comp(struct rvin_dev *vin);
+int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel);
+
#endif
--
2.19.0