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 <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>
pull/1279/head
Jacopo Mondi 2025-06-16 14:14:24 +02:00 committed by Hans Verkuil
parent d883f2e7f4
commit 6c1dedf805
2 changed files with 41 additions and 0 deletions

View 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>
@ -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);

View 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__ */