From patchwork Wed Mar 21 09:09:23 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Gaignard X-Patchwork-Id: 7383 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 6B15D23E42 for ; Wed, 21 Mar 2012 09:00:07 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 1A074A18233 for ; Wed, 21 Mar 2012 09:00:07 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id e36so1737390iag.11 for ; Wed, 21 Mar 2012 02:00:06 -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:from:to :date:message-id:x-mailer:in-reply-to:references:mime-version :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=5Zwk7H2AyXKJqRpKisjFUAdZIxaJJskoyhGuUvrJSA8=; b=A0FIrWjWu5cRkyMNh3P96k6J1sb9YGPw10lDCovGmvofTw9/fjSXcbViC5NgN4hcwS O4VtoOlZ+eLdwp98b8fKR1xWennpTjl2NdCg0HoX1eM6eUNwESEdgRB42Ks2Cu8RDUhp Z8pASnV27EZhfdWdV6mJhE1YwUDqQImXDs8TxVj2s2P09Ot/clIjtsDmrOMpwTe/znG/ bwiyWS2anFjKY6ZlRJre85Bff6vkHozKzINjEv6GmL9LZNa1c7WjIwvc3SsCSakL/ZYm hjKIAn+hjU/eSM10MuwZVb+J1z+S6tzKD6lOPYADtkgQCG3RiZABRsGxOXwi9bf8V7VB 677g== Received: by 10.50.153.193 with SMTP id vi1mr2238675igb.2.1332320406879; Wed, 21 Mar 2012 02:00:06 -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.203.79 with SMTP id fh15csp4715ibb; Wed, 21 Mar 2012 02:00:04 -0700 (PDT) Received: by 10.180.102.102 with SMTP id fn6mr36274557wib.10.1332320399217; Wed, 21 Mar 2012 01:59:59 -0700 (PDT) Received: from mombin.canonical.com (mombin.canonical.com. [91.189.95.16]) by mx.google.com with ESMTP id el4si1205564wid.17.2012.03.21.01.59.58; Wed, 21 Mar 2012 01:59:59 -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 1SAHOf-0004gF-DD; Wed, 21 Mar 2012 08:59:57 +0000 Received: from eu1sys200aog110.obsmtp.com ([207.126.144.129]) by mombin.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1SAHOd-0004f7-UL for linaro-mm-sig@lists.linaro.org; Wed, 21 Mar 2012 08:59:56 +0000 Received: from beta.dmz-eu.st.com ([164.129.1.35]) (using TLSv1) by eu1sys200aob110.postini.com ([207.126.147.11]) with SMTP ID DSNKT2mYis63lIs8PAaxAMslbUZm1CY244ne@postini.com; Wed, 21 Mar 2012 08:59:55 UTC Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 2BF50F5; Wed, 21 Mar 2012 08:59:51 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id C47061A7A; Wed, 21 Mar 2012 08:59:50 +0000 (GMT) Received: from exdcvycastm003.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm003", Issuer "exdcvycastm003" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id F374EA8065; Wed, 21 Mar 2012 09:59:46 +0100 (CET) Received: from localhost.localdomain (10.230.100.153) by smtp.stericsson.com (10.230.100.1) with Microsoft SMTP Server (TLS) id 8.3.83.0; Wed, 21 Mar 2012 09:59:50 +0100 From: To: Date: Wed, 21 Mar 2012 10:09:23 +0100 Message-ID: <1332320963-29001-5-git-send-email-benjamin.gaignard@stericsson.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1332320963-29001-1-git-send-email-benjamin.gaignard@stericsson.com> References: <1332320963-29001-1-git-send-email-benjamin.gaignard@stericsson.com> MIME-Version: 1.0 Subject: [Linaro-mm-sig] [PATCH v4 4/4] add test/example driver for ux500 platform 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: ALoCoQk18tL32zmVFXm8I5C/9MBQauvPSzxjlKoHLl7Ya+Ii7UjnUO1+zp0mtdOe9WVFthNgFLMC From: Benjamin Gaignard DO NOT MERGE ux500-ion driver is provided as example. Define 2 CMA heaps, one on a specific CMA region reserved at boot time the other will use the default CMA region. Since we can have multiple instances of this driver while only one ion device can be instanciated, we need to take care of ion_heap structure reallocation. Signed-off-by: Benjamin Gaignard --- arch/arm/mach-ux500/board-mop500.c | 77 +++++++++++++++++++ drivers/gpu/ion/Kconfig | 6 ++ drivers/gpu/ion/Makefile | 1 + drivers/gpu/ion/ux500/Makefile | 1 + drivers/gpu/ion/ux500/ux500_ion.c | 142 ++++++++++++++++++++++++++++++++++++ 5 files changed, 227 insertions(+), 0 deletions(-) create mode 100644 drivers/gpu/ion/ux500/Makefile create mode 100644 drivers/gpu/ion/ux500/ux500_ion.c diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index bdd7b80..d9dbee5 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -30,6 +30,11 @@ #include #include +#ifdef CONFIG_ION +#include +#include +#endif + #include #include #include @@ -50,6 +55,62 @@ #include "board-mop500.h" #include "board-mop500-regulators.h" +#ifdef CONFIG_ION +static u64 snowball_dmamask = DMA_BIT_MASK(32); + +static struct ion_platform_heap snowball_ion_heap1[] = { + [0] = { + .type = ION_HEAP_TYPE_DMA, + .id = 1, + .name = "ion-cma-heap-1", + .base = 0, + .size = (16 * SZ_1M), + }, +}; + +static struct ion_platform_data snowball_ion_data1 = { + .heaps = snowball_ion_heap1, + .nr = ARRAY_SIZE(snowball_ion_heap1), +}; + +static struct platform_device snowball_ion_device1 = { + .name = "ion-ux500", + .id = 1, + .dev = { + .dma_mask = &snowball_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &snowball_ion_data1, + }, + .num_resources = 0, +}; + +static struct ion_platform_heap snowball_ion_heap2[] = { + [0] = { + .type = ION_HEAP_TYPE_DMA, + .id = 2, + .name = "ion-cma-heap-2", + .base = 0, + .size = (16 * SZ_1M), + }, +}; + +static struct ion_platform_data snowball_ion_data2 = { + .heaps = snowball_ion_heap2, + .nr = ARRAY_SIZE(snowball_ion_heap2), +}; + +static struct platform_device snowball_ion_device2 = { + .name = "ion-ux500", + .id = 2, + .dev = { + .dma_mask = &snowball_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &snowball_ion_data2, + }, + .num_resources = 0, +}; +#endif + static struct gpio_led snowball_led_array[] = { { .name = "user_led", @@ -598,8 +659,21 @@ static struct platform_device *snowball_platform_devs[] __initdata = { &snowball_key_dev, &snowball_sbnet_dev, &ab8500_device, +#ifdef CONFIG_ION + &snowball_ion_device1, + &snowball_ion_device2, +#endif }; +#ifdef CONFIG_ION +static void __init mop500_reserve(void) +{ + dma_declare_contiguous(&snowball_ion_device1.dev, + snowball_ion_heap1[0].size, + snowball_ion_heap1[0].base, 0); +} +#endif + static void __init mop500_init_machine(void) { int i2c0_devs; @@ -713,4 +787,7 @@ MACHINE_START(SNOWBALL, "Calao Systems Snowball platform") /* we re-use nomadik timer here */ .timer = &ux500_timer, .init_machine = snowball_init_machine, +#ifdef CONFIG_ION + .reserve = mop500_reserve, +#endif MACHINE_END diff --git a/drivers/gpu/ion/Kconfig b/drivers/gpu/ion/Kconfig index 0e87dab..9352020 100644 --- a/drivers/gpu/ion/Kconfig +++ b/drivers/gpu/ion/Kconfig @@ -9,3 +9,9 @@ config ION_TEGRA depends on ARCH_TEGRA && ION help Choose this option if you wish to use ion on an nVidia Tegra. + +config ION_UX500 + tristate "Ion for ux500" + depends on ARCH_U8500 && ION + help + Choose this option if you wish to use ion on ux500 platforms. diff --git a/drivers/gpu/ion/Makefile b/drivers/gpu/ion/Makefile index ddcedb5..ed38775 100644 --- a/drivers/gpu/ion/Makefile +++ b/drivers/gpu/ion/Makefile @@ -1,3 +1,4 @@ ion-driver-objs += ion.o ion_heap.o ion_system_heap.o ion_carveout_heap.o ion_cma_heap.o obj-$(CONFIG_ION) += ion-driver.o obj-$(CONFIG_ION_TEGRA) += tegra/ +obj-$(CONFIG_ION_UX500) += ux500/ diff --git a/drivers/gpu/ion/ux500/Makefile b/drivers/gpu/ion/ux500/Makefile new file mode 100644 index 0000000..691c600 --- /dev/null +++ b/drivers/gpu/ion/ux500/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_ION_UX500) += ux500_ion.o diff --git a/drivers/gpu/ion/ux500/ux500_ion.c b/drivers/gpu/ion/ux500/ux500_ion.c new file mode 100644 index 0000000..c7560c7 --- /dev/null +++ b/drivers/gpu/ion/ux500/ux500_ion.c @@ -0,0 +1,142 @@ +/* + * drivers/gpu/ion/ux500/ux500_ion.c + * + * Copyright (C) Linaro 2012 + * Author: for ST-Ericsson. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include "../ion_priv.h" + +struct ion_device *ux500_ion_device; +int num_heaps; +struct ion_heap **ux500_ion_heaps; + +int ux500_ion_probe(struct platform_device *pdev) +{ + struct ion_platform_data *pdata = pdev->dev.platform_data; + int err; + int i, previous_heaps_count = 0; + + /* test if it is the first time we try to create ions heaps */ + if (num_heaps == 0) { + num_heaps = pdata->nr; + + ux500_ion_heaps = + kzalloc(sizeof(struct ion_heap *) * pdata->nr, GFP_KERNEL); + memset(ux500_ion_heaps, 0, + sizeof(struct ion_heap *) * pdata->nr); + + dev_dbg(&pdev->dev, "create ion device\n"); + ux500_ion_device = ion_device_create(NULL); + if (IS_ERR_OR_NULL(ux500_ion_device)) { + kfree(ux500_ion_heaps); + num_heaps = 0; + dev_err(&pdev->dev, "failed to create ion device\n"); + return PTR_ERR(ux500_ion_device); + } + } else { + struct ion_heap **new_ux500_ion_heaps; + + previous_heaps_count = num_heaps; + num_heaps += pdata->nr; + + /* allocate a bigger array of ion_heap */ + new_ux500_ion_heaps = + kzalloc(sizeof(struct ion_heap *) * num_heaps, GFP_KERNEL); + memset(new_ux500_ion_heaps, 0, + sizeof(struct ion_heap *) * num_heaps); + + dev_dbg(&pdev->dev, "realloc ion heap\n"); + /* copy old heap array info into the new one */ + for (i = 0; i < previous_heaps_count; i++) + new_ux500_ion_heaps[i] = ux500_ion_heaps[i]; + + /* free old heap array and swap it with the new one */ + kfree(ux500_ion_heaps); + ux500_ion_heaps = new_ux500_ion_heaps; + } + + /* create the heaps as specified in the board file */ + for (i = previous_heaps_count; i < num_heaps; i++) { + struct ion_platform_heap *heap_data = + &pdata->heaps[i - previous_heaps_count]; + + ux500_ion_heaps[i] = + ion_heap_create_full(heap_data, &pdev->dev); + + if (IS_ERR_OR_NULL(ux500_ion_heaps[i])) { + err = PTR_ERR(ux500_ion_heaps[i]); + ux500_ion_heaps[i] = NULL; + dev_err(&pdev->dev, + "failed to create heap type %d id %d\n", + heap_data->type, heap_data->id); + goto err; + } + ion_device_add_heap(ux500_ion_device, ux500_ion_heaps[i]); + } + + platform_set_drvdata(pdev, ux500_ion_device); + + return 0; +err: + for (i = 0; i < num_heaps; i++) { + if (ux500_ion_heaps[i]) + ion_heap_destroy(ux500_ion_heaps[i]); + } + kfree(ux500_ion_heaps); + return err; +} + +int ux500_ion_remove(struct platform_device *pdev) +{ + struct ion_device *idev = platform_get_drvdata(pdev); + int i; + + ion_device_destroy(idev); + for (i = 0; i < num_heaps; i++) + ion_heap_destroy(ux500_ion_heaps[i]); + kfree(ux500_ion_heaps); + return 0; +} + +static struct platform_driver ux500_ion_driver = { + .probe = ux500_ion_probe, + .remove = ux500_ion_remove, + .driver = { + .name = "ion-ux500", + } +}; + +static int __init ux500_ion_init(void) +{ + ux500_ion_device = NULL; + num_heaps = 0; + ux500_ion_heaps = NULL; + + return platform_driver_register(&ux500_ion_driver); +} + +static void __exit ux500_ion_exit(void) +{ + if (ux500_ion_device) + ion_device_destroy(ux500_ion_device); + + platform_driver_unregister(&ux500_ion_driver); +} + +module_init(ux500_ion_init); +module_exit(ux500_ion_exit);