[PATCH] drm/etnaviv: add DMA configuration and of_node to etnaviv platform device

Lucas Stach l.stach at pengutronix.de
Wed Sep 12 15:48:20 UTC 2018


The etnaviv device is a virtual device backing the DRM device, which may
drive multiple hardware GPU core devies. As most of the dma-mapping handling
is done through the virtual device, we need to make sure that a proper DMA
setup is in place. The easiest way to get a reasonable configuration is
to let the virtual device share the device node with one of the GPU devices,
so of_dma_configure() can do the right thing when probing the device.

This assumes that all etnaviv driven GPU devices in the system share the
same DMA configuration. If we ever encounter a SoC where the GPUs are on
busses with different offsets or behind different IOMMUs that will require
much deeper changes to the driver, as we would need to implement etnaviv
specific versions of most of the DRM helper functions.

For now we should be fine with this solution.

Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
 drivers/gpu/drm/etnaviv/etnaviv_drv.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 9b2720b41571..0878a7497740 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -592,8 +592,6 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct component_match *match = NULL;
 
-	dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
-
 	if (!dev->platform_data) {
 		struct device_node *core_node;
 
@@ -655,13 +653,26 @@ static int __init etnaviv_init(void)
 	for_each_compatible_node(np, NULL, "vivante,gc") {
 		if (!of_device_is_available(np))
 			continue;
-		pdev = platform_device_register_simple("etnaviv", -1,
-						       NULL, 0);
-		if (IS_ERR(pdev)) {
-			ret = PTR_ERR(pdev);
+
+		pdev = platform_device_alloc("etnaviv", -1);
+		if (!pdev) {
+			ret = -ENOMEM;
+			of_node_put(np);
+			goto unregister_platform_driver;
+		}
+		pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
+		pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+		pdev->dev.of_node = of_node_get(np);
+		pdev->dev.of_node_reused = true;
+
+		ret = platform_device_add(pdev);
+		if (ret) {
+			of_node_put(pdev->dev.of_node);
+			platform_device_put(pdev);
 			of_node_put(np);
 			goto unregister_platform_driver;
 		}
+
 		etnaviv_drm = pdev;
 		of_node_put(np);
 		break;
-- 
2.18.0



More information about the etnaviv mailing list