aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMagnus Damm <magnus.damm@gmail.com>2017-05-16 19:20:05 -0400
committerKieran Bingham <kieran.bingham+renesas@ideasonboard.com>2017-06-09 07:25:37 -0400
commit2cc2137ffbd191d4258cf49347578b510aa1085c (patch)
tree7e3aac8b96248b58a303be103999c1e162a85a4b
parent02533540ef8a54840a41843b8852755a543318e6 (diff)
v4l: vsp1: Map the DL and video buffers through the proper bus master
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> Signed-off-by: Kieran Bingham <kieran.bingham+renesas@ideasonboard.com> Acked-by: Mauro Cavalho Chehab <mchehab@s-opensource.com>
-rw-r--r--drivers/media/platform/vsp1/vsp1.h1
-rw-r--r--drivers/media/platform/vsp1/vsp1_dl.c4
-rw-r--r--drivers/media/platform/vsp1/vsp1_drv.c9
-rw-r--r--drivers/media/platform/vsp1/vsp1_video.c2
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 {
74 74
75 void __iomem *mmio; 75 void __iomem *mmio;
76 struct rcar_fcp_device *fcp; 76 struct rcar_fcp_device *fcp;
77 struct device *bus_master;
77 78
78 struct vsp1_bru *bru; 79 struct vsp1_bru *bru;
79 struct vsp1_clu *clu; 80 struct vsp1_clu *clu;
diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c
index 85fe2b4ae310..aaf17b13fd78 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,
137 dlb->vsp1 = vsp1; 137 dlb->vsp1 = vsp1;
138 dlb->size = size; 138 dlb->size = size;
139 139
140 dlb->entries = dma_alloc_wc(vsp1->dev, dlb->size, &dlb->dma, 140 dlb->entries = dma_alloc_wc(vsp1->bus_master, dlb->size, &dlb->dma,
141 GFP_KERNEL); 141 GFP_KERNEL);
142 if (!dlb->entries) 142 if (!dlb->entries)
143 return -ENOMEM; 143 return -ENOMEM;
@@ -150,7 +150,7 @@ static int vsp1_dl_body_init(struct vsp1_device *vsp1,
150 */ 150 */
151static void vsp1_dl_body_cleanup(struct vsp1_dl_body *dlb) 151static void vsp1_dl_body_cleanup(struct vsp1_dl_body *dlb)
152{ 152{
153 dma_free_wc(dlb->vsp1->dev, dlb->size, dlb->entries, dlb->dma); 153 dma_free_wc(dlb->vsp1->bus_master, dlb->size, dlb->entries, dlb->dma);
154} 154}
155 155
156/** 156/**
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)
764 PTR_ERR(vsp1->fcp)); 764 PTR_ERR(vsp1->fcp));
765 return PTR_ERR(vsp1->fcp); 765 return PTR_ERR(vsp1->fcp);
766 } 766 }
767
768 /*
769 * When the FCP is present, it handles all bus master accesses
770 * for the VSP and must thus be used in place of the VSP device
771 * to map DMA buffers.
772 */
773 vsp1->bus_master = rcar_fcp_get_device(vsp1->fcp);
774 } else {
775 vsp1->bus_master = vsp1->dev;
767 } 776 }
768 777
769 /* Configure device parameters based on the version register. */ 778 /* 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,
1197 video->queue.ops = &vsp1_video_queue_qops; 1197 video->queue.ops = &vsp1_video_queue_qops;
1198 video->queue.mem_ops = &vb2_dma_contig_memops; 1198 video->queue.mem_ops = &vb2_dma_contig_memops;
1199 video->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; 1199 video->queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1200 video->queue.dev = video->vsp1->dev; 1200 video->queue.dev = video->vsp1->bus_master;
1201 ret = vb2_queue_init(&video->queue); 1201 ret = vb2_queue_init(&video->queue);
1202 if (ret < 0) { 1202 if (ret < 0) {
1203 dev_err(video->vsp1->dev, "failed to initialize vb2 queue\n"); 1203 dev_err(video->vsp1->dev, "failed to initialize vb2 queue\n");