summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/rcar-du
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2017-11-12 15:12:10 +0300
committerLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>2021-10-07 05:42:05 +0300
commit780d4223f662167fa0a58a98b09c20e3e173c0cc (patch)
tree47681c18e1e60c1af565ab540ee436baa63075d0 /drivers/gpu/drm/rcar-du
parent206c54710882d85b838f1899fd58adf8bad9454c (diff)
downloadlinux-780d4223f662167fa0a58a98b09c20e3e173c0cc.tar.xz
drm: rcar-du: Set the DMA coherent mask for the DU device
The DU DMA address space is limited to 32 bits, so the DMA coherent mask should be set accordingly. The DMA mapping implementation will transparently map high memory buffers to 32-bit addresses through an IOMMU when present (or through bounce buffers otherwise, which isn't a supported use case as performances would be terrible). However, when sourcing frames from a VSP, the situation is more complicated. The DU delegates all memory accesses to the VSP and doesn't perform any DMA access by itself. Due to how the GEM CMA helpers are structured buffers are still mapped to the DU device. They are later mapped to the VSP as well to perform DMA access, through the IOMMU connected to the VSP. Setting the DMA coherent mask to 32 bits for the DU when using a VSP can cause issues when importing a dma_buf. If the buffer is located above the 32-bit address space, the DMA mapping implementation will try to map it to the DU's DMA address space. As the DU has no IOMMU a bounce buffer will be allocated, which in the best case will waste memory and in the worst case will just fail. To work around this issue, set the DMA coherent mask to the full 40-bit address space for the DU. All dma-buf instances will be imported without any restriction, and will be mapped to the VSP when preparing the associated framebuffer. Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Diffstat (limited to 'drivers/gpu/drm/rcar-du')
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index d4dc101dc1d7..62dfd1b66db0 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -8,6 +8,7 @@
*/
#include <linux/clk.h>
+#include <linux/dma-mapping.h>
#include <linux/io.h>
#include <linux/mm.h>
#include <linux/module.h>
@@ -589,6 +590,7 @@ static int rcar_du_probe(struct platform_device *pdev)
{
struct rcar_du_device *rcdu;
struct resource *mem;
+ unsigned int mask;
int ret;
/* Allocate and initialize the R-Car device structure. */
@@ -608,6 +610,16 @@ static int rcar_du_probe(struct platform_device *pdev)
if (IS_ERR(rcdu->mmio))
return PTR_ERR(rcdu->mmio);
+ /*
+ * Set the DMA coherent mask to reflect the DU 32-bit DMA address space
+ * limitations. When sourcing frames from a VSP the DU doesn't perform
+ * any memory access so set the mask to 40 bits to accept all buffers.
+ */
+ mask = rcar_du_has(rcdu, RCAR_DU_FEATURE_VSP1_SOURCE) ? 40 : 32;
+ ret = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(mask));
+ if (ret)
+ return ret;
+
/* DRM/KMS objects */
ret = rcar_du_modeset_init(rcdu);
if (ret < 0) {