From patchwork Tue Jun 21 04:34:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tomasz Figa X-Patchwork-Id: 9189381 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 A6AFC6075A for ; Tue, 21 Jun 2016 04:36:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9394F27F96 for ; Tue, 21 Jun 2016 04:36:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 884A127F9A; Tue, 21 Jun 2016 04:36:35 +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=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1B70427F99 for ; Tue, 21 Jun 2016 04:36:35 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bFDQQ-00027q-DE; Tue, 21 Jun 2016 04:36:34 +0000 Received: from mail-pa0-x233.google.com ([2607:f8b0:400e:c03::233]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bFDPd-0001EL-2E for linux-rockchip@lists.infradead.org; Tue, 21 Jun 2016 04:35:47 +0000 Received: by mail-pa0-x233.google.com with SMTP id hl6so2201722pac.2 for ; Mon, 20 Jun 2016 21:35:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/wU5/1vRe821PKyy8Dz1r130oCRVJrfsiK91VvEEBlU=; b=SS8G1jpTvxwtjqQV4l4zq1Y9uFF/DObCHotOsNOS5StRbv4IymiEAXa43Iig5Je+O4 JQyxGfQ6QMR+VBW23D7+zXcVHGoGDOapho6n2DCXJ6R3M5fkW8nb94nd+CtuxR8TIF2F RNk7pL5F8hc7Q+dq53ZrMnEx8e955xriSqPLI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/wU5/1vRe821PKyy8Dz1r130oCRVJrfsiK91VvEEBlU=; b=SfylJOeVw5QgoYZhlEZqEbkxTLT9+pR/MFxMnImfyQ/o+ICWtvpUe1PE8eyKXhJWCa Gj0t+CNNAG8HWmLvpsxrPptvSKuLRau9tp74kU6d/4wFN2crT5p45eDV6Y66yK2xhFBV x+aD3V4qEZYYZuHkMsZAGIZdzSvoNv0aifeqAn5UJU9gY3e68xkW0tbcp0YZxDxqUNix qhCFu1h615EOYO2wrfq2aCnB+ebcZY9AkHZhf8INL3mNdEDVO/UqC3Z4Ik3vWn+Kuirn AzQoP7B71hPjSon3okxqJBxHNmddxU/wxxX3Akgr92XkZS9SEqbih9a/pgq8qXNEzMyV fUfQ== X-Gm-Message-State: ALyK8tLbuh4gI00qPUIvNsPlLPUdLvmpAEPvc31R0UvrhiAPkUgEKA+0EjMvkJ0pLhpz4aIA X-Received: by 10.66.25.38 with SMTP id z6mr26348443paf.11.1466483727187; Mon, 20 Jun 2016 21:35:27 -0700 (PDT) Received: from basement.tok.corp.google.com ([100.103.3.207]) by smtp.gmail.com with ESMTPSA id s3sm24500160pfb.87.2016.06.20.21.35.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 20 Jun 2016 21:35:26 -0700 (PDT) From: Tomasz Figa To: iommu@lists.linux-foundation.org, dri-devel@lists.freedesktop.org Subject: [PATCH v4 7/8] drm/rockchip: Use common IOMMU API to attach devices Date: Tue, 21 Jun 2016 13:34:40 +0900 Message-Id: <1466483681-36110-8-git-send-email-tfiga@chromium.org> X-Mailer: git-send-email 2.8.0.rc3.226.g39d4020 In-Reply-To: <1466483681-36110-1-git-send-email-tfiga@chromium.org> References: <1466483681-36110-1-git-send-email-tfiga@chromium.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160620_213545_321994_4C567066 X-CRM114-Status: GOOD ( 16.31 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Heiko Stuebner , David Airlie , Joerg Roedel , linux-kernel@vger.kernel.org, Daniel Kurtz , Tomasz Figa , linux-rockchip@lists.infradead.org, Marek Szyprowski , Shunqian Zheng , linux-arm-kernel@lists.infradead.org, Mark Yao 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 --- 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 e2c31d3..2793ac9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -14,18 +14,18 @@ * GNU General Public License for more details. */ -#include - #include #include #include #include #include +#include #include #include #include #include #include +#include #include "rockchip_drm_drv.h" #include "rockchip_drm_fb.h" @@ -49,28 +49,31 @@ static struct drm_driver rockchip_drm_driver; 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, @@ -135,11 +138,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); @@ -160,38 +197,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); @@ -216,8 +229,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); @@ -227,12 +238,8 @@ err_kms_helper_poll_fini: drm_kms_helper_poll_fini(drm_dev); err_unbind: 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; @@ -251,8 +258,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);