* [PATCH v2 1/5] v4l: rcar-fcp: Don't get/put module reference
2017-05-16 23:20 [PATCH v2 0/5] R-Car DU: Fix IOMMU operation when connected to VSP Laurent Pinchart
@ 2017-05-16 23:20 ` Laurent Pinchart
2017-05-16 23:20 ` [PATCH v2 2/5] v4l: rcar-fcp: Add an API to retrieve the FCP device Laurent Pinchart
` (3 subsequent siblings)
4 siblings, 0 replies; 18+ messages in thread
From: Laurent Pinchart @ 2017-05-16 23:20 UTC (permalink / raw)
To: dri-devel; +Cc: linux-renesas-soc
Direct callers of the FCP API hold a reference to the FCP module due to
module linkage, there's no need to take another one manually. Take a
reference to the device instead to ensure that it won't disappear behind
the caller's back.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/media/platform/rcar-fcp.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
index 7146fc5ef168..e9f609edf513 100644
--- a/drivers/media/platform/rcar-fcp.c
+++ b/drivers/media/platform/rcar-fcp.c
@@ -53,14 +53,7 @@ struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
if (fcp->dev->of_node != np)
continue;
- /*
- * Make sure the module won't be unloaded behind our back. This
- * is a poor man's safety net, the module should really not be
- * unloaded while FCP users can be active.
- */
- if (!try_module_get(fcp->dev->driver->owner))
- fcp = NULL;
-
+ get_device(fcp->dev);
goto done;
}
@@ -81,7 +74,7 @@ EXPORT_SYMBOL_GPL(rcar_fcp_get);
void rcar_fcp_put(struct rcar_fcp_device *fcp)
{
if (fcp)
- module_put(fcp->dev->driver->owner);
+ put_device(fcp->dev);
}
EXPORT_SYMBOL_GPL(rcar_fcp_put);
--
Regards,
Laurent Pinchart
^ permalink raw reply related [flat|nested] 18+ messages in thread* [PATCH v2 1/5] v4l: rcar-fcp: Don't get/put module reference
@ 2017-05-16 23:20 ` Laurent Pinchart
0 siblings, 0 replies; 18+ messages in thread
From: Laurent Pinchart @ 2017-05-16 23:20 UTC (permalink / raw)
To: dri-devel; +Cc: linux-renesas-soc
Direct callers of the FCP API hold a reference to the FCP module due to
module linkage, there's no need to take another one manually. Take a
reference to the device instead to ensure that it won't disappear behind
the caller's back.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/media/platform/rcar-fcp.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
index 7146fc5ef168..e9f609edf513 100644
--- a/drivers/media/platform/rcar-fcp.c
+++ b/drivers/media/platform/rcar-fcp.c
@@ -53,14 +53,7 @@ struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
if (fcp->dev->of_node != np)
continue;
- /*
- * Make sure the module won't be unloaded behind our back. This
- * is a poor man's safety net, the module should really not be
- * unloaded while FCP users can be active.
- */
- if (!try_module_get(fcp->dev->driver->owner))
- fcp = NULL;
-
+ get_device(fcp->dev);
goto done;
}
@@ -81,7 +74,7 @@ EXPORT_SYMBOL_GPL(rcar_fcp_get);
void rcar_fcp_put(struct rcar_fcp_device *fcp)
{
if (fcp)
- module_put(fcp->dev->driver->owner);
+ put_device(fcp->dev);
}
EXPORT_SYMBOL_GPL(rcar_fcp_put);
--
Regards,
Laurent Pinchart
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 1/5] v4l: rcar-fcp: Don't get/put module reference
2017-05-16 23:20 ` Laurent Pinchart
(?)
@ 2017-05-22 11:36 ` Kieran Bingham
-1 siblings, 0 replies; 18+ messages in thread
From: Kieran Bingham @ 2017-05-22 11:36 UTC (permalink / raw)
To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc
Hi Laurent,
Thanks for the patch:
On 17/05/17 00:20, Laurent Pinchart wrote:
> Direct callers of the FCP API hold a reference to the FCP module due to
> module linkage, there's no need to take another one manually. Take a
> reference to the device instead to ensure that it won't disappear behind
> the caller's back.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
> drivers/media/platform/rcar-fcp.c | 11 ++---------
> 1 file changed, 2 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
> index 7146fc5ef168..e9f609edf513 100644
> --- a/drivers/media/platform/rcar-fcp.c
> +++ b/drivers/media/platform/rcar-fcp.c
> @@ -53,14 +53,7 @@ struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
> if (fcp->dev->of_node != np)
> continue;
>
> - /*
> - * Make sure the module won't be unloaded behind our back. This
> - * is a poor man's safety net, the module should really not be
> - * unloaded while FCP users can be active.
> - */
> - if (!try_module_get(fcp->dev->driver->owner))
> - fcp = NULL;
> -
> + get_device(fcp->dev);
> goto done;
> }
>
> @@ -81,7 +74,7 @@ EXPORT_SYMBOL_GPL(rcar_fcp_get);
> void rcar_fcp_put(struct rcar_fcp_device *fcp)
> {
> if (fcp)
> - module_put(fcp->dev->driver->owner);
> + put_device(fcp->dev);
> }
> EXPORT_SYMBOL_GPL(rcar_fcp_put);
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 2/5] v4l: rcar-fcp: Add an API to retrieve the FCP device
2017-05-16 23:20 [PATCH v2 0/5] R-Car DU: Fix IOMMU operation when connected to VSP Laurent Pinchart
2017-05-16 23:20 ` Laurent Pinchart
@ 2017-05-16 23:20 ` Laurent Pinchart
2017-05-22 11:44 ` Kieran Bingham
2017-05-16 23:20 ` [PATCH v2 3/5] v4l: vsp1: Map the DL and video buffers through the proper bus master Laurent Pinchart
` (2 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Laurent Pinchart @ 2017-05-16 23:20 UTC (permalink / raw)
To: dri-devel; +Cc: linux-renesas-soc
The new rcar_fcp_get_device() function retrieves the struct device
related to the FCP device. This is useful to handle DMA mapping through
the right device.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/media/platform/rcar-fcp.c | 6 ++++++
include/media/rcar-fcp.h | 5 +++++
2 files changed, 11 insertions(+)
diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
index e9f609edf513..2988031d285d 100644
--- a/drivers/media/platform/rcar-fcp.c
+++ b/drivers/media/platform/rcar-fcp.c
@@ -78,6 +78,12 @@ void rcar_fcp_put(struct rcar_fcp_device *fcp)
}
EXPORT_SYMBOL_GPL(rcar_fcp_put);
+struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp)
+{
+ return fcp->dev;
+}
+EXPORT_SYMBOL_GPL(rcar_fcp_get_device);
+
/**
* rcar_fcp_enable - Enable an FCP
* @fcp: The FCP instance
diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h
index 8723f05c6321..b60a7b176c37 100644
--- a/include/media/rcar-fcp.h
+++ b/include/media/rcar-fcp.h
@@ -19,6 +19,7 @@ struct rcar_fcp_device;
#if IS_ENABLED(CONFIG_VIDEO_RENESAS_FCP)
struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np);
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);
#else
@@ -27,6 +28,10 @@ static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
return ERR_PTR(-ENOENT);
}
static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { }
+static inline struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp)
+{
+ return NULL;
+}
static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp)
{
return 0;
--
Regards,
Laurent Pinchart
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 2/5] v4l: rcar-fcp: Add an API to retrieve the FCP device
2017-05-16 23:20 ` [PATCH v2 2/5] v4l: rcar-fcp: Add an API to retrieve the FCP device Laurent Pinchart
@ 2017-05-22 11:44 ` Kieran Bingham
0 siblings, 0 replies; 18+ messages in thread
From: Kieran Bingham @ 2017-05-22 11:44 UTC (permalink / raw)
To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc
Hi Laurent,
Thankyou for the patch:
On 17/05/17 00:20, Laurent Pinchart wrote:
> The new rcar_fcp_get_device() function retrieves the struct device
> related to the FCP device. This is useful to handle DMA mapping through
> the right device.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
> drivers/media/platform/rcar-fcp.c | 6 ++++++
> include/media/rcar-fcp.h | 5 +++++
> 2 files changed, 11 insertions(+)
>
> diff --git a/drivers/media/platform/rcar-fcp.c b/drivers/media/platform/rcar-fcp.c
> index e9f609edf513..2988031d285d 100644
> --- a/drivers/media/platform/rcar-fcp.c
> +++ b/drivers/media/platform/rcar-fcp.c
> @@ -78,6 +78,12 @@ void rcar_fcp_put(struct rcar_fcp_device *fcp)
> }
> EXPORT_SYMBOL_GPL(rcar_fcp_put);
>
> +struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp)
> +{
> + return fcp->dev;
> +}
> +EXPORT_SYMBOL_GPL(rcar_fcp_get_device);
> +
> /**
> * rcar_fcp_enable - Enable an FCP
> * @fcp: The FCP instance
> diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h
> index 8723f05c6321..b60a7b176c37 100644
> --- a/include/media/rcar-fcp.h
> +++ b/include/media/rcar-fcp.h
> @@ -19,6 +19,7 @@ struct rcar_fcp_device;
> #if IS_ENABLED(CONFIG_VIDEO_RENESAS_FCP)
> struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np);
> 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);
> #else
> @@ -27,6 +28,10 @@ static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
> return ERR_PTR(-ENOENT);
> }
> static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { }
> +static inline struct device *rcar_fcp_get_device(struct rcar_fcp_device *fcp)
> +{
> + return NULL;
> +}
> static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp)
> {
> return 0;
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 3/5] v4l: vsp1: Map the DL and video buffers through the proper bus master
2017-05-16 23:20 [PATCH v2 0/5] R-Car DU: Fix IOMMU operation when connected to VSP Laurent Pinchart
2017-05-16 23:20 ` Laurent Pinchart
2017-05-16 23:20 ` [PATCH v2 2/5] v4l: rcar-fcp: Add an API to retrieve the FCP device Laurent Pinchart
@ 2017-05-16 23:20 ` Laurent Pinchart
2017-05-22 11:47 ` Kieran Bingham
2017-05-16 23:20 ` [PATCH v2 4/5] v4l: vsp1: Add API to map and unmap DRM buffers through the VSP Laurent Pinchart
2017-05-16 23:20 ` [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device Laurent Pinchart
4 siblings, 1 reply; 18+ messages in thread
From: Laurent Pinchart @ 2017-05-16 23:20 UTC (permalink / raw)
To: dri-devel; +Cc: linux-renesas-soc
From: Magnus Damm <magnus.damm@gmail.com>
On Gen2 hardware the VSP1 is a bus master and accesses the display list
and video buffers through DMA directly. On Gen3 hardware, however,
memory accesses go through a separate IP core called FCP.
The VSP1 driver unconditionally maps DMA buffers through the VSP device.
While this doesn't cause any practical issue so far, DMA mappings will
be incorrect as soon as we will enable IOMMU support for the FCP on Gen3
platforms, resulting in IOMMU faults.
Fix this by mapping all buffers through the FCP device if present, and
through the VSP1 device as usual otherwise.
Suggested-by: Magnus Damm <magnus.damm@gmail.com>
[Cache the bus master device]
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/media/platform/vsp1/vsp1.h | 1 +
drivers/media/platform/vsp1/vsp1_dl.c | 4 ++--
drivers/media/platform/vsp1/vsp1_drv.c | 9 +++++++++
drivers/media/platform/vsp1/vsp1_video.c | 2 +-
4 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
index 85387a64179a..847963b6e9eb 100644
--- a/drivers/media/platform/vsp1/vsp1.h
+++ b/drivers/media/platform/vsp1/vsp1.h
@@ -74,6 +74,7 @@ struct vsp1_device {
void __iomem *mmio;
struct rcar_fcp_device *fcp;
+ struct device *bus_master;
struct vsp1_bru *bru;
struct vsp1_clu *clu;
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 7d8f37772b56..445d1c31fff3 100644
--- a/drivers/media/platform/vsp1/vsp1_dl.c
+++ b/drivers/media/platform/vsp1/vsp1_dl.c
@@ -137,7 +137,7 @@ static int vsp1_dl_body_init(struct vsp1_device *vsp1,
dlb->vsp1 = vsp1;
dlb->size = size;
- dlb->entries = dma_alloc_wc(vsp1->dev, dlb->size, &dlb->dma,
+ dlb->entries = dma_alloc_wc(vsp1->bus_master, dlb->size, &dlb->dma,
GFP_KERNEL);
if (!dlb->entries)
return -ENOMEM;
@@ -150,7 +150,7 @@ static int vsp1_dl_body_init(struct vsp1_device *vsp1,
*/
static void vsp1_dl_body_cleanup(struct vsp1_dl_body *dlb)
{
- dma_free_wc(dlb->vsp1->dev, dlb->size, dlb->entries, dlb->dma);
+ dma_free_wc(dlb->vsp1->bus_master, dlb->size, dlb->entries, dlb->dma);
}
/**
diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
index 048446af5ae7..95c26edead85 100644
--- a/drivers/media/platform/vsp1/vsp1_drv.c
+++ b/drivers/media/platform/vsp1/vsp1_drv.c
@@ -764,6 +764,15 @@ static int vsp1_probe(struct platform_device *pdev)
PTR_ERR(vsp1->fcp));
return PTR_ERR(vsp1->fcp);
}
+
+ /*
+ * When the FCP is present, it handles all bus master accesses
+ * for the VSP and must thus be used in place of the VSP device
+ * to map DMA buffers.
+ */
+ vsp1->bus_master = rcar_fcp_get_device(vsp1->fcp);
+ } else {
+ vsp1->bus_master = vsp1->dev;
}
/* Configure device parameters based on the version register. */
diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
index eab3c3ea85d7..5af3486afe07 100644
--- a/drivers/media/platform/vsp1/vsp1_video.c
+++ b/drivers/media/platform/vsp1/vsp1_video.c
@@ -1197,7 +1197,7 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
video->queue.ops = &vsp1_video_queue_qops;
video->queue.mem_ops = &vb2_dma_contig_memops;
video->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
- video->queue.dev = video->vsp1->dev;
+ video->queue.dev = video->vsp1->bus_master;
ret = vb2_queue_init(&video->queue);
if (ret < 0) {
dev_err(video->vsp1->dev, "failed to initialize vb2 queue\n");
--
Regards,
Laurent Pinchart
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 3/5] v4l: vsp1: Map the DL and video buffers through the proper bus master
2017-05-16 23:20 ` [PATCH v2 3/5] v4l: vsp1: Map the DL and video buffers through the proper bus master Laurent Pinchart
@ 2017-05-22 11:47 ` Kieran Bingham
0 siblings, 0 replies; 18+ messages in thread
From: Kieran Bingham @ 2017-05-22 11:47 UTC (permalink / raw)
To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc
Hi Laurent,
Thanks for the patch:
On 17/05/17 00:20, Laurent Pinchart wrote:
> From: Magnus Damm <magnus.damm@gmail.com>
>
> On Gen2 hardware the VSP1 is a bus master and accesses the display list
> and video buffers through DMA directly. On Gen3 hardware, however,
> memory accesses go through a separate IP core called FCP.
>
> The VSP1 driver unconditionally maps DMA buffers through the VSP device.
> While this doesn't cause any practical issue so far, DMA mappings will
> be incorrect as soon as we will enable IOMMU support for the FCP on Gen3
> platforms, resulting in IOMMU faults.
>
> Fix this by mapping all buffers through the FCP device if present, and
> through the VSP1 device as usual otherwise.
>
> Suggested-by: Magnus Damm <magnus.damm@gmail.com>
> [Cache the bus master device]
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
> drivers/media/platform/vsp1/vsp1.h | 1 +
> drivers/media/platform/vsp1/vsp1_dl.c | 4 ++--
> drivers/media/platform/vsp1/vsp1_drv.c | 9 +++++++++
> drivers/media/platform/vsp1/vsp1_video.c | 2 +-
> 4 files changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h
> index 85387a64179a..847963b6e9eb 100644
> --- a/drivers/media/platform/vsp1/vsp1.h
> +++ b/drivers/media/platform/vsp1/vsp1.h
> @@ -74,6 +74,7 @@ struct vsp1_device {
>
> void __iomem *mmio;
> struct rcar_fcp_device *fcp;
> + struct device *bus_master;
>
> struct vsp1_bru *bru;
> struct vsp1_clu *clu;
> diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
> index 7d8f37772b56..445d1c31fff3 100644
> --- a/drivers/media/platform/vsp1/vsp1_dl.c
> +++ b/drivers/media/platform/vsp1/vsp1_dl.c
> @@ -137,7 +137,7 @@ static int vsp1_dl_body_init(struct vsp1_device *vsp1,
> dlb->vsp1 = vsp1;
> dlb->size = size;
>
> - dlb->entries = dma_alloc_wc(vsp1->dev, dlb->size, &dlb->dma,
> + dlb->entries = dma_alloc_wc(vsp1->bus_master, dlb->size, &dlb->dma,
> GFP_KERNEL);
> if (!dlb->entries)
> return -ENOMEM;
> @@ -150,7 +150,7 @@ static int vsp1_dl_body_init(struct vsp1_device *vsp1,
> */
> static void vsp1_dl_body_cleanup(struct vsp1_dl_body *dlb)
> {
> - dma_free_wc(dlb->vsp1->dev, dlb->size, dlb->entries, dlb->dma);
> + dma_free_wc(dlb->vsp1->bus_master, dlb->size, dlb->entries, dlb->dma);
> }
>
> /**
> diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c
> index 048446af5ae7..95c26edead85 100644
> --- a/drivers/media/platform/vsp1/vsp1_drv.c
> +++ b/drivers/media/platform/vsp1/vsp1_drv.c
> @@ -764,6 +764,15 @@ static int vsp1_probe(struct platform_device *pdev)
> PTR_ERR(vsp1->fcp));
> return PTR_ERR(vsp1->fcp);
> }
> +
> + /*
> + * When the FCP is present, it handles all bus master accesses
> + * for the VSP and must thus be used in place of the VSP device
> + * to map DMA buffers.
> + */
> + vsp1->bus_master = rcar_fcp_get_device(vsp1->fcp);
> + } else {
> + vsp1->bus_master = vsp1->dev;
> }
>
> /* Configure device parameters based on the version register. */
> diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
> index eab3c3ea85d7..5af3486afe07 100644
> --- a/drivers/media/platform/vsp1/vsp1_video.c
> +++ b/drivers/media/platform/vsp1/vsp1_video.c
> @@ -1197,7 +1197,7 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1,
> video->queue.ops = &vsp1_video_queue_qops;
> video->queue.mem_ops = &vb2_dma_contig_memops;
> video->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
> - video->queue.dev = video->vsp1->dev;
> + video->queue.dev = video->vsp1->bus_master;
> ret = vb2_queue_init(&video->queue);
> if (ret < 0) {
> dev_err(video->vsp1->dev, "failed to initialize vb2 queue\n");
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 4/5] v4l: vsp1: Add API to map and unmap DRM buffers through the VSP
2017-05-16 23:20 [PATCH v2 0/5] R-Car DU: Fix IOMMU operation when connected to VSP Laurent Pinchart
` (2 preceding siblings ...)
2017-05-16 23:20 ` [PATCH v2 3/5] v4l: vsp1: Map the DL and video buffers through the proper bus master Laurent Pinchart
@ 2017-05-16 23:20 ` Laurent Pinchart
2017-05-22 11:52 ` Kieran Bingham
2017-05-16 23:20 ` [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device Laurent Pinchart
4 siblings, 1 reply; 18+ messages in thread
From: Laurent Pinchart @ 2017-05-16 23:20 UTC (permalink / raw)
To: dri-devel; +Cc: linux-renesas-soc
The display buffers must be mapped for DMA through the device that
performs memory access. Expose an API to map and unmap memory through
the VSP device to be used by the DU.
As all the buffers allocated by the DU driver are coherent, we can skip
cache handling when mapping and unmapping them. This will need to be
revisited when support for non-coherent buffers will be added to the DU
driver.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/media/platform/vsp1/vsp1_drm.c | 25 +++++++++++++++++++++++++
include/media/vsp1.h | 3 +++
2 files changed, 28 insertions(+)
diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
index 9d235e830f5a..c809c2aadca0 100644
--- a/drivers/media/platform/vsp1/vsp1_drm.c
+++ b/drivers/media/platform/vsp1/vsp1_drm.c
@@ -12,9 +12,11 @@
*/
#include <linux/device.h>
+#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <media/media-entity.h>
+#include <media/rcar-fcp.h>
#include <media/v4l2-subdev.h>
#include <media/vsp1.h>
@@ -524,6 +526,29 @@ void vsp1_du_atomic_flush(struct device *dev)
}
EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
+int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt)
+{
+ struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+
+ /*
+ * As all the buffers allocated by the DU driver are coherent, we can
+ * skip cache sync. This will need to be revisited when support for
+ * non-coherent buffers will be added to the DU driver.
+ */
+ return dma_map_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents,
+ DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
+}
+EXPORT_SYMBOL_GPL(vsp1_du_map_sg);
+
+void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt)
+{
+ struct vsp1_device *vsp1 = dev_get_drvdata(dev);
+
+ dma_unmap_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents,
+ DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
+}
+EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg);
+
/* -----------------------------------------------------------------------------
* Initialization
*/
diff --git a/include/media/vsp1.h b/include/media/vsp1.h
index 38aac554dbba..6aa630c9f7af 100644
--- a/include/media/vsp1.h
+++ b/include/media/vsp1.h
@@ -13,6 +13,7 @@
#ifndef __MEDIA_VSP1_H__
#define __MEDIA_VSP1_H__
+#include <linux/scatterlist.h>
#include <linux/types.h>
#include <linux/videodev2.h>
@@ -46,5 +47,7 @@ void vsp1_du_atomic_begin(struct device *dev);
int vsp1_du_atomic_update(struct device *dev, unsigned int rpf,
const struct vsp1_du_atomic_config *cfg);
void vsp1_du_atomic_flush(struct device *dev);
+int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
+void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
#endif /* __MEDIA_VSP1_H__ */
--
Regards,
Laurent Pinchart
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 4/5] v4l: vsp1: Add API to map and unmap DRM buffers through the VSP
2017-05-16 23:20 ` [PATCH v2 4/5] v4l: vsp1: Add API to map and unmap DRM buffers through the VSP Laurent Pinchart
@ 2017-05-22 11:52 ` Kieran Bingham
0 siblings, 0 replies; 18+ messages in thread
From: Kieran Bingham @ 2017-05-22 11:52 UTC (permalink / raw)
To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc
Hi Laurent,
On 17/05/17 00:20, Laurent Pinchart wrote:
> The display buffers must be mapped for DMA through the device that
> performs memory access. Expose an API to map and unmap memory through
> the VSP device to be used by the DU.
>
> As all the buffers allocated by the DU driver are coherent, we can skip
> cache handling when mapping and unmapping them. This will need to be
> revisited when support for non-coherent buffers will be added to the DU
> driver.
Thankyou for the patch
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
With the small nitpick fixed:
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
> drivers/media/platform/vsp1/vsp1_drm.c | 25 +++++++++++++++++++++++++
> include/media/vsp1.h | 3 +++
> 2 files changed, 28 insertions(+)
>
> diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c
> index 9d235e830f5a..c809c2aadca0 100644
> --- a/drivers/media/platform/vsp1/vsp1_drm.c
> +++ b/drivers/media/platform/vsp1/vsp1_drm.c
> @@ -12,9 +12,11 @@
> */
>
> #include <linux/device.h>
> +#include <linux/dma-mapping.h>
> #include <linux/slab.h>
>
> #include <media/media-entity.h>
> +#include <media/rcar-fcp.h>
This header isn't used here.
(Presumably it was before you cached the fcp dev as the vsp1->bus_master).
I'll fix this while applying locally. No need to resend.
> #include <media/v4l2-subdev.h>
> #include <media/vsp1.h>
>
> @@ -524,6 +526,29 @@ void vsp1_du_atomic_flush(struct device *dev)
> }
> EXPORT_SYMBOL_GPL(vsp1_du_atomic_flush);
>
> +int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt)
> +{
> + struct vsp1_device *vsp1 = dev_get_drvdata(dev);
> +
> + /*
> + * As all the buffers allocated by the DU driver are coherent, we can
> + * skip cache sync. This will need to be revisited when support for
> + * non-coherent buffers will be added to the DU driver.
> + */
> + return dma_map_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents,
> + DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
> +}
> +EXPORT_SYMBOL_GPL(vsp1_du_map_sg);
> +
> +void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt)
> +{
> + struct vsp1_device *vsp1 = dev_get_drvdata(dev);
> +
> + dma_unmap_sg_attrs(vsp1->bus_master, sgt->sgl, sgt->nents,
> + DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
> +}
> +EXPORT_SYMBOL_GPL(vsp1_du_unmap_sg);
> +
> /* -----------------------------------------------------------------------------
> * Initialization
> */
> diff --git a/include/media/vsp1.h b/include/media/vsp1.h
> index 38aac554dbba..6aa630c9f7af 100644
> --- a/include/media/vsp1.h
> +++ b/include/media/vsp1.h
> @@ -13,6 +13,7 @@
> #ifndef __MEDIA_VSP1_H__
> #define __MEDIA_VSP1_H__
>
> +#include <linux/scatterlist.h>
> #include <linux/types.h>
> #include <linux/videodev2.h>
>
> @@ -46,5 +47,7 @@ void vsp1_du_atomic_begin(struct device *dev);
> int vsp1_du_atomic_update(struct device *dev, unsigned int rpf,
> const struct vsp1_du_atomic_config *cfg);
> void vsp1_du_atomic_flush(struct device *dev);
> +int vsp1_du_map_sg(struct device *dev, struct sg_table *sgt);
> +void vsp1_du_unmap_sg(struct device *dev, struct sg_table *sgt);
>
> #endif /* __MEDIA_VSP1_H__ */
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device
2017-05-16 23:20 [PATCH v2 0/5] R-Car DU: Fix IOMMU operation when connected to VSP Laurent Pinchart
` (3 preceding siblings ...)
2017-05-16 23:20 ` [PATCH v2 4/5] v4l: vsp1: Add API to map and unmap DRM buffers through the VSP Laurent Pinchart
@ 2017-05-16 23:20 ` Laurent Pinchart
2017-05-22 12:15 ` Kieran Bingham
2017-05-22 12:16 ` Kieran Bingham
4 siblings, 2 replies; 18+ messages in thread
From: Laurent Pinchart @ 2017-05-16 23:20 UTC (permalink / raw)
To: dri-devel; +Cc: linux-renesas-soc
For planes handled by a VSP instance, map the framebuffer memory through
the VSP to ensure proper IOMMU handling.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
---
drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 74 ++++++++++++++++++++++++++++++++---
drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +
2 files changed, 70 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
index b0ff304ce3dc..1b874cfd40f3 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
@@ -19,7 +19,9 @@
#include <drm/drm_gem_cma_helper.h>
#include <drm/drm_plane_helper.h>
+#include <linux/dma-mapping.h>
#include <linux/of_platform.h>
+#include <linux/scatterlist.h>
#include <linux/videodev2.h>
#include <media/vsp1.h>
@@ -170,12 +172,9 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
cfg.dst.width = state->state.crtc_w;
cfg.dst.height = state->state.crtc_h;
- for (i = 0; i < state->format->planes; ++i) {
- struct drm_gem_cma_object *gem;
-
- gem = drm_fb_cma_get_gem_obj(fb, i);
- cfg.mem[i] = gem->paddr + fb->offsets[i];
- }
+ for (i = 0; i < state->format->planes; ++i)
+ cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
+ + fb->offsets[i];
for (i = 0; i < ARRAY_SIZE(formats_kms); ++i) {
if (formats_kms[i] == state->format->fourcc) {
@@ -187,6 +186,67 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
}
+static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
+ struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
+ struct rcar_du_device *rcdu = vsp->dev;
+ unsigned int i;
+ int ret;
+
+ if (!state->fb)
+ return 0;
+
+ for (i = 0; i < rstate->format->planes; ++i) {
+ struct drm_gem_cma_object *gem =
+ drm_fb_cma_get_gem_obj(state->fb, i);
+ struct sg_table *sgt = &rstate->sg_tables[i];
+
+ ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr,
+ gem->base.size);
+ if (ret)
+ goto fail;
+
+ ret = vsp1_du_map_sg(vsp->vsp, sgt);
+ if (!ret) {
+ sg_free_table(sgt);
+ ret = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ return 0;
+
+fail:
+ for (i--; i >= 0; i--) {
+ struct sg_table *sgt = &rstate->sg_tables[i];
+
+ vsp1_du_unmap_sg(vsp->vsp, sgt);
+ sg_free_table(sgt);
+ }
+
+ return ret;
+}
+
+static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
+ struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
+ unsigned int i;
+
+ if (!state->fb)
+ return;
+
+ for (i = 0; i < rstate->format->planes; ++i) {
+ struct sg_table *sgt = &rstate->sg_tables[i];
+
+ vsp1_du_unmap_sg(vsp->vsp, sgt);
+ sg_free_table(sgt);
+ }
+}
+
static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
@@ -227,6 +287,8 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
}
static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
+ .prepare_fb = rcar_du_vsp_plane_prepare_fb,
+ .cleanup_fb = rcar_du_vsp_plane_cleanup_fb,
.atomic_check = rcar_du_vsp_plane_atomic_check,
.atomic_update = rcar_du_vsp_plane_atomic_update,
};
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
index f1d0f1824528..8861661590ff 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
+++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
@@ -43,6 +43,7 @@ static inline struct rcar_du_vsp_plane *to_rcar_vsp_plane(struct drm_plane *p)
* struct rcar_du_vsp_plane_state - Driver-specific plane state
* @state: base DRM plane state
* @format: information about the pixel format used by the plane
+ * @sg_tables: scatter-gather tables for the frame buffer memory
* @alpha: value of the plane alpha property
* @zpos: value of the plane zpos property
*/
@@ -50,6 +51,7 @@ struct rcar_du_vsp_plane_state {
struct drm_plane_state state;
const struct rcar_du_format_info *format;
+ struct sg_table sg_tables[3];
unsigned int alpha;
unsigned int zpos;
--
Regards,
Laurent Pinchart
^ permalink raw reply related [flat|nested] 18+ messages in thread* Re: [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device
2017-05-16 23:20 ` [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device Laurent Pinchart
@ 2017-05-22 12:15 ` Kieran Bingham
2017-05-22 12:16 ` Kieran Bingham
1 sibling, 0 replies; 18+ messages in thread
From: Kieran Bingham @ 2017-05-22 12:15 UTC (permalink / raw)
To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc
Hi Laurent,
Thankyou for the patch.
On 17/05/17 00:20, Laurent Pinchart wrote:
> For planes handled by a VSP instance, map the framebuffer memory through
> the VSP to ensure proper IOMMU handling.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Looks good except for a small unsigned int comparison causing an infinite loop
on fail case.
With the loop fixed:
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
> drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 74 ++++++++++++++++++++++++++++++++---
> drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +
> 2 files changed, 70 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index b0ff304ce3dc..1b874cfd40f3 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -19,7 +19,9 @@
> #include <drm/drm_gem_cma_helper.h>
> #include <drm/drm_plane_helper.h>
>
> +#include <linux/dma-mapping.h>
> #include <linux/of_platform.h>
> +#include <linux/scatterlist.h>
> #include <linux/videodev2.h>
>
> #include <media/vsp1.h>
> @@ -170,12 +172,9 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
> cfg.dst.width = state->state.crtc_w;
> cfg.dst.height = state->state.crtc_h;
>
> - for (i = 0; i < state->format->planes; ++i) {
> - struct drm_gem_cma_object *gem;
> -
> - gem = drm_fb_cma_get_gem_obj(fb, i);
> - cfg.mem[i] = gem->paddr + fb->offsets[i];
> - }
> + for (i = 0; i < state->format->planes; ++i)
> + cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
> + + fb->offsets[i];
>
> for (i = 0; i < ARRAY_SIZE(formats_kms); ++i) {
> if (formats_kms[i] == state->format->fourcc) {
> @@ -187,6 +186,67 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
> vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
> }
>
> +static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
> + struct drm_plane_state *state)
> +{
> + struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
> + struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
> + struct rcar_du_device *rcdu = vsp->dev;
> + unsigned int i;
Unsigned here..
> + int ret;
> +
> + if (!state->fb)
> + return 0;
> +
> + for (i = 0; i < rstate->format->planes; ++i) {
> + struct drm_gem_cma_object *gem =
> + drm_fb_cma_get_gem_obj(state->fb, i);
> + struct sg_table *sgt = &rstate->sg_tables[i];
> +
> + ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr,
> + gem->base.size);
> + if (ret)
> + goto fail;
> +
> + ret = vsp1_du_map_sg(vsp->vsp, sgt);
> + if (!ret) {
> + sg_free_table(sgt);
> + ret = -ENOMEM;
> + goto fail;
> + }
> + }
> +
> + return 0;
> +
> +fail:
> + for (i--; i >= 0; i--) {
Means that this loop will never exit; i will always be >= 0;
I'd propose just making signed for this usage.
I've checked the i values for the breakouts - so they are good, and we need to
use i == 0 to unmap the last table.
> + struct sg_table *sgt = &rstate->sg_tables[i];
> +
> + vsp1_du_unmap_sg(vsp->vsp, sgt);
> + sg_free_table(sgt);
> + }
> +
> + return ret;
> +}
> +
> +static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
> + struct drm_plane_state *state)
> +{
> + struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
> + struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
> + unsigned int i;
> +
> + if (!state->fb)
> + return;
> +
> + for (i = 0; i < rstate->format->planes; ++i) {
> + struct sg_table *sgt = &rstate->sg_tables[i];
> +
> + vsp1_du_unmap_sg(vsp->vsp, sgt);
> + sg_free_table(sgt);
> + }
> +}
> +
> static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
> struct drm_plane_state *state)
> {
> @@ -227,6 +287,8 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
> }
>
> static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
> + .prepare_fb = rcar_du_vsp_plane_prepare_fb,
> + .cleanup_fb = rcar_du_vsp_plane_cleanup_fb,
> .atomic_check = rcar_du_vsp_plane_atomic_check,
> .atomic_update = rcar_du_vsp_plane_atomic_update,
> };
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> index f1d0f1824528..8861661590ff 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> @@ -43,6 +43,7 @@ static inline struct rcar_du_vsp_plane *to_rcar_vsp_plane(struct drm_plane *p)
> * struct rcar_du_vsp_plane_state - Driver-specific plane state
> * @state: base DRM plane state
> * @format: information about the pixel format used by the plane
> + * @sg_tables: scatter-gather tables for the frame buffer memory
> * @alpha: value of the plane alpha property
> * @zpos: value of the plane zpos property
> */
> @@ -50,6 +51,7 @@ struct rcar_du_vsp_plane_state {
> struct drm_plane_state state;
>
> const struct rcar_du_format_info *format;
> + struct sg_table sg_tables[3];
>
> unsigned int alpha;
> unsigned int zpos;
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device
2017-05-16 23:20 ` [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device Laurent Pinchart
2017-05-22 12:15 ` Kieran Bingham
@ 2017-05-22 12:16 ` Kieran Bingham
2017-05-22 12:24 ` Laurent Pinchart
1 sibling, 1 reply; 18+ messages in thread
From: Kieran Bingham @ 2017-05-22 12:16 UTC (permalink / raw)
To: Laurent Pinchart, dri-devel; +Cc: linux-renesas-soc
Hi Laurent,
Thankyou for the patch.
On 17/05/17 00:20, Laurent Pinchart wrote:
> For planes handled by a VSP instance, map the framebuffer memory through
> the VSP to ensure proper IOMMU handling.
>
> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Looks good except for a small unsigned int comparison causing an infinite loop
on fail case.
With the loop fixed:
Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
> ---
> drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 74 ++++++++++++++++++++++++++++++++---
> drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +
> 2 files changed, 70 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> index b0ff304ce3dc..1b874cfd40f3 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> @@ -19,7 +19,9 @@
> #include <drm/drm_gem_cma_helper.h>
> #include <drm/drm_plane_helper.h>
>
> +#include <linux/dma-mapping.h>
> #include <linux/of_platform.h>
> +#include <linux/scatterlist.h>
> #include <linux/videodev2.h>
>
> #include <media/vsp1.h>
> @@ -170,12 +172,9 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
> cfg.dst.width = state->state.crtc_w;
> cfg.dst.height = state->state.crtc_h;
>
> - for (i = 0; i < state->format->planes; ++i) {
> - struct drm_gem_cma_object *gem;
> -
> - gem = drm_fb_cma_get_gem_obj(fb, i);
> - cfg.mem[i] = gem->paddr + fb->offsets[i];
> - }
> + for (i = 0; i < state->format->planes; ++i)
> + cfg.mem[i] = sg_dma_address(state->sg_tables[i].sgl)
> + + fb->offsets[i];
>
> for (i = 0; i < ARRAY_SIZE(formats_kms); ++i) {
> if (formats_kms[i] == state->format->fourcc) {
> @@ -187,6 +186,67 @@ static void rcar_du_vsp_plane_setup(struct rcar_du_vsp_plane *plane)
> vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
> }
>
> +static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
> + struct drm_plane_state *state)
> +{
> + struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
> + struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
> + struct rcar_du_device *rcdu = vsp->dev;
> + unsigned int i;
Unsigned here..
> + int ret;
> +
> + if (!state->fb)
> + return 0;
> +
> + for (i = 0; i < rstate->format->planes; ++i) {
> + struct drm_gem_cma_object *gem =
> + drm_fb_cma_get_gem_obj(state->fb, i);
> + struct sg_table *sgt = &rstate->sg_tables[i];
> +
> + ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr,
> + gem->base.size);
> + if (ret)
> + goto fail;
> +
> + ret = vsp1_du_map_sg(vsp->vsp, sgt);
> + if (!ret) {
> + sg_free_table(sgt);
> + ret = -ENOMEM;
> + goto fail;
> + }
> + }
> +
> + return 0;
> +
> +fail:
> + for (i--; i >= 0; i--) {
Means that this loop will never exit; i will always be >= 0;
I'd propose just making signed for this usage.
I've checked the i values for the breakouts - so they are good, and we need to
use i == 0 to unmap the last table.
> + struct sg_table *sgt = &rstate->sg_tables[i];
> +
> + vsp1_du_unmap_sg(vsp->vsp, sgt);
> + sg_free_table(sgt);
> + }
> +
> + return ret;
> +}
> +
> +static void rcar_du_vsp_plane_cleanup_fb(struct drm_plane *plane,
> + struct drm_plane_state *state)
> +{
> + struct rcar_du_vsp_plane_state *rstate = to_rcar_vsp_plane_state(state);
> + struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
> + unsigned int i;
> +
> + if (!state->fb)
> + return;
> +
> + for (i = 0; i < rstate->format->planes; ++i) {
> + struct sg_table *sgt = &rstate->sg_tables[i];
> +
> + vsp1_du_unmap_sg(vsp->vsp, sgt);
> + sg_free_table(sgt);
> + }
> +}
> +
> static int rcar_du_vsp_plane_atomic_check(struct drm_plane *plane,
> struct drm_plane_state *state)
> {
> @@ -227,6 +287,8 @@ static void rcar_du_vsp_plane_atomic_update(struct drm_plane *plane,
> }
>
> static const struct drm_plane_helper_funcs rcar_du_vsp_plane_helper_funcs = {
> + .prepare_fb = rcar_du_vsp_plane_prepare_fb,
> + .cleanup_fb = rcar_du_vsp_plane_cleanup_fb,
> .atomic_check = rcar_du_vsp_plane_atomic_check,
> .atomic_update = rcar_du_vsp_plane_atomic_update,
> };
> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> index f1d0f1824528..8861661590ff 100644
> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.h
> @@ -43,6 +43,7 @@ static inline struct rcar_du_vsp_plane *to_rcar_vsp_plane(struct drm_plane *p)
> * struct rcar_du_vsp_plane_state - Driver-specific plane state
> * @state: base DRM plane state
> * @format: information about the pixel format used by the plane
> + * @sg_tables: scatter-gather tables for the frame buffer memory
> * @alpha: value of the plane alpha property
> * @zpos: value of the plane zpos property
> */
> @@ -50,6 +51,7 @@ struct rcar_du_vsp_plane_state {
> struct drm_plane_state state;
>
> const struct rcar_du_format_info *format;
> + struct sg_table sg_tables[3];
>
> unsigned int alpha;
> unsigned int zpos;
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device
2017-05-22 12:16 ` Kieran Bingham
@ 2017-05-22 12:24 ` Laurent Pinchart
2017-05-22 12:52 ` Kieran Bingham
0 siblings, 1 reply; 18+ messages in thread
From: Laurent Pinchart @ 2017-05-22 12:24 UTC (permalink / raw)
To: kieran.bingham; +Cc: Laurent Pinchart, dri-devel, linux-renesas-soc
Hi Kieran,
On Monday 22 May 2017 13:16:11 Kieran Bingham wrote:
> On 17/05/17 00:20, Laurent Pinchart wrote:
> > For planes handled by a VSP instance, map the framebuffer memory through
> > the VSP to ensure proper IOMMU handling.
> >
> > Signed-off-by: Laurent Pinchart
> > <laurent.pinchart+renesas@ideasonboard.com>
>
> Looks good except for a small unsigned int comparison causing an infinite
> loop on fail case.
>
> With the loop fixed:
>
> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>
> > ---
> >
> > drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 74 +++++++++++++++++++++++++++---
> > drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +
> > 2 files changed, 70 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> > b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index b0ff304ce3dc..1b874cfd40f3
> > 100644
> > --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
> > +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
[snip]
> > @@ -187,6 +186,67 @@ static void rcar_du_vsp_plane_setup(struct
> > rcar_du_vsp_plane *plane)
> > vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
> > }
> >
> > +static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
> > + struct drm_plane_state *state)
> > +{
> > + struct rcar_du_vsp_plane_state *rstate =
to_rcar_vsp_plane_state(state);
> > + struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
> > + struct rcar_du_device *rcdu = vsp->dev;
> > + unsigned int i;
>
> Unsigned here..
>
> > + int ret;
> > +
> > + if (!state->fb)
> > + return 0;
> > +
> > + for (i = 0; i < rstate->format->planes; ++i) {
> > + struct drm_gem_cma_object *gem =
> > + drm_fb_cma_get_gem_obj(state->fb, i);
> > + struct sg_table *sgt = &rstate->sg_tables[i];
> > +
> > + ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr,
> > + gem->base.size);
> > + if (ret)
> > + goto fail;
> > +
> > + ret = vsp1_du_map_sg(vsp->vsp, sgt);
> > + if (!ret) {
> > + sg_free_table(sgt);
> > + ret = -ENOMEM;
> > + goto fail;
> > + }
> > + }
> > +
> > + return 0;
> > +
> > +fail:
> > + for (i--; i >= 0; i--) {
>
> Means that this loop will never exit; i will always be >= 0;
>
> I'd propose just making signed for this usage.
>
> I've checked the i values for the breakouts - so they are good, and we need
> to use i == 0 to unmap the last table.
>
> > + struct sg_table *sgt = &rstate->sg_tables[i];
How about keep i unsigned and using
for (; i > 0; i--) {
struct sg_table *sgt = &rstate->sg_tables[i-1];
...
}
If you want to fix while applying, you can pick your favourite version.
> > +
> > + vsp1_du_unmap_sg(vsp->vsp, sgt);
> > + sg_free_table(sgt);
> > + }
> > +
> > + return ret;
> > +}
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device
2017-05-22 12:24 ` Laurent Pinchart
@ 2017-05-22 12:52 ` Kieran Bingham
2017-05-22 13:00 ` Geert Uytterhoeven
0 siblings, 1 reply; 18+ messages in thread
From: Kieran Bingham @ 2017-05-22 12:52 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: Laurent Pinchart, dri-devel, linux-renesas-soc
Hi Laurent,
On 22/05/17 13:24, Laurent Pinchart wrote:
> Hi Kieran,
>
> On Monday 22 May 2017 13:16:11 Kieran Bingham wrote:
>> On 17/05/17 00:20, Laurent Pinchart wrote:
>>> For planes handled by a VSP instance, map the framebuffer memory through
>>> the VSP to ensure proper IOMMU handling.
>>>
>>> Signed-off-by: Laurent Pinchart
>>> <laurent.pinchart+renesas@ideasonboard.com>
>>
>> Looks good except for a small unsigned int comparison causing an infinite
>> loop on fail case.
>>
>> With the loop fixed:
>>
>> Reviewed-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>
>>
>>> ---
>>>
>>> drivers/gpu/drm/rcar-du/rcar_du_vsp.c | 74 +++++++++++++++++++++++++++---
>>> drivers/gpu/drm/rcar-du/rcar_du_vsp.h | 2 +
>>> 2 files changed, 70 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>> b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c index b0ff304ce3dc..1b874cfd40f3
>>> 100644
>>> --- a/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>>> +++ b/drivers/gpu/drm/rcar-du/rcar_du_vsp.c
>
> [snip]
>
>
>>> @@ -187,6 +186,67 @@ static void rcar_du_vsp_plane_setup(struct
>>> rcar_du_vsp_plane *plane)
>>> vsp1_du_atomic_update(plane->vsp->vsp, plane->index, &cfg);
>>> }
>>>
>>> +static int rcar_du_vsp_plane_prepare_fb(struct drm_plane *plane,
>>> + struct drm_plane_state *state)
>>> +{
>>> + struct rcar_du_vsp_plane_state *rstate =
> to_rcar_vsp_plane_state(state);
>>> + struct rcar_du_vsp *vsp = to_rcar_vsp_plane(plane)->vsp;
>>> + struct rcar_du_device *rcdu = vsp->dev;
>>> + unsigned int i;
>>
>> Unsigned here..
>>
>>> + int ret;
>>> +
>>> + if (!state->fb)
>>> + return 0;
>>> +
>>> + for (i = 0; i < rstate->format->planes; ++i) {
>>> + struct drm_gem_cma_object *gem =
>>> + drm_fb_cma_get_gem_obj(state->fb, i);
>>> + struct sg_table *sgt = &rstate->sg_tables[i];
>>> +
>>> + ret = dma_get_sgtable(rcdu->dev, sgt, gem->vaddr, gem->paddr,
>>> + gem->base.size);
>>> + if (ret)
>>> + goto fail;
>>> +
>>> + ret = vsp1_du_map_sg(vsp->vsp, sgt);
>>> + if (!ret) {
>>> + sg_free_table(sgt);
>>> + ret = -ENOMEM;
>>> + goto fail;
>>> + }
>>> + }
>>> +
>>> + return 0;
>>> +
>>> +fail:
>>> + for (i--; i >= 0; i--) {
>>
>> Means that this loop will never exit; i will always be >= 0;
>>
>> I'd propose just making signed for this usage.
>>
>> I've checked the i values for the breakouts - so they are good, and we need
>> to use i == 0 to unmap the last table.
>>
>>> + struct sg_table *sgt = &rstate->sg_tables[i];
>
> How about keep i unsigned and using
>
> for (; i > 0; i--) {
> struct sg_table *sgt = &rstate->sg_tables[i-1];
> ...
> }
My only distaste there is having to then add the [i-1] index to the sg_tables.
I have just experimented with:
fail:
for (; i-- != 0;) {
struct sg_table *sgt = &rstate->sg_tables[i];
...
}
This performs the correct loops, with the correct indexes, but does the
decrement in the condition offend coding styles ?
If that's disliked even more I'll just apply your suggestion.
--
Kieran
>
> If you want to fix while applying, you can pick your favourite version.
>
>>> +
>>> + vsp1_du_unmap_sg(vsp->vsp, sgt);
>>> + sg_free_table(sgt);
>>> + }
>>> +
>>> + return ret;
>>> +}
>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device
2017-05-22 12:52 ` Kieran Bingham
@ 2017-05-22 13:00 ` Geert Uytterhoeven
2017-05-22 13:23 ` Laurent Pinchart
0 siblings, 1 reply; 18+ messages in thread
From: Geert Uytterhoeven @ 2017-05-22 13:00 UTC (permalink / raw)
To: Kieran Bingham
Cc: Laurent Pinchart, Laurent Pinchart, DRI Development,
Linux-Renesas
On Mon, May 22, 2017 at 2:52 PM, Kieran Bingham
<kieran.bingham@ideasonboard.com> wrote:
> My only distaste there is having to then add the [i-1] index to the sg_tables.
>
> I have just experimented with:
>
> fail:
> for (; i-- != 0;) {
> struct sg_table *sgt = &rstate->sg_tables[i];
> ...
> }
>
> This performs the correct loops, with the correct indexes, but does the
> decrement in the condition offend coding styles ?
>
> If that's disliked even more I'll just apply your suggestion.
You can still use "i-- > 0", which looks a little bit better IMHO.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device
2017-05-22 13:00 ` Geert Uytterhoeven
@ 2017-05-22 13:23 ` Laurent Pinchart
2017-05-22 13:40 ` Kieran Bingham
0 siblings, 1 reply; 18+ messages in thread
From: Laurent Pinchart @ 2017-05-22 13:23 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Kieran Bingham, Laurent Pinchart, DRI Development, Linux-Renesas
Hello Geert and Kieran,
On Monday 22 May 2017 15:00:27 Geert Uytterhoeven wrote:
> On Mon, May 22, 2017 at 2:52 PM, Kieran Bingham wrote:
> > My only distaste there is having to then add the [i-1] index to the
> > sg_tables.
> >
> > I have just experimented with:
> >
> > fail:
> > for (; i-- != 0;) {
> > struct sg_table *sgt = &rstate->sg_tables[i];
> > ...
> > }
> >
> > This performs the correct loops, with the correct indexes, but does the
> > decrement in the condition offend coding styles ?
> >
> > If that's disliked even more I'll just apply your suggestion.
>
> You can still use "i-- > 0", which looks a little bit better IMHO.
I'm fine with that option too.
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH v2 5/5] drm: rcar-du: Map memory through the VSP device
2017-05-22 13:23 ` Laurent Pinchart
@ 2017-05-22 13:40 ` Kieran Bingham
0 siblings, 0 replies; 18+ messages in thread
From: Kieran Bingham @ 2017-05-22 13:40 UTC (permalink / raw)
To: Laurent Pinchart, Geert Uytterhoeven
Cc: Laurent Pinchart, DRI Development, Linux-Renesas
On 22/05/17 14:23, Laurent Pinchart wrote:
> Hello Geert and Kieran,
>
> On Monday 22 May 2017 15:00:27 Geert Uytterhoeven wrote:
>> On Mon, May 22, 2017 at 2:52 PM, Kieran Bingham wrote:
>>> My only distaste there is having to then add the [i-1] index to the
>>> sg_tables.
>>>
>>> I have just experimented with:
>>>
>>> fail:
>>> for (; i-- != 0;) {
>>> struct sg_table *sgt = &rstate->sg_tables[i];
>>> ...
>>> }
>>>
>>> This performs the correct loops, with the correct indexes, but does the
>>> decrement in the condition offend coding styles ?
>>>
>>> If that's disliked even more I'll just apply your suggestion.
>>
>> You can still use "i-- > 0", which looks a little bit better IMHO.
>
> I'm fine with that option too.
>
Of course for(; X ;) is just while(X), which is also more readable ;)
And while (i-- > 0) simplifies cleanly to while (i--) which I'm sure is quite
readable.
I'll clean up and post the updated series including linux-media.
--
Kieran
^ permalink raw reply [flat|nested] 18+ messages in thread