From patchwork Wed Apr 11 14:36:44 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Szyprowski X-Patchwork-Id: 7736 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 15E6023E42 for ; Wed, 11 Apr 2012 14:37:09 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id C3A2CA1876B for ; Wed, 11 Apr 2012 14:37:08 +0000 (UTC) Received: by yenl4 with SMTP id l4so590245yen.11 for ; Wed, 11 Apr 2012 07:37:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :mime-version:date:from:in-reply-to:to:message-id:x-mailer :references:cc:subject:x-beenthere:x-mailman-version:precedence :list-id:list-unsubscribe:list-archive:list-post:list-help :list-subscribe:content-type:content-transfer-encoding:sender :errors-to:x-gm-message-state; bh=IHTwZbgu4H7vCWkzEZs+E3+/ZvzSx310sufJKW7qfSE=; b=ShqPuSOP5VSS+WOjRsX1Pt86fdBQz0EGvr8NtdXi4yaZOW0eWlaVvsvzYYdPcsLDLT yHH8VOZmBSQ/Dya/AAu8Ok+rU3TRAN2J8Fg/JDodkKNnh0bTx2U12sx+FBD8xkLYIcvZ Rz6XPpx4LkgjjAKx6S9f4uFBuNKijMUz9EJGgH3ych2oAbC4Xq3PmCpVRiLVW8TEmj4v 7hK7I/30LRKEJC9o32a1C8QpPh5PneFJwJAyc9taBxmhv0XHLfzB5ELSvOMa7n6mkFSo DmMOZK/2C3oS5gdV4JS9LLbz5LgrQ/OJQvBbKBNEo+2e0TCT5pBogP9/0M49Mtos6J3n 4UoQ== Received: by 10.50.168.67 with SMTP id zu3mr5968884igb.28.1334155027709; Wed, 11 Apr 2012 07:37:07 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.164.217 with SMTP id f25csp87497iby; Wed, 11 Apr 2012 07:37:07 -0700 (PDT) Received: by 10.216.143.209 with SMTP id l59mr8758133wej.87.1334155020688; Wed, 11 Apr 2012 07:37:00 -0700 (PDT) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id l67si2830333weq.38.2012.04.11.07.36.59; Wed, 11 Apr 2012 07:37:00 -0700 (PDT) Received-SPF: neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) client-ip=91.189.95.16; Authentication-Results: mx.google.com; spf=neutral (google.com: 91.189.95.16 is neither permitted nor denied by best guess record for domain of linaro-mm-sig-bounces@lists.linaro.org) smtp.mail=linaro-mm-sig-bounces@lists.linaro.org Received: from localhost ([127.0.0.1] helo=mombin.canonical.com) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SHyfK-0005Ui-WD; Wed, 11 Apr 2012 14:36:59 +0000 Received: from mailout3.w1.samsung.com ([210.118.77.13]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SHyfK-0005UN-2n for linaro-mm-sig@lists.linaro.org; Wed, 11 Apr 2012 14:36:58 +0000 MIME-version: 1.0 Received: from euspt1 ([210.118.77.13]) by mailout3.w1.samsung.com (Sun Java(tm) System Messaging Server 6.3-8.04 (built Jul 29 2009; 32bit)) with ESMTP id <0M2B001I3KKZQN10@mailout3.w1.samsung.com> for linaro-mm-sig@lists.linaro.org; Wed, 11 Apr 2012 15:36:36 +0100 (BST) Received: from linux.samsung.com ([106.116.38.10]) by spt1.w1.samsung.com (iPlanet Messaging Server 5.2 Patch 2 (built Jul 14 2004)) with ESMTPA id <0M2B00EJFKLJ2Q@spt1.w1.samsung.com> for linaro-mm-sig@lists.linaro.org; Wed, 11 Apr 2012 15:36:55 +0100 (BST) Received: from mcdsrvbld02.digital.local (unknown [106.116.37.23]) by linux.samsung.com (Postfix) with ESMTP id 2BB89270061; Wed, 11 Apr 2012 16:46:29 +0200 (CEST) Date: Wed, 11 Apr 2012 16:36:44 +0200 From: Marek Szyprowski In-reply-to: <1334155004-5700-1-git-send-email-m.szyprowski@samsung.com> To: linux-arm-kernel@lists.infradead.org, linaro-mm-sig@lists.linaro.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, iommu@lists.linux-foundation.org Message-id: <1334155004-5700-2-git-send-email-m.szyprowski@samsung.com> X-Mailer: git-send-email 1.7.9.1 References: <1334155004-5700-1-git-send-email-m.szyprowski@samsung.com> Cc: Russell King - ARM Linux , Arnd Bergmann , Konrad Rzeszutek Wilk , Benjamin Herrenschmidt , Kyungmin Park , Andrzej Pietrasiewicz , KyongHo Cho , Joerg Roedel Subject: [Linaro-mm-sig] [PATCH] ARM: Exynos4: integrate SYSMMU driver with DMA-mapping interface X-BeenThere: linaro-mm-sig@lists.linaro.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Unified memory management interest group." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linaro-mm-sig-bounces@lists.linaro.org Errors-To: linaro-mm-sig-bounces@lists.linaro.org X-Gm-Message-State: ALoCoQl3vSM6x2+7bTmO0JM6uR4v4IaALQiLX11GbhQ/sbHo2j0kSgXUB8Z04li4/Q3HXxWKapJF This patch provides an provides setup code which assigns IOMMU controllers to FIMC and MFC devices and enables IOMMU aware DMA-mapping for them. It has been tested on Samsung Exynos4 platform, NURI board. Most of the work is done in the s5p_sysmmu_late_init() function, which first assigns SYSMMU controller to respective client device and then creates IO address space mapping structures. In this example 128 MiB of address space is created at 0x20000000 for most of the devices. IO address allocation precision is set to 2^4 pages, so all small allocations will be aligned to 64 pages. This reduces the size of the io address space bitmap to 4 KiB. To solve the clock dependency issues, parent clocks have been added to each SYSMMU controller bus clock. This models the true hardware behavior, because client's device bus clock also gates the respective sysmmu bus clock. Signed-off-by: Marek Szyprowski Acked-by: Kyungmin Park --- arch/arm/mach-exynos/Kconfig | 1 + arch/arm/mach-exynos/clock-exynos4.c | 64 +++++++++++++++------------- arch/arm/mach-exynos/dev-sysmmu.c | 44 +++++++++++++++++++ arch/arm/mach-exynos/include/mach/sysmmu.h | 3 + drivers/iommu/Kconfig | 1 + 5 files changed, 84 insertions(+), 29 deletions(-) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index 801c738..25b9ba5 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -288,6 +288,7 @@ config MACH_NURI select S5P_DEV_USB_EHCI select S5P_SETUP_MIPIPHY select EXYNOS4_DEV_DMA + select EXYNOS_DEV_SYSMMU select EXYNOS4_SETUP_FIMC select EXYNOS4_SETUP_FIMD0 select EXYNOS4_SETUP_I2C1 diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c index 29ae4df..fe459a3 100644 --- a/arch/arm/mach-exynos/clock-exynos4.c +++ b/arch/arm/mach-exynos/clock-exynos4.c @@ -497,29 +497,6 @@ static struct clk *exynos4_gate_clocks[] = { static struct clk exynos4_init_clocks_off[] = { { - .name = "timers", - .parent = &exynos4_clk_aclk_100.clk, - .enable = exynos4_clk_ip_peril_ctrl, - .ctrlbit = (1<<24), - }, { - .name = "csis", - .devname = "s5p-mipi-csis.0", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 4), - .parent = &exynos4_clk_gate_cam, - }, { - .name = "csis", - .devname = "s5p-mipi-csis.1", - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 5), - .parent = &exynos4_clk_gate_cam, - }, { - .name = "jpeg", - .id = 0, - .enable = exynos4_clk_ip_cam_ctrl, - .ctrlbit = (1 << 6), - .parent = &exynos4_clk_gate_cam, - }, { .name = "fimc", .devname = "exynos4-fimc.0", .enable = exynos4_clk_ip_cam_ctrl, @@ -544,6 +521,35 @@ static struct clk exynos4_init_clocks_off[] = { .ctrlbit = (1 << 3), .parent = &exynos4_clk_gate_cam, }, { + .name = "mfc", + .devname = "s5p-mfc", + .enable = exynos4_clk_ip_mfc_ctrl, + .ctrlbit = (1 << 0), + .parent = &exynos4_clk_gate_mfc, + }, { + .name = "timers", + .parent = &exynos4_clk_aclk_100.clk, + .enable = exynos4_clk_ip_peril_ctrl, + .ctrlbit = (1<<24), + }, { + .name = "csis", + .devname = "s5p-mipi-csis.0", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 4), + .parent = &exynos4_clk_gate_cam, + }, { + .name = "csis", + .devname = "s5p-mipi-csis.1", + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 5), + .parent = &exynos4_clk_gate_cam, + }, { + .name = "jpeg", + .id = 0, + .enable = exynos4_clk_ip_cam_ctrl, + .ctrlbit = (1 << 6), + .parent = &exynos4_clk_gate_cam, + }, { .name = "hsmmc", .devname = "exynos4-sdhci.0", .parent = &exynos4_clk_aclk_133.clk, @@ -674,12 +680,6 @@ static struct clk exynos4_init_clocks_off[] = { .ctrlbit = (1 << 0), .parent = &exynos4_clk_gate_lcd0, }, { - .name = "mfc", - .devname = "s5p-mfc", - .enable = exynos4_clk_ip_mfc_ctrl, - .ctrlbit = (1 << 0), - .parent = &exynos4_clk_gate_mfc, - }, { .name = "i2c", .devname = "s3c2440-i2c.0", .parent = &exynos4_clk_aclk_100.clk, @@ -738,11 +738,13 @@ static struct clk exynos4_init_clocks_off[] = { .devname = SYSMMU_CLOCK_DEVNAME(mfc_l, 0), .enable = exynos4_clk_ip_mfc_ctrl, .ctrlbit = (1 << 1), + .parent = &exynos4_init_clocks_off[4], }, { .name = SYSMMU_CLOCK_NAME, .devname = SYSMMU_CLOCK_DEVNAME(mfc_r, 1), .enable = exynos4_clk_ip_mfc_ctrl, .ctrlbit = (1 << 2), + .parent = &exynos4_init_clocks_off[4], }, { .name = SYSMMU_CLOCK_NAME, .devname = SYSMMU_CLOCK_DEVNAME(tv, 2), @@ -763,21 +765,25 @@ static struct clk exynos4_init_clocks_off[] = { .devname = SYSMMU_CLOCK_DEVNAME(fimc0, 5), .enable = exynos4_clk_ip_cam_ctrl, .ctrlbit = (1 << 7), + .parent = &exynos4_init_clocks_off[0], }, { .name = SYSMMU_CLOCK_NAME, .devname = SYSMMU_CLOCK_DEVNAME(fimc1, 6), .enable = exynos4_clk_ip_cam_ctrl, .ctrlbit = (1 << 8), + .parent = &exynos4_init_clocks_off[1], }, { .name = SYSMMU_CLOCK_NAME, .devname = SYSMMU_CLOCK_DEVNAME(fimc2, 7), .enable = exynos4_clk_ip_cam_ctrl, .ctrlbit = (1 << 9), + .parent = &exynos4_init_clocks_off[2], }, { .name = SYSMMU_CLOCK_NAME, .devname = SYSMMU_CLOCK_DEVNAME(fimc3, 8), .enable = exynos4_clk_ip_cam_ctrl, .ctrlbit = (1 << 10), + .parent = &exynos4_init_clocks_off[3], }, { .name = SYSMMU_CLOCK_NAME, .devname = SYSMMU_CLOCK_DEVNAME(fimd0, 10), diff --git a/arch/arm/mach-exynos/dev-sysmmu.c b/arch/arm/mach-exynos/dev-sysmmu.c index 3544638..31f2d6ca 100644 --- a/arch/arm/mach-exynos/dev-sysmmu.c +++ b/arch/arm/mach-exynos/dev-sysmmu.c @@ -12,12 +12,15 @@ #include #include +#include #include +#include #include #include #include +#include static u64 exynos_sysmmu_dma_mask = DMA_BIT_MASK(32); @@ -276,3 +279,44 @@ static int __init init_sysmmu_platform_device(void) * see pm_domain.c, which use arch_initcall() */ core_initcall(init_sysmmu_platform_device); +#ifdef CONFIG_ARM_DMA_USE_IOMMU +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base, + unsigned int size, int order) +{ + struct dma_iommu_mapping *mapping; + if (!client) + return 0; + mapping = arm_iommu_create_mapping(&platform_bus_type, base, size, order); + if (!mapping) + return -ENOMEM; + client->dma_parms = kzalloc(sizeof(*client->dma_parms), GFP_KERNEL); + dma_set_max_seg_size(client, 0xffffffffu); + arm_iommu_attach_device(client, mapping); + return 0; +} + +/* + * s5p_sysmmu_late_init + * Create DMA-mapping IOMMU context for specified devices. This function must + * be called later, once SYSMMU driver gets registered and probed. + */ +static int __init s5p_sysmmu_late_init(void) +{ + platform_set_sysmmu(&SYSMMU_PLATDEV(fimc0).dev, &s5p_device_fimc0.dev); + platform_set_sysmmu(&SYSMMU_PLATDEV(fimc1).dev, &s5p_device_fimc1.dev); + platform_set_sysmmu(&SYSMMU_PLATDEV(fimc2).dev, &s5p_device_fimc2.dev); + platform_set_sysmmu(&SYSMMU_PLATDEV(fimc3).dev, &s5p_device_fimc3.dev); + platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_l).dev, &s5p_device_mfc_l.dev); + platform_set_sysmmu(&SYSMMU_PLATDEV(mfc_r).dev, &s5p_device_mfc_r.dev); + + s5p_create_iommu_mapping(&s5p_device_fimc0.dev, 0x20000000, SZ_128M, 4); + s5p_create_iommu_mapping(&s5p_device_fimc1.dev, 0x20000000, SZ_128M, 4); + s5p_create_iommu_mapping(&s5p_device_fimc2.dev, 0x20000000, SZ_128M, 4); + s5p_create_iommu_mapping(&s5p_device_fimc3.dev, 0x20000000, SZ_128M, 4); + s5p_create_iommu_mapping(&s5p_device_mfc_l.dev, 0x20000000, SZ_128M, 4); + s5p_create_iommu_mapping(&s5p_device_mfc_r.dev, 0x40000000, SZ_128M, 4); + + return 0; +} +device_initcall(s5p_sysmmu_late_init); +#endif diff --git a/arch/arm/mach-exynos/include/mach/sysmmu.h b/arch/arm/mach-exynos/include/mach/sysmmu.h index 998daf2..07cae3a 100644 --- a/arch/arm/mach-exynos/include/mach/sysmmu.h +++ b/arch/arm/mach-exynos/include/mach/sysmmu.h @@ -57,6 +57,9 @@ static inline void platform_set_sysmmu( } #endif +int __init s5p_create_iommu_mapping(struct device *client, dma_addr_t base, + unsigned int size, int order); + #else /* !CONFIG_EXYNOS_DEV_SYSMMU */ #define platform_set_sysmmu(dev, sysmmu) do { } while (0) #endif diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 3b745bb..223e31e 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -166,6 +166,7 @@ config EXYNOS_IOMMU bool "Exynos IOMMU Support" depends on EXYNOS_DEV_SYSMMU select IOMMU_API + select ARM_DMA_USE_IOMMU help Support for the IOMMU(System MMU) of Samsung Exynos application processor family. This enables H/W multimedia accellerators to see