]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
media: rcar-fcp: Add rcar_fcp_soft_reset()
authorJacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
Mon, 16 Jun 2025 12:14:24 +0000 (14:14 +0200)
committerHans Verkuil <hverkuil@xs4all.nl>
Wed, 18 Jun 2025 07:20:45 +0000 (09:20 +0200)
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 <jacopo.mondi+renesas@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Link: https://lore.kernel.org/r/20250616-vspx-reset-v2-1-6cc12ed7e9bb@ideasonboard.com
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
drivers/media/platform/renesas/rcar-fcp.c
include/media/rcar-fcp.h

index cee9bbce4e3affb2467dbc28142e1ab2304bf5b0..f90c86bbce6e25c9f1cb625ea597e2b1dc5fb6fe 100644 (file)
@@ -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>
 
 #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);
index 179240fb163bd2e7cc347e559f99bae943bf0e34..6ac9be9f675e667d6482a5a2483963fa52a0c622 100644 (file)
@@ -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__ */