diff options
| author | Koji Matsuoka <koji.matsuoka.xm@renesas.com> | 2021-03-17 16:42:35 +0000 |
|---|---|---|
| committer | Kieran Bingham <kieran.bingham@ideasonboard.com> | 2021-06-17 13:00:53 +0100 |
| commit | 1f4e9a15a76d4eb298a2771b7ca0e94990098923 (patch) | |
| tree | cb716b701a0cb8f37504ef4b843b4a2cf82c1a48 | |
| parent | d4b40b8cdcfa662fa7b826aa0432f0c0f3662132 (diff) | |
| download | rcar-1f4e9a15a76d4eb298a2771b7ca0e94990098923.tar.gz | |
rcar-fcp: Add FCPVD reset sequence for VSPD
According to H/W manual v1.00, VSPD must be executed
FCP_RST.SOFTRST after VI6_SRESET.SRST. So this patch adds it.
VSPDL is not applicable.
Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com>
[ Kieran: Hrm ... changed it to gen == 3, but now I see VSPDL not
applicable ]
| -rw-r--r-- | drivers/media/platform/rcar-fcp.c | 53 | ||||
| -rw-r--r-- | drivers/media/platform/vsp1/vsp1_pipe.c | 5 | ||||
| -rw-r--r-- | include/media/rcar-fcp.h | 5 |
3 files changed, 63 insertions, 0 deletions
diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c index eb59a3ba6d0fe..ca92b5d0e0706 100644 --- a/drivers/media/platform/rcar-fcp.c +++ b/drivers/media/platform/rcar-fcp.c @@ -8,6 +8,8 @@ */ #include <linux/device.h> +#include <linux/delay.h> +#include <linux/io.h> #include <linux/dma-mapping.h> #include <linux/list.h> #include <linux/module.h> @@ -22,11 +24,19 @@ struct rcar_fcp_device { struct list_head list; struct device *dev; + void __iomem *base; }; static LIST_HEAD(fcp_devices); static DEFINE_MUTEX(fcp_lock); +#define FCP_VCR 0x00 +#define FCP_CFG0 0x04 +#define FCP_RST 0x10 +#define FCP_RST_SOFTRST BIT(0) +#define FCP_STA 0x18 +#define FCP_STA_ACT BIT(0) + /* ----------------------------------------------------------------------------- * Public API */ @@ -41,6 +51,16 @@ static DEFINE_MUTEX(fcp_lock); * Return a pointer to the FCP instance, or an ERR_PTR if the instance can't be * found. */ +static void fcp_write(struct rcar_fcp_device *fcp, u32 value, u32 offset) +{ + iowrite32(value, fcp->base + offset); +} + +static u32 fcp_read(struct rcar_fcp_device *fcp, u32 offset) +{ + return ioread32(fcp->base + offset); +} + struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np) { struct rcar_fcp_device *fcp; @@ -121,9 +141,34 @@ EXPORT_SYMBOL_GPL(rcar_fcp_disable); * Platform Driver */ +int rcar_fcp_reset(struct rcar_fcp_device *fcp) +{ + unsigned int timeout; + u32 status; + + fcp_write(fcp, FCP_RST_SOFTRST, FCP_RST); + + for (timeout = 10; timeout > 0; --timeout) { + status = fcp_read(fcp, FCP_STA); + if (!(status & FCP_STA_ACT)) + break; + + usleep_range(1000, 2000); + } + + if (!timeout) { + dev_err(fcp->dev, "failed to reset\n"); + return -ETIMEDOUT; + } + + return 0; +} +EXPORT_SYMBOL_GPL(rcar_fcp_reset); + static int rcar_fcp_probe(struct platform_device *pdev) { struct rcar_fcp_device *fcp; + struct resource *mem; fcp = devm_kzalloc(&pdev->dev, sizeof(*fcp), GFP_KERNEL); if (fcp == NULL) @@ -133,6 +178,14 @@ static int rcar_fcp_probe(struct platform_device *pdev) dma_set_max_seg_size(fcp->dev, UINT_MAX); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) + return -EINVAL; + + fcp->base = devm_ioremap_resource(fcp->dev, mem); + if (IS_ERR(fcp->base)) + return PTR_ERR(fcp->base); + pm_runtime_enable(&pdev->dev); mutex_lock(&fcp_lock); diff --git a/drivers/media/platform/vsp1/vsp1_pipe.c b/drivers/media/platform/vsp1/vsp1_pipe.c index f72ac01c21ea3..b0fbaaf1bdb0f 100644 --- a/drivers/media/platform/vsp1/vsp1_pipe.c +++ b/drivers/media/platform/vsp1/vsp1_pipe.c @@ -13,6 +13,7 @@ #include <linux/wait.h> #include <media/media-entity.h> +#include <media/rcar-fcp.h> #include <media/v4l2-subdev.h> #include "vsp1.h" @@ -327,6 +328,10 @@ int vsp1_pipeline_stop(struct vsp1_pipeline *pipe) pipe->state = VSP1_PIPELINE_STOPPED; spin_unlock_irqrestore(&pipe->irqlock, flags); } + + if (vsp1->info->gen == 3) + ret = rcar_fcp_reset(vsp1->fcp); + } else { /* Otherwise just request a stop and wait. */ spin_lock_irqsave(&pipe->irqlock, flags); diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h index 179240fb163bd..78dca42c9c981 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_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_reset(struct rcar_fcp_device *fcp) +{ + return 0; +} #endif #endif /* __MEDIA_RCAR_FCP_H__ */ |
