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
parent
d883f2e7f4
commit
6c1dedf805
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue