aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoji Matsuoka <koji.matsuoka.xm@renesas.com>2021-03-17 16:42:35 +0000
committerKieran Bingham <kieran.bingham@ideasonboard.com>2021-06-17 13:00:53 +0100
commit1f4e9a15a76d4eb298a2771b7ca0e94990098923 (patch)
treecb716b701a0cb8f37504ef4b843b4a2cf82c1a48
parentd4b40b8cdcfa662fa7b826aa0432f0c0f3662132 (diff)
downloadrcar-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.c53
-rw-r--r--drivers/media/platform/vsp1/vsp1_pipe.c5
-rw-r--r--include/media/rcar-fcp.h5
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__ */