From patchwork Tue Feb 7 06:09:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: yao mark X-Patchwork-Id: 9559241 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 894136047A for ; Tue, 7 Feb 2017 06:10:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7AE67269A3 for ; Tue, 7 Feb 2017 06:10:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6F62F27F93; Tue, 7 Feb 2017 06:10:33 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00 autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 13E7627CEA for ; Tue, 7 Feb 2017 06:10:33 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cayz2-0004oM-H5; Tue, 07 Feb 2017 06:10:32 +0000 Received: from regular1.263xmail.com ([211.150.99.139]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cayye-00038S-2c; Tue, 07 Feb 2017 06:10:12 +0000 Received: from mark.yao?rock-chips.com (unknown [192.168.167.157]) by regular1.263xmail.com (Postfix) with ESMTP id F367F56D8; Tue, 7 Feb 2017 14:09:41 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from yaozq-pc.lan (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTP id CFF37408; Tue, 7 Feb 2017 14:09:41 +0800 (CST) 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: <99ea3cfb68324fbb6473c8721424207e> X-ATTACHMENT-NUM: 0 X-SENDER: yzq@rock-chips.com X-DNS-TYPE: 0 Received: from unknown (unknown [58.22.7.114]) by smtp.263.net (Postfix) whith SMTP id 27530W5BF8S; Tue, 07 Feb 2017 14:09:42 +0800 (CST) 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 Subject: [PATCH 2/4] drm/rockchip: Use common IOMMU API to attach devices Date: Tue, 7 Feb 2017 14:09:34 +0800 Message-Id: <1486447776-30543-3-git-send-email-mark.yao@rock-chips.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1486447776-30543-1-git-send-email-mark.yao@rock-chips.com> References: <1486447776-30543-1-git-send-email-mark.yao@rock-chips.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170206_221008_932054_A51CF7D5 X-CRM114-Status: GOOD ( 12.47 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Shunqian Zheng , Tomasz Figa MIME-Version: 1.0 Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+patchwork-linux-rockchip=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Shunqian Zheng Rockchip DRM used the arm special API, arm_iommu_*(), to attach iommu for ARM32 SoCs. This patch convert to common iommu API so it would support ARM64 like RK3399. Since previous patch added support for direct IOMMU address space management, there is no need to use DMA API anymore and this patch wires things to use the new method. Signed-off-by: Shunqian Zheng Signed-off-by: Tomasz Figa Acked-by: Mark Yao --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 100 +++++++++++++++------------- 1 file changed, 53 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index c30d649..7a610e9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -14,19 +14,19 @@ * GNU General Public License for more details. */ -#include - #include #include #include #include #include #include +#include #include #include #include #include #include +#include #include "rockchip_drm_drv.h" #include "rockchip_drm_fb.h" @@ -50,28 +50,31 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, struct device *dev) { - struct dma_iommu_mapping *mapping = drm_dev->dev->archdata.mapping; + struct rockchip_drm_private *private = drm_dev->dev_private; int ret; if (!is_support_iommu) return 0; - ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); - if (ret) + ret = iommu_attach_device(private->domain, dev); + if (ret) { + dev_err(dev, "Failed to attach iommu device\n"); return ret; + } - dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); - - return arm_iommu_attach_device(dev, mapping); + return 0; } void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, struct device *dev) { + struct rockchip_drm_private *private = drm_dev->dev_private; + struct iommu_domain *domain = private->domain; + if (!is_support_iommu) return; - arm_iommu_detach_device(dev); + iommu_detach_device(domain, dev); } int rockchip_register_crtc_funcs(struct drm_crtc *crtc, @@ -123,11 +126,45 @@ static void rockchip_drm_crtc_disable_vblank(struct drm_device *dev, priv->crtc_funcs[pipe]->disable_vblank(crtc); } +static int rockchip_drm_init_iommu(struct drm_device *drm_dev) +{ + struct rockchip_drm_private *private = drm_dev->dev_private; + struct iommu_domain_geometry *geometry; + u64 start, end; + + if (!is_support_iommu) + return 0; + + private->domain = iommu_domain_alloc(&platform_bus_type); + if (!private->domain) + return -ENOMEM; + + geometry = &private->domain->geometry; + start = geometry->aperture_start; + end = geometry->aperture_end; + + DRM_DEBUG("IOMMU context initialized (aperture: %#llx-%#llx)\n", + start, end); + drm_mm_init(&private->mm, start, end - start + 1); + + return 0; +} + +static void rockchip_iommu_cleanup(struct drm_device *drm_dev) +{ + struct rockchip_drm_private *private = drm_dev->dev_private; + + if (!is_support_iommu) + return; + + drm_mm_takedown(&private->mm); + iommu_domain_free(private->domain); +} + static int rockchip_drm_bind(struct device *dev) { struct drm_device *drm_dev; struct rockchip_drm_private *private; - struct dma_iommu_mapping *mapping = NULL; int ret; drm_dev = drm_dev_alloc(&rockchip_drm_driver, dev); @@ -151,38 +188,14 @@ static int rockchip_drm_bind(struct device *dev) rockchip_drm_mode_config_init(drm_dev); - dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), - GFP_KERNEL); - if (!dev->dma_parms) { - ret = -ENOMEM; + ret = rockchip_drm_init_iommu(drm_dev); + if (ret) 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; - - dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); - - 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); if (ret) - goto err_detach_device; + goto err_iommu_cleanup; /* init kms poll for handling hpd */ drm_kms_helper_poll_init(drm_dev); @@ -207,8 +220,6 @@ static int rockchip_drm_bind(struct device *dev) if (ret) goto err_fbdev_fini; - if (is_support_iommu) - arm_iommu_release_mapping(mapping); return 0; err_fbdev_fini: rockchip_drm_fbdev_fini(drm_dev); @@ -217,12 +228,8 @@ static int rockchip_drm_bind(struct device *dev) err_kms_helper_poll_fini: drm_kms_helper_poll_fini(drm_dev); component_unbind_all(dev, drm_dev); -err_detach_device: - if (is_support_iommu) - arm_iommu_detach_device(dev); -err_release_mapping: - if (is_support_iommu) - arm_iommu_release_mapping(mapping); +err_iommu_cleanup: + rockchip_iommu_cleanup(drm_dev); err_config_cleanup: drm_mode_config_cleanup(drm_dev); drm_dev->dev_private = NULL; @@ -239,8 +246,7 @@ static void rockchip_drm_unbind(struct device *dev) drm_vblank_cleanup(drm_dev); drm_kms_helper_poll_fini(drm_dev); component_unbind_all(dev, drm_dev); - if (is_support_iommu) - arm_iommu_detach_device(dev); + rockchip_iommu_cleanup(drm_dev); drm_mode_config_cleanup(drm_dev); drm_dev->dev_private = NULL; drm_dev_unregister(drm_dev);