drm/rockchip: support non-iommu buffer path

Submitted by Mark yao on April 19, 2016, 2:19 a.m.

Details

Message ID 1461032372-14630-1-git-send-email-mark.yao@rock-chips.com
State New
Headers show
Series "drm/rockchip: support non-iommu buffer path" ( rev: 1 ) in DRI devel

Not browsing as part of any series.

Commit Message

Mark yao April 19, 2016, 2:19 a.m.
Some rockchip vop not support iommu, need use non-iommu
buffer for it. And if we get iommu issues, we can compare
the issues with non-iommu path, the would help the debug.

Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
---
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |   65 +++++++++++++++++++--------
 1 file changed, 47 insertions(+), 18 deletions(-)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index f556a8f..90729c0 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -36,6 +36,8 @@ 
 #define DRIVER_MAJOR	1
 #define DRIVER_MINOR	0
 
+static bool is_support_iommu = true;
+
 /*
  * Attach a (component) device to the shared drm dma mapping from master drm
  * device.  This is used by the VOPs to map GEM buffers to a common DMA
@@ -47,6 +49,9 @@  int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
 	struct dma_iommu_mapping *mapping = drm_dev->dev->archdata.mapping;
 	int ret;
 
+	if (!is_support_iommu)
+		return 0;
+
 	ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
 	if (ret)
 		return ret;
@@ -59,6 +64,9 @@  int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
 void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
 				    struct device *dev)
 {
+	if (!is_support_iommu)
+		return;
+
 	arm_iommu_detach_device(dev);
 }
 
@@ -152,23 +160,26 @@  static int rockchip_drm_load(struct drm_device *drm_dev, unsigned long flags)
 		goto err_config_cleanup;
 	}
 
-	/* TODO(djkurtz): fetch the mapping start/size from somewhere */
-	mapping = arm_iommu_create_mapping(&platform_bus_type, 0x00000000,
-					   SZ_2G);
-	if (IS_ERR(mapping)) {
-		ret = PTR_ERR(mapping);
-		goto err_config_cleanup;
-	}
+	if (is_support_iommu) {
+		/* TODO(djkurtz): fetch the mapping start/size from somewhere */
+		mapping = arm_iommu_create_mapping(&platform_bus_type,
+						   0x00000000,
+						   SZ_2G);
+		if (IS_ERR(mapping)) {
+			ret = PTR_ERR(mapping);
+			goto err_config_cleanup;
+		}
 
-	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
-	if (ret)
-		goto err_release_mapping;
+		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+		if (ret)
+			goto err_release_mapping;
 
-	dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
+		dma_set_max_seg_size(dev, DMA_BIT_MASK(32));
 
-	ret = arm_iommu_attach_device(dev, mapping);
-	if (ret)
-		goto err_release_mapping;
+		ret = arm_iommu_attach_device(dev, mapping);
+		if (ret)
+			goto err_release_mapping;
+	}
 
 	/* Try to bind all sub drivers. */
 	ret = component_bind_all(dev, drm_dev);
@@ -226,9 +237,11 @@  err_kms_helper_poll_fini:
 err_unbind:
 	component_unbind_all(dev, drm_dev);
 err_detach_device:
-	arm_iommu_detach_device(dev);
+	if (is_support_iommu)
+		arm_iommu_detach_device(dev);
 err_release_mapping:
-	arm_iommu_release_mapping(dev->archdata.mapping);
+	if (is_support_iommu)
+		arm_iommu_release_mapping(dev->archdata.mapping);
 err_config_cleanup:
 	drm_mode_config_cleanup(drm_dev);
 	drm_dev->dev_private = NULL;
@@ -243,8 +256,10 @@  static int rockchip_drm_unload(struct drm_device *drm_dev)
 	drm_vblank_cleanup(drm_dev);
 	drm_kms_helper_poll_fini(drm_dev);
 	component_unbind_all(dev, drm_dev);
-	arm_iommu_detach_device(dev);
-	arm_iommu_release_mapping(dev->archdata.mapping);
+	if (is_support_iommu) {
+		arm_iommu_detach_device(dev);
+		arm_iommu_release_mapping(dev->archdata.mapping);
+	}
 	drm_mode_config_cleanup(drm_dev);
 	drm_dev->dev_private = NULL;
 
@@ -488,6 +503,8 @@  static int rockchip_drm_platform_probe(struct platform_device *pdev)
 	 * works as expected.
 	 */
 	for (i = 0;; i++) {
+		struct device_node *iommu;
+
 		port = of_parse_phandle(np, "ports", i);
 		if (!port)
 			break;
@@ -497,6 +514,18 @@  static int rockchip_drm_platform_probe(struct platform_device *pdev)
 			continue;
 		}
 
+		iommu = of_parse_phandle(port->parent, "iommus", 0);
+		if (!iommu || !of_device_is_available(iommu->parent)) {
+			dev_warn(dev, "No available iommu found for %s\n",
+				 port->parent->full_name);
+			dev_warn(dev, "Force non-iommu buffer for all crtc\n");
+			/*
+			 * if there is a crtc not support iommu, force set all
+			 * crtc use non-iommu buffer.
+			 */
+			is_support_iommu = false;
+		}
+
 		component_match_add(dev, &match, compare_of, port->parent);
 		of_node_put(port);
 	}

Comments

Am Dienstag, 19. April 2016, 10:19:32 schrieb Mark Yao:
> Some rockchip vop not support iommu, need use non-iommu
> buffer for it. And if we get iommu issues, we can compare
> the issues with non-iommu path, the would help the debug.
> 
> Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
> ---
>  drivers/gpu/drm/rockchip/rockchip_drm_drv.c |   65
> +++++++++++++++++++-------- 1 file changed, 47 insertions(+), 18
> deletions(-)
> 
> diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index f556a8f..90729c0 100644
> --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
> +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c

[...]

> @@ -497,6 +514,18 @@ static int rockchip_drm_platform_probe(struct
> platform_device *pdev) continue;
>  		}
> 
> +		iommu = of_parse_phandle(port->parent, "iommus", 0);
> +		if (!iommu || !of_device_is_available(iommu->parent)) {
> +			dev_warn(dev, "No available iommu found for %s\n",
> +				 port->parent->full_name);
> +			dev_warn(dev, "Force non-iommu buffer for all crtc\n");

As stated in the patch-description, this is somewhat common for _some_ vops 
[like the Cortex-A9s I'm still hoping to support at some point in the future 
:-D ], so this should probably be either a dev_dbg or a dev_info as maximum 
and also condensed into one line of output like:

	dev_dbg(dev, "no iommu attached for %s, using non-iommu buffers\n",
			  port->parent->full_name);


Heiko