On Mon Jun 16 14:14:24 2025 +0200, Jacopo Mondi wrote:
> Add a function to perform soft reset of the FCP.
>
> It is intended to support the correct stop procedure of the VSPX-FCPVX
> and VSPD-FCPD pairs according to section "62.3.7.3 Reset Operation" of
> the R-Car Hardware Manual at revision 1.20.
>
> Signed-off-by: Jacopo Mondi <[email protected]>
> Reviewed-by: Laurent Pinchart <[email protected]>
> Link:
> https://lore.kernel.org/r/[email protected]
> Signed-off-by: Laurent Pinchart <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>
Patch committed.
Thanks,
Hans Verkuil
drivers/media/platform/renesas/rcar-fcp.c | 36 +++++++++++++++++++++++++++++++
include/media/rcar-fcp.h | 5 +++++
2 files changed, 41 insertions(+)
---
diff --git a/drivers/media/platform/renesas/rcar-fcp.c
b/drivers/media/platform/renesas/rcar-fcp.c
index cee9bbce4e3a..f90c86bbce6e 100644
--- a/drivers/media/platform/renesas/rcar-fcp.c
+++ b/drivers/media/platform/renesas/rcar-fcp.c
@@ -9,6 +9,8 @@
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
@@ -19,14 +21,25 @@
#include <media/rcar-fcp.h>
+#define RCAR_FCP_REG_RST 0x0010
+#define RCAR_FCP_REG_RST_SOFTRST BIT(0)
+#define RCAR_FCP_REG_STA 0x0018
+#define RCAR_FCP_REG_STA_ACT BIT(0)
+
struct rcar_fcp_device {
struct list_head list;
struct device *dev;
+ void __iomem *base;
};
static LIST_HEAD(fcp_devices);
static DEFINE_MUTEX(fcp_lock);
+static inline void rcar_fcp_write(struct rcar_fcp_device *fcp, u32 reg, u32
val)
+{
+ iowrite32(val, fcp->base + reg);
+}
+
/*
-----------------------------------------------------------------------------
* Public API
*/
@@ -117,6 +130,25 @@ void rcar_fcp_disable(struct rcar_fcp_device *fcp)
}
EXPORT_SYMBOL_GPL(rcar_fcp_disable);
+int rcar_fcp_soft_reset(struct rcar_fcp_device *fcp)
+{
+ u32 value;
+ int ret;
+
+ if (!fcp)
+ return 0;
+
+ rcar_fcp_write(fcp, RCAR_FCP_REG_RST, RCAR_FCP_REG_RST_SOFTRST);
+ ret = readl_poll_timeout(fcp->base + RCAR_FCP_REG_STA,
+ value, !(value & RCAR_FCP_REG_STA_ACT),
+ 1, 100);
+ if (ret)
+ dev_err(fcp->dev, "Failed to soft-reset\n");
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(rcar_fcp_soft_reset);
+
/*
-----------------------------------------------------------------------------
* Platform Driver
*/
@@ -131,6 +163,10 @@ static int rcar_fcp_probe(struct platform_device *pdev)
fcp->dev = &pdev->dev;
+ fcp->base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(fcp->base))
+ return PTR_ERR(fcp->base);
+
dma_set_max_seg_size(fcp->dev, UINT_MAX);
pm_runtime_enable(&pdev->dev);
diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h
index 179240fb163b..6ac9be9f675e 100644
--- a/include/media/rcar-fcp.h
+++ b/include/media/rcar-fcp.h
@@ -18,6 +18,7 @@ void rcar_fcp_put(struct rcar_fcp_device *fcp);
struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp);
int rcar_fcp_enable(struct rcar_fcp_device *fcp);
void rcar_fcp_disable(struct rcar_fcp_device *fcp);
+int rcar_fcp_soft_reset(struct rcar_fcp_device *fcp);
#else
static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node
*np)
{
@@ -33,6 +34,10 @@ static inline int rcar_fcp_enable(struct rcar_fcp_device
*fcp)
return 0;
}
static inline void rcar_fcp_disable(struct rcar_fcp_device *fcp) { }
+static inline int rcar_fcp_soft_reset(struct rcar_fcp_device *fcp)
+{
+ return 0;
+}
#endif
#endif /* __MEDIA_RCAR_FCP_H__ */