From patchwork Fri Oct 1 11:55:59 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh KUMAR X-Patchwork-Id: 224042 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o91C6WGF014464 for ; Fri, 1 Oct 2010 12:06:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932133Ab0JAMEu (ORCPT ); Fri, 1 Oct 2010 08:04:50 -0400 Received: from eu1sys200aog110.obsmtp.com ([207.126.144.129]:56161 "EHLO eu1sys200aog110.obsmtp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756111Ab0JAL6I (ORCPT ); Fri, 1 Oct 2010 07:58:08 -0400 Received: from source ([164.129.1.35]) (using TLSv1) by eu1sys200aob110.postini.com ([207.126.147.11]) with SMTP ID DSNKTKXMxERtZtUVrX9dfj20JXXLiF8piSwc@postini.com; Fri, 01 Oct 2010 11:58:07 UTC Received: from zeta.dmz-eu.st.com (ns2.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 4D7339A; Fri, 1 Oct 2010 11:57:49 +0000 (GMT) Received: from mail2.dlh.st.com (mail2.dlh.st.com [10.199.8.22]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id B42C22652; Fri, 1 Oct 2010 11:57:45 +0000 (GMT) Received: from localhost (dlhl0509.dlh.st.com [10.199.7.86]) by mail2.dlh.st.com (MOS 3.8.7a) with ESMTP id CUF00985 (AUTH viresh.kumar@st.com); Fri, 1 Oct 2010 17:27:44 +0530 (IST) From: Viresh KUMAR To: linux-arm-kernel@lists.infradead.org, rtc-linux@googlegroups.com, a.zummo@towertech.it, dbrownell@users.sourceforge.net, linux-usb@vger.kernel.org, linux-input@vger.kernel.org, dmitry.torokhov@gmail.com, linux-mtd@lists.infradead.org, dwmw2@infradead.org Cc: Vipin Kumar , shiraz.hashim@st.com, deepak.sikri@st.com, armando.visconti@st.com, vipulkumar.samar@st.com, rajeev-dlh.kumar@st.com, pratyush.anand@st.com, bhupesh.sharma@st.com, Viresh Kumar Subject: [PATCH V2 39/69] ST SPEAr : EMI (Extrenal Memory Interface) controller driver Date: Fri, 1 Oct 2010 17:25:59 +0530 Message-Id: <027f942df7073593a3b14406be48590f0ad460eb.1285933332.git.viresh.kumar@st.com> X-Mailer: git-send-email 1.7.2.2 In-Reply-To: References: In-Reply-To: References: Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Fri, 01 Oct 2010 12:06:33 +0000 (UTC) diff --git a/arch/arm/mach-spear3xx/Makefile b/arch/arm/mach-spear3xx/Makefile index b248624..d38ae47 100644 --- a/arch/arm/mach-spear3xx/Makefile +++ b/arch/arm/mach-spear3xx/Makefile @@ -24,3 +24,7 @@ obj-$(CONFIG_MACH_SPEAR320) += spear320.o # spear320 boards files obj-$(CONFIG_BOARD_SPEAR320_EVB) += spear320_evb.o + +# specific files +obj-$(CONFIG_MACH_SPEAR310) += emi.o +obj-$(CONFIG_MACH_SPEAR320) += emi.o diff --git a/arch/arm/mach-spear3xx/emi.c b/arch/arm/mach-spear3xx/emi.c new file mode 100644 index 0000000..7b62ff0 --- /dev/null +++ b/arch/arm/mach-spear3xx/emi.c @@ -0,0 +1,101 @@ +/* + * arch/arm/mach-spear3xx/emi.c + * + * EMI (External Memory Interface) file + * + * Copyright (C) 2010 ST Microelectronics + * Vipin Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include + +int __init emi_init(struct platform_device *pdev, unsigned long base, + u32 bank, u32 width) +{ + void __iomem *emi_reg_base; + struct clk *clk; + int ret; + + if (bank > (EMI_MAX_BANKS - 1)) + return -EINVAL; + + emi_reg_base = ioremap(base, EMI_REG_SIZE); + if (!emi_reg_base) + return -ENOMEM; + + clk = clk_get(NULL, "emi"); + if (IS_ERR(clk)) { + iounmap(emi_reg_base); + return PTR_ERR(clk); + } + + ret = clk_enable(clk); + if (ret) { + iounmap(emi_reg_base); + return ret; + } + + /* + * Note: These are relaxed NOR device timings. Nor devices on spear + * eval machines are working fine with these timings. Specific board + * files can optimize these timings based on devices found on board. + */ + writel(0x10, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TAP_REG); + writel(0x05, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TSDP_REG); + writel(0x0a, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TDPW_REG); + writel(0x0a, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TDPR_REG); + writel(0x05, emi_reg_base + (EMI_BANK_REG_SIZE * bank) + TDCS_REG); + + switch (width) { + case EMI_FLASH_WIDTH8: + width = EMI_CNTL_WIDTH8; + break; + + case EMI_FLASH_WIDTH16: + width = EMI_CNTL_WIDTH16; + break; + + case EMI_FLASH_WIDTH32: + width = EMI_CNTL_WIDTH32; + break; + default: + width = EMI_CNTL_WIDTH8; + break; + } + /* set the data width */ + writel(width | EMI_CNTL_ENBBYTERW, + emi_reg_base + (EMI_BANK_REG_SIZE * bank) + CTRL_REG); + + /* disable all the acks */ + writel(0x3f, emi_reg_base + ack_reg); + + iounmap(emi_reg_base); + + return 0; +} + +void __init +emi_init_board_info(struct platform_device *pdev, struct resource *resources, + int res_num, struct mtd_partition *partitions, + unsigned int nr_partitions, unsigned int width) +{ + struct physmap_flash_data *emi_plat_data = dev_get_platdata(&pdev->dev); + + pdev->resource = resources; + pdev->num_resources = res_num; + + if (partitions) { + emi_plat_data->parts = partitions; + emi_plat_data->nr_parts = nr_partitions; + } + + emi_plat_data->width = width; +} diff --git a/arch/arm/mach-spear3xx/include/mach/emi.h b/arch/arm/mach-spear3xx/include/mach/emi.h new file mode 100644 index 0000000..b620bf5 --- /dev/null +++ b/arch/arm/mach-spear3xx/include/mach/emi.h @@ -0,0 +1,64 @@ +/* + * arch/arm/mach-spear3xx/include/mach/emi.h + * + * EMI macros for SPEAr platform + * + * Copyright (C) 2010 ST Microelectronics + * Vipin Kumar + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#ifndef __MACH_EMI_H +#define __MACH_EMI_H + +#include +#include +#include + +#define EMI_FLASH_WIDTH8 1 +#define EMI_FLASH_WIDTH16 2 +#define EMI_FLASH_WIDTH32 4 + +#define EMI_REG_SIZE 0x100 +#define EMI_BANK_REG_SIZE 0x18 + +#define TAP_REG (0x0) +#define TSDP_REG (0x4) +#define TDPW_REG (0x8) +#define TDPR_REG (0xC) +#define TDCS_REG (0x10) +#define CTRL_REG (0x14) + +#if defined(CONFIG_MACH_SPEAR310) +#define TIMEOUT_REG (0x90) +#define ACK_REG (0x94) +#define IRQ_REG (0x98) + +#define EMI_MAX_BANKS 6 + +#elif defined(CONFIG_MACH_SPEAR320) +#define TIMEOUT_REG (0x60) +#define ACK_REG (0x64) +#define IRQ_REG (0x68) + +#define EMI_MAX_BANKS 4 + +#endif + +/* Control register definitions */ +#define EMI_CNTL_WIDTH8 (0 << 0) +#define EMI_CNTL_WIDTH16 (1 << 0) +#define EMI_CNTL_WIDTH32 (2 << 0) +#define EMI_CNTL_ENBBYTEW (1 << 2) +#define EMI_CNTL_ENBBYTER (1 << 3) +#define EMI_CNTL_ENBBYTERW (EMI_CNTL_ENBBYTER | EMI_CNTL_ENBBYTEW) + +extern int __init emi_init(struct platform_device *pdev, unsigned long base, + u32 bank, u32 width); +extern void __init emi_init_board_info(struct platform_device *pdev, + struct resource *resources, int res_num, struct mtd_partition + *partitions, unsigned int nr_partitions, unsigned int width); +#endif diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h index 7b83197..1462944 100644 --- a/arch/arm/mach-spear3xx/include/mach/generic.h +++ b/arch/arm/mach-spear3xx/include/mach/generic.h @@ -166,6 +166,7 @@ extern struct amba_device uart2_device; extern struct amba_device uart3_device; extern struct amba_device uart4_device; extern struct amba_device uart5_device; +extern struct platform_device emi_nor_device; extern struct platform_device plgpio_device; extern struct platform_device nand_device; @@ -191,6 +192,7 @@ extern struct amba_device uart1_device; extern struct amba_device uart2_device; extern struct platform_device can0_device; extern struct platform_device can1_device; +extern struct platform_device emi_nor_device; extern struct platform_device i2c1_device; extern struct platform_device nand_device; extern struct platform_device plgpio_device; diff --git a/arch/arm/mach-spear3xx/include/mach/spear310.h b/arch/arm/mach-spear3xx/include/mach/spear310.h index 1e85347..37556b6 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear310.h +++ b/arch/arm/mach-spear3xx/include/mach/spear310.h @@ -18,6 +18,15 @@ #define SPEAR310_NAND_BASE UL(0x40000000) #define SPEAR310_FSMC_BASE UL(0x44000000) +#define SPEAR310_EMI_REG_BASE UL(0x4F000000) +#define SPEAR310_EMI_MEM_0_BASE UL(0x50000000) +#define SPEAR310_EMI_MEM_1_BASE UL(0x60000000) +#define SPEAR310_EMI_MEM_2_BASE UL(0x70000000) +#define SPEAR310_EMI_MEM_3_BASE UL(0x80000000) +#define SPEAR310_EMI_MEM_4_BASE UL(0x90000000) +#define SPEAR310_EMI_MEM_5_BASE UL(0xA0000000) +#define SPEAR310_EMI_MEM_SIZE UL(0x10000000) + #define SPEAR310_UART1_BASE UL(0xB2000000) #define SPEAR310_UART2_BASE UL(0xB2080000) #define SPEAR310_UART3_BASE UL(0xB2100000) diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h index 940f0d8..4f60073 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear320.h +++ b/arch/arm/mach-spear3xx/include/mach/spear320.h @@ -17,6 +17,12 @@ #define __MACH_SPEAR320_H #define SPEAR320_EMI_CTRL_BASE UL(0x40000000) +#define SPEAR320_EMI_MEM_0_BASE UL(0x44000000) +#define SPEAR320_EMI_MEM_1_BASE UL(0x45000000) +#define SPEAR320_EMI_MEM_2_BASE UL(0x46000000) +#define SPEAR320_EMI_MEM_3_BASE UL(0x47000000) +#define SPEAR320_EMI_MEM_SIZE UL(0x01000000) + #define SPEAR320_FSMC_BASE UL(0x4C000000) #define SPEAR320_NAND_BASE UL(0x50000000) #define SPEAR320_I2S_BASE UL(0x60000000) diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 25a0e94..0d12ee3 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c @@ -11,6 +11,7 @@ * warranty of any kind, whether express or implied. */ +#include #include #include #include @@ -268,6 +269,14 @@ int spear300_o2p(int offset) return offset + 2; } +/* emi nor flash device registeration */ +static struct physmap_flash_data emi_norflash_data; +struct platform_device emi_nor_device = { + .name = "physmap-flash", + .id = -1, + .dev.platform_data = &emi_norflash_data, +}; + static struct plgpio_platform_data plgpio_plat_data = { .gpio_base = 8, .irq_base = SPEAR_PLGPIO_INT_BASE, diff --git a/arch/arm/mach-spear3xx/spear310_evb.c b/arch/arm/mach-spear3xx/spear310_evb.c index bff90b3..49aca18 100644 --- a/arch/arm/mach-spear3xx/spear310_evb.c +++ b/arch/arm/mach-spear3xx/spear310_evb.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,24 @@ #include #include +#define PARTITION(n, off, sz) {.name = n, .offset = off, .size = sz} + +static struct mtd_partition partition_info[] = { + PARTITION("X-loader", 0, 1 * 0x20000), + PARTITION("U-Boot", 0x20000, 3 * 0x20000), + PARTITION("Kernel", 0x80000, 24 * 0x20000), + PARTITION("Root File System", 0x380000, 84 * 0x20000), +}; + +/* emi nor flash resources registeration */ +static struct resource emi_nor_resources[] = { + { + .start = SPEAR310_EMI_MEM_0_BASE, + .end = SPEAR310_EMI_MEM_0_BASE + SPEAR310_EMI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + /* padmux devices to enable */ static struct pmx_dev *pmx_devs[] = { /* spear3xx specific devices */ @@ -61,6 +80,7 @@ static struct amba_device *amba_devs[] __initdata = { static struct platform_device *plat_devs[] __initdata = { /* spear3xx specific devices */ &ehci_device, + &emi_nor_device, &i2c_device, &nand_device, &ohci0_device, @@ -129,6 +149,11 @@ static void __init spear310_evb_init(void) /* initialize serial nor related data in smi plat data */ smi_init_board_info(&smi_device); + /* initialize emi related data in emi plat data */ + emi_init_board_info(&emi_nor_device, emi_nor_resources, + ARRAY_SIZE(emi_nor_resources), partition_info, + ARRAY_SIZE(partition_info), EMI_FLASH_WIDTH32); + /* Add Platform Devices */ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); @@ -136,6 +161,9 @@ static void __init spear310_evb_init(void) for (i = 0; i < ARRAY_SIZE(amba_devs); i++) amba_device_register(amba_devs[i], &iomem_resource); + /* Initialize emi regiters */ + emi_init(&emi_nor_device, SPEAR310_EMI_REG_BASE, 0, EMI_FLASH_WIDTH32); + spi_init(); } diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index a6aa487..ae09245 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -473,6 +474,14 @@ struct amba_device uart2_device = { .irq = {VIRQ_UART2, NO_IRQ}, }; +/* emi nor flash device registeration */ +static struct physmap_flash_data emi_norflash_data; +struct platform_device emi_nor_device = { + .name = "physmap-flash", + .id = -1, + .dev.platform_data = &emi_norflash_data, +}; + /* plgpio device registeration */ static struct plgpio_platform_data plgpio_plat_data = { .gpio_base = 8, diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c index 1131f9b..04361fc 100644 --- a/arch/arm/mach-spear3xx/spear320_evb.c +++ b/arch/arm/mach-spear3xx/spear320_evb.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,24 @@ #include #include +#define PARTITION(n, off, sz) {.name = n, .offset = off, .size = sz} + +static struct mtd_partition partition_info[] = { + PARTITION("X-loader", 0, 1 * 0x20000), + PARTITION("U-Boot", 0x20000, 3 * 0x20000), + PARTITION("Kernel", 0x80000, 24 * 0x20000), + PARTITION("Root File System", 0x380000, 84 * 0x20000), +}; + +/* emi nor flash resources registeration */ +static struct resource emi_nor_resources[] = { + { + .start = SPEAR310_EMI_MEM_0_BASE, + .end = SPEAR310_EMI_MEM_0_BASE + SPEAR310_EMI_MEM_SIZE - 1, + .flags = IORESOURCE_MEM, + }, +}; + /* padmux devices to enable */ static struct pmx_dev *pmx_devs[] = { /* spear3xx specific devices */ @@ -116,6 +135,11 @@ static void __init spear320_evb_init(void) /* Register slave devices on the I2C buses */ i2c_register_board_devices(); + /* initialize emi related data in emi plat data */ + emi_init_board_info(&emi_nor_device, emi_nor_resources, + ARRAY_SIZE(emi_nor_resources), partition_info, + ARRAY_SIZE(partition_info), EMI_FLASH_WIDTH16); + /* Add Platform Devices */ platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs)); @@ -123,6 +147,9 @@ static void __init spear320_evb_init(void) for (i = 0; i < ARRAY_SIZE(amba_devs); i++) amba_device_register(amba_devs[i], &iomem_resource); + /* Initialize emi regiters */ + emi_init(&emi_nor_device, SPEAR320_EMI_CTRL_BASE, 0, EMI_FLASH_WIDTH16); + spi_init(); }