Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752220AbcDSCUx (ORCPT ); Mon, 18 Apr 2016 22:20:53 -0400 Received: from regular1.263xmail.com ([211.150.99.135]:52882 "EHLO regular1.263xmail.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751891AbcDSCUw (ORCPT ); Mon, 18 Apr 2016 22:20:52 -0400 X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-ABS-CHECKED: 4 X-ADDR-CHECKED: 0 X-KSVirus-check: 0 X-RL-SENDER: mark.yao@rock-chips.com X-FST-TO: airlied@linux.ie X-SENDER-IP: 58.22.7.114 X-LOGIN-NAME: mark.yao@rock-chips.com X-UNIQUE-TAG: <472d52227e4c73422a33da80483957f7> X-ATTACHMENT-NUM: 0 X-DNS-TYPE: 0 From: Mark Yao To: David Airlie , Heiko Stuebner , dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Mark Yao Subject: [PATCH] drm/rockchip: support non-iommu buffer path Date: Tue, 19 Apr 2016 10:19:32 +0800 Message-Id: <1461032372-14630-1-git-send-email-mark.yao@rock-chips.com> X-Mailer: git-send-email 1.7.9.5 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4368 Lines: 141 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 --- 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 @@ -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); } -- 1.7.9.5