@@ -14,6 +14,11 @@ Required properties:
- interrupts: VSP interrupt specifier.
- clocks: A phandle + clock-specifier pair for the VSP functional clock.
+Optional properties:
+
+ - renesas,fcp: A phandle referencing the FCP that handles memory accesses
+ for the VSP. Not needed on Gen2, mandatory on Gen3.
+
Example: R8A7790 (R-Car H2) VSP1-S node
@@ -272,6 +272,7 @@ config VIDEO_RENESAS_VSP1
tristate "Renesas VSP1 Video Processing Engine"
depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API && HAS_DMA
depends on (ARCH_SHMOBILE && OF) || COMPILE_TEST
+ depends on m || VIDEO_RENESAS_FCP != m
select VIDEOBUF2_DMA_CONTIG
---help---
This is a V4L2 driver for the Renesas VSP1 video processing engine.
@@ -25,6 +25,7 @@
struct clk;
struct device;
+struct rcar_fcp_device;
struct vsp1_dl;
struct vsp1_drm;
@@ -63,6 +64,7 @@ struct vsp1_device {
void __iomem *mmio;
struct clk *clock;
+ struct rcar_fcp_device *fcp;
struct mutex lock;
int ref_count;
@@ -21,6 +21,7 @@
#include <linux/platform_device.h>
#include <linux/videodev2.h>
+#include <media/rcar-fcp.h>
#include <media/v4l2-subdev.h>
#include "vsp1.h"
@@ -491,8 +492,11 @@ int vsp1_device_get(struct vsp1_device *vsp1)
if (ret < 0)
goto done;
+ rcar_fcp_enable(vsp1->fcp);
+
ret = vsp1_device_init(vsp1);
if (ret < 0) {
+ rcar_fcp_disable(vsp1->fcp);
clk_disable_unprepare(vsp1->clock);
goto done;
}
@@ -515,8 +519,10 @@ void vsp1_device_put(struct vsp1_device *vsp1)
{
mutex_lock(&vsp1->lock);
- if (--vsp1->ref_count == 0)
+ if (--vsp1->ref_count == 0) {
+ rcar_fcp_disable(vsp1->fcp);
clk_disable_unprepare(vsp1->clock);
+ }
mutex_unlock(&vsp1->lock);
}
@@ -537,6 +543,7 @@ static int vsp1_pm_suspend(struct device *dev)
vsp1_pipelines_suspend(vsp1);
+ rcar_fcp_disable(vsp1->fcp);
clk_disable_unprepare(vsp1->clock);
return 0;
@@ -552,6 +559,7 @@ static int vsp1_pm_resume(struct device *dev)
return 0;
clk_prepare_enable(vsp1->clock);
+ rcar_fcp_enable(vsp1->fcp);
vsp1_pipelines_resume(vsp1);
@@ -633,6 +641,7 @@ static const struct vsp1_device_info vsp1_device_infos[] = {
static int vsp1_probe(struct platform_device *pdev)
{
struct vsp1_device *vsp1;
+ struct device_node *fcp_node;
struct resource *irq;
struct resource *io;
unsigned int i;
@@ -673,6 +682,18 @@ static int vsp1_probe(struct platform_device *pdev)
return ret;
}
+ /* FCP (optional) */
+ fcp_node = of_parse_phandle(pdev->dev.of_node, "renesas,fcp", 0);
+ if (fcp_node) {
+ vsp1->fcp = rcar_fcp_get(fcp_node);
+ of_node_put(fcp_node);
+ if (IS_ERR(vsp1->fcp)) {
+ dev_dbg(&pdev->dev, "FCP not found (%ld)\n",
+ PTR_ERR(vsp1->fcp));
+ return PTR_ERR(vsp1->fcp);
+ }
+ }
+
/* Configure device parameters based on the version register. */
ret = clk_prepare_enable(vsp1->clock);
if (ret < 0)
@@ -713,6 +734,7 @@ static int vsp1_remove(struct platform_device *pdev)
struct vsp1_device *vsp1 = platform_get_drvdata(pdev);
vsp1_destroy_entities(vsp1);
+ rcar_fcp_put(vsp1->fcp);
return 0;
}
On some platforms the VSP performs memory accesses through an FCP. When that's the case get a reference to the FCP from the VSP DT node and enable/disable it at runtime as needed. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> --- .../devicetree/bindings/media/renesas,vsp1.txt | 5 +++++ drivers/media/platform/Kconfig | 1 + drivers/media/platform/vsp1/vsp1.h | 2 ++ drivers/media/platform/vsp1/vsp1_drv.c | 24 +++++++++++++++++++++- 4 files changed, 31 insertions(+), 1 deletion(-)