From 6c1dedf805ecd304236a83a2057ed803fb6b32f6 Mon Sep 17 00:00:00 2001 From: Jacopo Mondi Date: Mon, 16 Jun 2025 14:14:24 +0200 Subject: [PATCH] media: rcar-fcp: Add rcar_fcp_soft_reset() 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 Reviewed-by: Laurent Pinchart Link: https://lore.kernel.org/r/20250616-vspx-reset-v2-1-6cc12ed7e9bb@ideasonboard.com Signed-off-by: Laurent Pinchart Signed-off-by: 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 cee9bbce4e3af..f90c86bbce6e2 100644 --- a/drivers/media/platform/renesas/rcar-fcp.c +++ b/drivers/media/platform/renesas/rcar-fcp.c @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include #include @@ -19,14 +21,25 @@ #include +#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 179240fb163bd..6ac9be9f675e6 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__ */ -- 2.47.2