Commit 6c1dedf8 authored by Jacopo Mondi's avatar Jacopo Mondi Committed by Hans Verkuil
Browse files

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: default avatarJacopo Mondi <jacopo.mondi+renesas@ideasonboard.com>
Reviewed-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Link: https://lore.kernel.org/r/20250616-vspx-reset-v2-1-6cc12ed7e9bb@ideasonboard.com


Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
parent d883f2e7
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -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);
+5 −0
Original line number Diff line number Diff line
@@ -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__ */