From patchwork Fri Oct 1 11:55:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Viresh KUMAR X-Patchwork-Id: 66456 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 37E98B70E1 for ; Sat, 2 Oct 2010 03:12:00 +1000 (EST) Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1P1j7i-0000Ly-Ui; Fri, 01 Oct 2010 17:10:19 +0000 Received: from casper.infradead.org ([2001:770:15f::2]) by bombadil.infradead.org with esmtps (Exim 4.72 #1 (Red Hat Linux)) id 1P1ix8-0004Zc-GI; Fri, 01 Oct 2010 16:59:23 +0000 Received: from eu1sys200aog112.obsmtp.com ([207.126.144.133]) by casper.infradead.org with smtps (Exim 4.72 #1 (Red Hat Linux)) id 1P1eFd-00081C-I9; Fri, 01 Oct 2010 11:58:17 +0000 Received: from source ([164.129.1.35]) (using TLSv1) by eu1sys200aob112.postini.com ([207.126.147.11]) with SMTP ID DSNKTKXMxpeY/fj84dXVJnhu9sAtL/mD7o/x@postini.com; Fri, 01 Oct 2010 11:58:09 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 BB0AFC0; Fri, 1 Oct 2010 11:57:48 +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 2F2CD264B; Fri, 1 Oct 2010 11:57:44 +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 CUF00978 (AUTH viresh.kumar@st.com); Fri, 1 Oct 2010 17:27:43 +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 Subject: [PATCH V2 32/69] ST SPEAr: Adding support for SDHCI (SDIO) Date: Fri, 1 Oct 2010 17:25:52 +0530 Message-Id: X-Mailer: git-send-email 1.7.2.2 In-Reply-To: References: In-Reply-To: References: X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20101001_125810_211783_2DA48A3C X-CRM114-Status: GOOD ( 17.45 ) X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.1 on casper.infradead.org summary: Content analysis details: (-4.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [207.126.144.133 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: pratyush.anand@st.com, Viresh Kumar , vipulkumar.samar@st.com, bhupesh.sharma@st.com, armando.visconti@st.com, vipin.kumar@st.com, shiraz.hashim@st.com, rajeev-dlh.kumar@st.com, deepak.sikri@st.com X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Signed-off-by: Viresh Kumar Signed-off-by: Shiraz Hashim --- arch/arm/mach-spear13xx/include/mach/generic.h | 1 + arch/arm/mach-spear13xx/spear1300_evb.c | 1 + arch/arm/mach-spear13xx/spear13xx.c | 34 +++++++++++++- arch/arm/mach-spear3xx/include/mach/generic.h | 13 ++++-- arch/arm/mach-spear3xx/include/mach/irqs.h | 4 +- arch/arm/mach-spear3xx/include/mach/spear300.h | 4 +- arch/arm/mach-spear3xx/include/mach/spear320.h | 6 +- arch/arm/mach-spear3xx/spear300.c | 62 ++++++++++++++++++++---- arch/arm/mach-spear3xx/spear300_evb.c | 18 +++++++- arch/arm/mach-spear3xx/spear320.c | 43 +++++++++++++---- arch/arm/mach-spear3xx/spear320_evb.c | 15 +++++- 11 files changed, 167 insertions(+), 34 deletions(-) diff --git a/arch/arm/mach-spear13xx/include/mach/generic.h b/arch/arm/mach-spear13xx/include/mach/generic.h index 7419e0b..bfd0667 100644 --- a/arch/arm/mach-spear13xx/include/mach/generic.h +++ b/arch/arm/mach-spear13xx/include/mach/generic.h @@ -40,6 +40,7 @@ extern struct platform_device spear13xx_nand_device; extern struct platform_device spear13xx_ohci0_device; extern struct platform_device spear13xx_ohci1_device; extern struct platform_device spear13xx_rtc_device; +extern struct platform_device spear13xx_sdhci_device; extern struct platform_device spear13xx_smi_device; extern struct sys_timer spear13xx_timer; diff --git a/arch/arm/mach-spear13xx/spear1300_evb.c b/arch/arm/mach-spear13xx/spear1300_evb.c index ba46f61..269d9b0 100644 --- a/arch/arm/mach-spear13xx/spear1300_evb.c +++ b/arch/arm/mach-spear13xx/spear1300_evb.c @@ -43,6 +43,7 @@ static struct platform_device *plat_devs[] __initdata = { &spear13xx_ohci0_device, &spear13xx_ohci1_device, &spear13xx_rtc_device, + &spear13xx_sdhci_device, &spear13xx_smi_device, }; diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c index 6455ebb..b058c3b 100644 --- a/arch/arm/mach-spear13xx/spear13xx.c +++ b/arch/arm/mach-spear13xx/spear13xx.c @@ -349,6 +349,16 @@ struct platform_device spear13xx_smi_device = { .resource = smi_resources, }; +static void sdhci_enable(void) +{ + unsigned val = readl(PERIP_CFG); + + /* This function enables SD/MMC interface out of SD/MMC, CF, XD */ + val &= ~(MCIF_SEL_MASK << MCIF_SEL_SHIFT); + val |= SD_MMC_ACTIVE << MCIF_SEL_SHIFT; + writel(val, PERIP_CFG); +} + #ifdef CONFIG_PCIEPORTBUS /* PCIE0 clock always needs to be enabled if any of the three PCIE port * have to be used. So call this function from the board initilization @@ -377,10 +387,32 @@ int enable_pcie0_clk(void) } #endif +/* sdhci (sdio) device declaration */ +static struct resource sdhci_resources[] = { + { + .start = SPEAR13XX_MCIF_SDHCI_BASE, + .end = SPEAR13XX_MCIF_SDHCI_BASE + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_SDHCI, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device spear13xx_sdhci_device = { + .dev = { + .coherent_dma_mask = ~0, + }, + .name = "sdhci", + .id = -1, + .num_resources = ARRAY_SIZE(sdhci_resources), + .resource = sdhci_resources, +}; + /* Do spear13xx familiy common initialization part here */ void __init spear13xx_init(void) { - /* nothing to do for now */ + sdhci_enable(); } /* This will initialize vic */ diff --git a/arch/arm/mach-spear3xx/include/mach/generic.h b/arch/arm/mach-spear3xx/include/mach/generic.h index 04ce8700..9bd9424 100644 --- a/arch/arm/mach-spear3xx/include/mach/generic.h +++ b/arch/arm/mach-spear3xx/include/mach/generic.h @@ -116,6 +116,7 @@ extern struct platform_device nand0_device; extern struct platform_device nand1_device; extern struct platform_device nand2_device; extern struct platform_device nand3_device; +extern struct platform_device sdhci_device; /* pad mux modes */ extern struct pmx_mode nand_mode; @@ -144,12 +145,15 @@ extern struct pmx_dev pmx_telecom_camera; extern struct pmx_dev pmx_telecom_dac; extern struct pmx_dev pmx_telecom_i2s; extern struct pmx_dev pmx_telecom_boot_pins; -extern struct pmx_dev pmx_telecom_sdio_4bit; -extern struct pmx_dev pmx_telecom_sdio_8bit; +extern struct pmx_dev pmx_telecom_sdhci_4bit; +extern struct pmx_dev pmx_telecom_sdhci_8bit; extern struct pmx_dev pmx_gpio1; /* Add spear300 machine function declarations here */ void __init spear300_init(void); +#define SDHCI_MEM_ENB 0x1 +#define I2S_MEM_ENB 0x2 +void sdhci_i2s_mem_enable(u8 mask); /* Add misc structure declarations here */ extern struct clcd_board clcd_plat_data; @@ -182,6 +186,7 @@ extern struct platform_device i2c1_device; extern struct platform_device nand_device; extern struct platform_device plgpio_device; extern struct platform_device pwm_device; +extern struct platform_device sdhci_device; /* pad mux modes */ extern struct pmx_mode auto_net_smii_mode; @@ -194,14 +199,14 @@ extern struct pmx_dev pmx_clcd; extern struct pmx_dev pmx_emi; extern struct pmx_dev pmx_fsmc; extern struct pmx_dev pmx_spp; -extern struct pmx_dev pmx_sdio; +extern struct pmx_dev pmx_sdhci; extern struct pmx_dev pmx_i2s; extern struct pmx_dev pmx_uart1; extern struct pmx_dev pmx_uart1_modem; extern struct pmx_dev pmx_uart2; extern struct pmx_dev pmx_touchscreen; extern struct pmx_dev pmx_can; -extern struct pmx_dev pmx_sdio_led; +extern struct pmx_dev pmx_sdhci_led; extern struct pmx_dev pmx_pwm0; extern struct pmx_dev pmx_pwm1; extern struct pmx_dev pmx_pwm2; diff --git a/arch/arm/mach-spear3xx/include/mach/irqs.h b/arch/arm/mach-spear3xx/include/mach/irqs.h index 5ad7574..df0c1f3 100644 --- a/arch/arm/mach-spear3xx/include/mach/irqs.h +++ b/arch/arm/mach-spear3xx/include/mach/irqs.h @@ -69,7 +69,7 @@ #define IRQ_CLCD IRQ_GEN_RAS_3 /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */ -#define IRQ_SDIO IRQ_INTRCOMM_RAS_ARM +#define IRQ_SDHCI IRQ_INTRCOMM_RAS_ARM /* GPIO pins virtual irqs */ #define SPEAR_GPIO_INT_BASE (VIRQ_START + 9) @@ -115,7 +115,7 @@ #define VIRQ_SPP (VIRQ_START + 2) /* IRQs sharing IRQ_GEN_RAS_2 */ -#define IRQ_SDIO IRQ_GEN_RAS_2 +#define IRQ_SDHCI IRQ_GEN_RAS_2 /* IRQs sharing IRQ_GEN_RAS_3 */ #define VIRQ_PLGPIO (VIRQ_START + 3) diff --git a/arch/arm/mach-spear3xx/include/mach/spear300.h b/arch/arm/mach-spear3xx/include/mach/spear300.h index ccaa765..1059d5a 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear300.h +++ b/arch/arm/mach-spear3xx/include/mach/spear300.h @@ -39,8 +39,8 @@ #define SPEAR300_CLCD_BASE 0x60000000 #define SPEAR300_CLCD_SIZE 0x10000000 -#define SPEAR300_SDIO_BASE 0x70000000 -#define SPEAR300_SDIO_SIZE 0x10000000 +#define SPEAR300_SDHCI_BASE 0x70000000 +#define SPEAR300_SDHCI_SIZE 0x10000000 #define SPEAR300_NAND_0_BASE 0x80000000 #define SPEAR300_NAND_0_SIZE 0x04000000 diff --git a/arch/arm/mach-spear3xx/include/mach/spear320.h b/arch/arm/mach-spear3xx/include/mach/spear320.h index aa6727c..89f5bfb 100644 --- a/arch/arm/mach-spear3xx/include/mach/spear320.h +++ b/arch/arm/mach-spear3xx/include/mach/spear320.h @@ -28,8 +28,8 @@ #define SPEAR320_I2S_BASE 0x60000000 #define SPEAR320_I2S_SIZE 0x10000000 -#define SPEAR320_SDIO_BASE 0x70000000 -#define SPEAR320_SDIO_SIZE 0x10000000 +#define SPEAR320_SDHCI_BASE 0x70000000 +#define SPEAR320_SDHCI_SIZE 0x10000000 #define SPEAR320_CLCD_BASE 0x90000000 #define SPEAR320_CLCD_SIZE 0x10000000 @@ -77,7 +77,7 @@ #define EMI_IRQ_MASK (1 << 7) #define CLCD_IRQ_MASK (1 << 8) #define SPP_IRQ_MASK (1 << 9) -#define SDIO_IRQ_MASK (1 << 10) +#define SDHCI_IRQ_MASK (1 << 10) #define CAN_U_IRQ_MASK (1 << 11) #define CAN_L_IRQ_MASK (1 << 12) #define UART1_IRQ_MASK (1 << 13) diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index c213614..fd83f53 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -311,7 +311,7 @@ struct pmx_dev pmx_telecom_boot_pins = { .enb_on_reset = 1, }; -struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = { +struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = { { .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | @@ -324,14 +324,14 @@ struct pmx_dev_mode pmx_telecom_sdio_4bit_modes[] = { }, }; -struct pmx_dev pmx_telecom_sdio_4bit = { - .name = "telecom_sdio_4bit", - .modes = pmx_telecom_sdio_4bit_modes, - .mode_count = ARRAY_SIZE(pmx_telecom_sdio_4bit_modes), +struct pmx_dev pmx_telecom_sdhci_4bit = { + .name = "telecom_sdhci_4bit", + .modes = pmx_telecom_sdhci_4bit_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_sdhci_4bit_modes), .enb_on_reset = 1, }; -struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = { +struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = { { .ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE | @@ -343,10 +343,10 @@ struct pmx_dev_mode pmx_telecom_sdio_8bit_modes[] = { }, }; -struct pmx_dev pmx_telecom_sdio_8bit = { - .name = "telecom_sdio_8bit", - .modes = pmx_telecom_sdio_8bit_modes, - .mode_count = ARRAY_SIZE(pmx_telecom_sdio_8bit_modes), +struct pmx_dev pmx_telecom_sdhci_8bit = { + .name = "telecom_sdhci_8bit", + .modes = pmx_telecom_sdhci_8bit_modes, + .mode_count = ARRAY_SIZE(pmx_telecom_sdhci_8bit_modes), .enb_on_reset = 1, }; @@ -524,6 +524,28 @@ struct platform_device nand3_device = { .dev.platform_data = &nand3_platform_data, }; +/* sdhci (sdio) device declaration */ +static struct resource sdhci_resources[] = { + { + .start = SPEAR300_SDHCI_BASE, + .end = SPEAR300_SDHCI_BASE + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_SDHCI, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device sdhci_device = { + .dev = { + .coherent_dma_mask = ~0, + }, + .name = "sdhci", + .id = -1, + .num_resources = ARRAY_SIZE(sdhci_resources), + .resource = sdhci_resources, +}; + /* spear3xx shared irq */ struct shirq_dev_config shirq_ras1_config[] = { { @@ -577,6 +599,26 @@ struct spear_shirq shirq_ras1 = { }, }; +/* Function handling sdhci and i2s memory sharing */ +#define SDHCI_MEM_SELECT 0x20000000 +void sdhci_i2s_mem_enable(u8 mask) +{ + u32 val; + void __iomem *base = ioremap(SPEAR300_SOC_CONFIG_BASE, + SPEAR300_SOC_CONFIG_SIZE); + if (!base) { + pr_debug("sdhci_i2s_enb: ioremap fail\n"); + return; + } + + val = readl(base + MODE_CONFIG_REG); + if (mask == SDHCI_MEM_ENB) + val |= SDHCI_MEM_SELECT; + else + val &= ~SDHCI_MEM_SELECT; + writel(val, base + MODE_CONFIG_REG); +} + /* spear300 routines */ void __init spear300_init(void) { diff --git a/arch/arm/mach-spear3xx/spear300_evb.c b/arch/arm/mach-spear3xx/spear300_evb.c index c702cc3..2bcb55f 100644 --- a/arch/arm/mach-spear3xx/spear300_evb.c +++ b/arch/arm/mach-spear3xx/spear300_evb.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ static struct pmx_dev *pmx_devs[] = { /* spear300 specific devices */ &pmx_fsmc_2_chips, &pmx_clcd, - &pmx_telecom_sdio_4bit, + &pmx_telecom_sdhci_4bit, &pmx_gpio1, }; @@ -65,6 +66,15 @@ static struct platform_device *plat_devs[] __initdata = { /* spear300 specific devices */ &kbd_device, + &sdhci_device, +}; + +/* sdhci board specific information */ +static struct sdhci_plat_data sdhci_plat_data = { + .card_power_gpio = RAS_GPIO_2, + .power_active_high = 0, + .power_always_enb = 0, + .card_int_gpio = RAS_GPIO_0, }; /* keyboard specific platform data */ @@ -115,6 +125,12 @@ static void __init spear300_evb_init(void) fsmc_nand_set_plat_data(&nand0_device, NULL, 0, NAND_SKIP_BBTSCAN, FSMC_NAND_BW8); + /* set sdhci device platform data */ + sdhci_set_plat_data(&sdhci_device, &sdhci_plat_data); + + /* Enable sdhci memory */ + sdhci_i2s_mem_enable(SDHCI_MEM_ENB); + /* call spear300 machine init function */ spear300_init(); diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index f87cc97..e14e201 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include #include @@ -113,7 +115,7 @@ struct pmx_dev pmx_spp = { .enb_on_reset = 1, }; -struct pmx_dev_mode pmx_sdio_modes[] = { +struct pmx_dev_mode pmx_sdhci_modes[] = { { .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | SMALL_PRINTERS_MODE, @@ -121,10 +123,10 @@ struct pmx_dev_mode pmx_sdio_modes[] = { }, }; -struct pmx_dev pmx_sdio = { - .name = "sdio", - .modes = pmx_sdio_modes, - .mode_count = ARRAY_SIZE(pmx_sdio_modes), +struct pmx_dev pmx_sdhci = { + .name = "sdhci", + .modes = pmx_sdhci_modes, + .mode_count = ARRAY_SIZE(pmx_sdhci_modes), .enb_on_reset = 1, }; @@ -218,17 +220,17 @@ struct pmx_dev pmx_can = { .enb_on_reset = 1, }; -struct pmx_dev_mode pmx_sdio_led_modes[] = { +struct pmx_dev_mode pmx_sdhci_led_modes[] = { { .ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE, .mask = PMX_SSP_CS_MASK, }, }; -struct pmx_dev pmx_sdio_led = { - .name = "sdio_led", - .modes = pmx_sdio_led_modes, - .mode_count = ARRAY_SIZE(pmx_sdio_led_modes), +struct pmx_dev pmx_sdhci_led = { + .name = "sdhci_led", + .modes = pmx_sdhci_led_modes, + .mode_count = ARRAY_SIZE(pmx_sdhci_led_modes), .enb_on_reset = 1, }; @@ -536,6 +538,27 @@ struct platform_device pwm_device = { .resource = pwm_resources, }; +/* sdhci (sdio) device registeration */ +static struct resource sdhci_resources[] = { + { + .start = SPEAR320_SDHCI_BASE, + .end = SPEAR320_SDHCI_BASE + SZ_256 - 1, + .flags = IORESOURCE_MEM, + }, { + .start = IRQ_SDHCI, + .flags = IORESOURCE_IRQ, + } +}; + +struct platform_device sdhci_device = { + .dev = { + .coherent_dma_mask = ~0, + }, + .name = "sdhci", + .id = -1, + .num_resources = ARRAY_SIZE(sdhci_resources), + .resource = sdhci_resources, +}; /* spear3xx shared irq */ struct shirq_dev_config shirq_ras1_config[] = { diff --git a/arch/arm/mach-spear3xx/spear320_evb.c b/arch/arm/mach-spear3xx/spear320_evb.c index dcca84e..2142ad9 100644 --- a/arch/arm/mach-spear3xx/spear320_evb.c +++ b/arch/arm/mach-spear3xx/spear320_evb.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,7 @@ static struct pmx_dev *pmx_devs[] = { /* spear320 specific devices */ &pmx_fsmc, - &pmx_sdio, + &pmx_sdhci, &pmx_i2s, &pmx_uart1, &pmx_uart2, @@ -69,6 +70,15 @@ static struct platform_device *plat_devs[] __initdata = { &i2c1_device, &plgpio_device, &pwm_device, + &sdhci_device, +}; + +/* sdhci board specific information */ +static struct sdhci_plat_data sdhci_plat_data = { + .card_power_gpio = PLGPIO_61, + .power_active_high = 0, + .power_always_enb = 1, + .card_int_gpio = -1, }; static struct spi_board_info __initdata spi_board_info[] = { @@ -83,6 +93,9 @@ static void __init spear320_evb_init(void) { unsigned int i; + /* set sdhci device platform data */ + sdhci_set_plat_data(&sdhci_device, &sdhci_plat_data); + /* padmux initialization, must be done before spear320_init */ pmx_driver.mode = &auto_net_mii_mode; pmx_driver.devs = pmx_devs;