Hi Eric,

Thanks for the links.  I was following the patches to add the babbage
registration specific bits (see patch below).  I can see following mmc
related boot log showing the card is initialized and recognized.

sdhci: Copyright(c) Pierre Ossman
mmc0: SDHCI controller on platform [sdhci-esdhc-imx.0] using DMA
mmc1: SDHCI controller on platform [sdhci-esdhc-imx.1] using DMA
......
Waiting for root device /dev/mmcblk0p3...
mmc0: new high speed SD card at address fb74
blk_queue_max_hw_sectors: set to minimum 8
mmcblk0: mmc0:fb74 SD02G 1.83 GiB
 mmcblk0: p1 p2 p3
......

But when I try to login console, it gives a bunch of error messages like below.

mmcblk0: error -110 transferring data, sector 1737392, nr 2, card status 0xe00
end_request: I/O error, dev mmcblk0, sector 1737392
mmcblk0: error -84 transferring data, sector 1737394, nr 8, card status 0x900
end_request: I/O error, dev mmcblk0, sector 1737394
mmcblk0: error -84 transferring data, sector 1737402, nr 8, card status 0x900
end_request: I/O error, dev mmcblk0, sector 1737402
......

As you have tested Wolfram's bits on i.MX51 (eukrea?), probably my
babbage registration bit is causing problem.  Could you please help
have a review to see if anything incorrect?


On Mon, Oct 18, 2010 at 1:04 AM, Eric Bénard <e...@eukrea.com> wrote:
> Hi Shawn,
>
> Le 17/10/2010 17:27, Shawn Guo a écrit :
>>
>> Thanks for the merging.  But the bits for babbage mmc resources and
>> driver registration are missing.  I'm trying to add them for getting a
>> bootable mmc linaro image, but running into some problem right now.
>> Will continue digging tomorrow.
>>
> you can find a working example here :
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-October/028846.html
>
> before, you will need this patch serie :
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-October/028826.html
> and this patch :
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-October/028855.html
>
> Eric
>


>From 511b5ec7aaeb8c15b6613b9ff68e967998e6c37a Mon Sep 17 00:00:00 2001
From: Shawn Guo <shawn....@gmail.com>
Date: Sun, 17 Oct 2010 22:31:34 +0800
Subject: [PATCH] Add resource and registeration for wsa mmc driver

Signed-off-by: Shawn Guo <shawn....@gmail.com>
---
 arch/arm/mach-mx5/Kconfig                       |    1 +
 arch/arm/mach-mx5/board-mx51_babbage.c          |   20 ++
 arch/arm/mach-mx5/clock-mx51.c                  |  268 +++++++++++++++--------
 arch/arm/mach-mx5/devices-imx51.h               |   17 ++
 arch/arm/plat-mxc/devices/Kconfig               |    3 +
 arch/arm/plat-mxc/devices/Makefile              |    1 +
 arch/arm/plat-mxc/devices/platform-esdhc.c      |   71 ++++++
 arch/arm/plat-mxc/include/mach/devices-common.h |   10 +
 arch/arm/plat-mxc/include/mach/esdhc.h          |   16 ++
 arch/arm/plat-mxc/include/mach/iomux-mx51.h     |   39 +++-
 arch/arm/plat-mxc/include/mach/mx51.h           |   16 +-
 11 files changed, 351 insertions(+), 111 deletions(-)
 create mode 100644 arch/arm/mach-mx5/devices-imx51.h
 create mode 100644 arch/arm/plat-mxc/devices/platform-esdhc.c
 create mode 100644 arch/arm/plat-mxc/include/mach/esdhc.h

diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 0848db5..a263666 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -10,6 +10,7 @@ comment "MX5 platforms:"

 config MACH_MX51_BABBAGE
        bool "Support MX51 BABBAGE platforms"
+       select IMX_HAVE_PLATFORM_ESDHC
        help
          Include support for MX51 Babbage platform, also known as MX51EVK in
          u-boot. This includes specific configurations for the board and its
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c
b/arch/arm/mach-mx5/board-mx51_babbage.c
index 6e384d9..476bfe4 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -31,6 +31,7 @@
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>

+#include "devices-imx51.h"
 #include "devices.h"

 #define BABBAGE_USB_HUB_RESET  (0*32 + 7)      /* GPIO_1_7 */
@@ -93,6 +94,22 @@ static struct pad_desc mx51babbage_pads[] = {

        /* USB HUB reset line*/
        MX51_PAD_GPIO_1_7__GPIO_1_7,
+
+       /* SD 1 */
+       MX51_PAD_SD1_CMD__SD1_CMD,
+       MX51_PAD_SD1_CLK__SD1_CLK,
+       MX51_PAD_SD1_DATA0__SD1_DATA0,
+       MX51_PAD_SD1_DATA1__SD1_DATA1,
+       MX51_PAD_SD1_DATA2__SD1_DATA2,
+       MX51_PAD_SD1_DATA3__SD1_DATA3,
+
+       /* SD 2 */
+       MX51_PAD_SD2_CMD__SD2_CMD,
+       MX51_PAD_SD2_CLK__SD2_CLK,
+       MX51_PAD_SD2_DATA0__SD2_DATA0,
+       MX51_PAD_SD2_DATA1__SD2_DATA1,
+       MX51_PAD_SD2_DATA2__SD2_DATA2,
+       MX51_PAD_SD2_DATA3__SD2_DATA3,
 };

 /* Serial ports */
@@ -268,6 +285,9 @@ static void __init mxc_board_init(void)
        /* setback USBH1_STP to be function */
        mxc_iomux_v3_setup_pad(&usbh1stp);
        babbage_usbhub_reset();
+
+       imx51_add_esdhc(0, NULL);
+       imx51_add_esdhc(1, NULL);
 }

 static void __init mx51_babbage_timer_init(void)
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
index 57c10a9..c879a91 100644
--- a/arch/arm/mach-mx5/clock-mx51.c
+++ b/arch/arm/mach-mx5/clock-mx51.c
@@ -41,34 +41,66 @@ static struct clk usboh3_clk;

 #define MAX_DPLL_WAIT_TRIES    1000 /* 1000 * udelay(1) = 1ms */

-static int _clk_ccgr_enable(struct clk *clk)
+/* calculate best pre and post dividers to get the required divider */
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post,
+       u32 max_pre, u32 max_post)
+{
+       if (div >= max_pre * max_post) {
+               *pre = max_pre;
+               *post = max_post;
+       } else if (div >= max_pre) {
+               u32 min_pre, temp_pre, old_err, err;
+               min_pre = DIV_ROUND_UP(div, max_post);
+               old_err = max_pre;
+               for (temp_pre = max_pre; temp_pre >= min_pre; temp_pre--) {
+                       err = div % temp_pre;
+                       if (err == 0) {
+                               *pre = temp_pre;
+                               break;
+                       }
+                       err = temp_pre - err;
+                       if (err < old_err) {
+                               old_err = err;
+                               *pre = temp_pre;
+                       }
+               }
+               *post = DIV_ROUND_UP(div, *pre);
+       } else {
+               *pre = div;
+               *post = 1;
+       }
+}
+
+static void _clk_ccgr_setclk(struct clk *clk, unsigned mode)
 {
-       u32 reg;
+       u32 reg = __raw_readl(clk->enable_reg);
+
+       reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+       reg |= mode << clk->enable_shift;

-       reg = __raw_readl(clk->enable_reg);
-       reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
        __raw_writel(reg, clk->enable_reg);
+}

+static int _clk_ccgr_enable(struct clk *clk)
+{
+       _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_ON);
        return 0;
 }

 static void _clk_ccgr_disable(struct clk *clk)
 {
-       u32 reg;
-       reg = __raw_readl(clk->enable_reg);
-       reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
-       __raw_writel(reg, clk->enable_reg);
+       _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_OFF);
+}

+static int _clk_ccgr_enable_inrun(struct clk *clk)
+{
+       _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
+       return 0;
 }

 static void _clk_ccgr_disable_inwait(struct clk *clk)
 {
-       u32 reg;
-
-       reg = __raw_readl(clk->enable_reg);
-       reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
-       reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
-       __raw_writel(reg, clk->enable_reg);
+       _clk_ccgr_setclk(clk, MXC_CCM_CCGRx_MOD_IDLE);
 }

 /*
@@ -542,64 +574,6 @@ static int _clk_ipg_per_set_parent(struct clk
*clk, struct clk *parent)
        return 0;
 }

-static unsigned long clk_uart_get_rate(struct clk *clk)
-{
-       u32 reg, prediv, podf;
-       unsigned long parent_rate;
-
-       parent_rate = clk_get_rate(clk->parent);
-
-       reg = __raw_readl(MXC_CCM_CSCDR1);
-       prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
-                 MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
-       podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
-               MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
-
-       return parent_rate / (prediv * podf);
-}
-
-static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
-{
-       u32 reg, mux;
-
-       mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
-                      &lp_apm_clk);
-       reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
-       reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
-       __raw_writel(reg, MXC_CCM_CSCMR1);
-
-       return 0;
-}
-
-static unsigned long clk_usboh3_get_rate(struct clk *clk)
-{
-       u32 reg, prediv, podf;
-       unsigned long parent_rate;
-
-       parent_rate = clk_get_rate(clk->parent);
-
-       reg = __raw_readl(MXC_CCM_CSCDR1);
-       prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >>
-                 MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1;
-       podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >>
-               MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1;
-
-       return parent_rate / (prediv * podf);
-}
-
-static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent)
-{
-       u32 reg, mux;
-
-       mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
-                      &lp_apm_clk);
-       reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK;
-       reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET;
-       __raw_writel(reg, MXC_CCM_CSCMR1);
-
-       return 0;
-}
-
 static unsigned long get_high_reference_clock_rate(struct clk *clk)
 {
        return external_high_reference;
@@ -715,18 +689,6 @@ static struct clk ipg_perclk = {
        .set_parent = _clk_ipg_per_set_parent,
 };

-static struct clk uart_root_clk = {
-       .parent = &pll2_sw_clk,
-       .get_rate = clk_uart_get_rate,
-       .set_parent = _clk_uart_set_parent,
-};
-
-static struct clk usboh3_clk = {
-       .parent = &pll2_sw_clk,
-       .get_rate = clk_usboh3_get_rate,
-       .set_parent = _clk_usboh3_set_parent,
-};
-
 static struct clk ahb_max_clk = {
        .parent = &ahb_clk,
        .enable_reg = MXC_CCM_CCGR0,
@@ -762,21 +724,125 @@ static struct clk kpp_clk = {
        .id = 0,
 };

-#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s)    \
+#define DEFINE_CLOCK_MAX(name, i, er, es, pfx, p, s)   \
        static struct clk name = {                      \
                .id             = i,                    \
                .enable_reg     = er,                   \
                .enable_shift   = es,                   \
-               .get_rate       = gr,                   \
-               .set_rate       = sr,                   \
-               .enable         = _clk_ccgr_enable,     \
-               .disable        = _clk_ccgr_disable,    \
+               .get_rate       = pfx##_get_rate,       \
+               .set_rate       = pfx##_set_rate,       \
+               .set_parent     = pfx##_set_parent,     \
+               .enable         = _clk_max_enable,      \
+               .disable        = _clk_max_disable,     \
                .parent         = p,                    \
                .secondary      = s,                    \
        }

-/* DEFINE_CLOCK(name, id, enable_reg, enable_shift,
-   get_rate, set_rate, parent, secondary); */
+#define CLK_GET_RATE(name, nr, bitsname)                               \
+static unsigned long clk_##name##_get_rate(struct clk *clk)            \
+{                                                                      \
+       u32 reg, pred, podf;                                            \
+                                                                       \
+       reg = __raw_readl(MXC_CCM_CSCDR##nr);                           \
+       pred = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK)   \
+               >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET;    \
+       podf = (reg & MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK)   \
+               >> MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET;    \
+                                                                       \
+       return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent),             \
+                       (pred + 1) * (podf + 1));                       \
+}
+
+#define CLK_SET_PARENT(name, nr, bitsname)                             \
+static int clk_##name##_set_parent(struct clk *clk, struct clk *parent)        
\
+{                                                                      \
+       u32 reg, mux;                                                   \
+                                                                       \
+       mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,              \
+                       &pll3_sw_clk, &lp_apm_clk);                     \
+       reg = __raw_readl(MXC_CCM_CSCMR##nr) &                          \
+               ~MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_MASK;         \
+       reg |= mux << MXC_CCM_CSCMR##nr##_##bitsname##_CLK_SEL_OFFSET;  \
+       __raw_writel(reg, MXC_CCM_CSCMR##nr);                           \
+                                                                       \
+       return 0;                                                       \
+}
+
+#define CLK_SET_RATE(name, nr, bitsname)                               \
+static int clk_##name##_set_rate(struct clk *clk, unsigned long rate)  \
+{                                                                      \
+       u32 reg, div, parent_rate;                                      \
+       u32 pre = 0, post = 0;                                          \
+                                                                       \
+       parent_rate = clk_get_rate(clk->parent);                        \
+       div = parent_rate / rate;                                       \
+                                                                       \
+       if ((parent_rate / div) != rate)                                \
+               return -EINVAL;                                         \
+                                                                       \
+       __calc_pre_post_dividers(div, &pre, &post,                      \
+               (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK >>      \
+               MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET) + 1,  \
+               (MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK >>      \
+               MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET) + 1);\
+                                                                       \
+       /* Set sdhc1 clock divider */                                   \
+       reg = __raw_readl(MXC_CCM_CSCDR##nr) &                          \
+               ~(MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_MASK        \
+               | MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_MASK);      \
+       reg |= (post - 1) <<                                            \
+               MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PODF_OFFSET;       \
+       reg |= (pre - 1) <<                                             \
+               MXC_CCM_CSCDR##nr##_##bitsname##_CLK_PRED_OFFSET;       \
+       __raw_writel(reg, MXC_CCM_CSCDR##nr);                           \
+                                                                       \
+       return 0;                                                       \
+}
+
+/* UART */
+CLK_GET_RATE(uart, 1, UART)
+CLK_SET_PARENT(uart, 1, UART)
+
+static struct clk uart_root_clk = {
+       .parent = &pll2_sw_clk,
+       .get_rate = clk_uart_get_rate,
+       .set_parent = clk_uart_set_parent,
+};
+
+/* USBOH3 */
+CLK_GET_RATE(usboh3, 1, USBOH3)
+CLK_SET_PARENT(usboh3, 1, USBOH3)
+
+static struct clk usboh3_clk = {
+       .parent = &pll2_sw_clk,
+       .get_rate = clk_usboh3_get_rate,
+       .set_parent = clk_usboh3_set_parent,
+};
+
+/* eSDHC */
+CLK_GET_RATE(esdhc1, 1, ESDHC1_MSHC1)
+CLK_SET_PARENT(esdhc1, 1, ESDHC1_MSHC1)
+CLK_SET_RATE(esdhc1, 1, ESDHC1_MSHC1)
+
+CLK_GET_RATE(esdhc2, 1, ESDHC2_MSHC2)
+CLK_SET_PARENT(esdhc2, 1, ESDHC2_MSHC2)
+CLK_SET_RATE(esdhc2, 1, ESDHC2_MSHC2)
+
+#define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s)         \
+       static struct clk name = {                                      \
+               .id             = i,                                    \
+               .enable_reg     = er,                                   \
+               .enable_shift   = es,                                   \
+               .get_rate       = gr,                                   \
+               .set_rate       = sr,                                   \
+               .enable         = e,                                    \
+               .disable        = d,                                    \
+               .parent         = p,                                    \
+               .secondary      = s,                                    \
+       }
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s)                    \
+       DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, _clk_ccgr_enable,
_clk_ccgr_disable, p, s)

 /* Shared peripheral bus arbiter */
 DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
@@ -814,6 +880,16 @@ DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1,
MXC_CCM_CCGRx_CG11_OFFSET,
 DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
        NULL,  NULL, &ipg_clk, NULL);

+/* eSDHC */
+DEFINE_CLOCK_FULL(esdhc1_ipg_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG0_OFFSET,
+       NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+DEFINE_CLOCK_MAX(esdhc1_clk, 0, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG1_OFFSET,
+       clk_esdhc1, &pll2_sw_clk, &esdhc1_ipg_clk);
+DEFINE_CLOCK_FULL(esdhc2_ipg_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG2_OFFSET,
+       NULL,  NULL, _clk_max_enable, _clk_max_disable, &ipg_clk, NULL);
+DEFINE_CLOCK_MAX(esdhc2_clk, 1, MXC_CCM_CCGR3, MXC_CCM_CCGRx_CG3_OFFSET,
+       clk_esdhc2, &pll2_sw_clk, &esdhc2_ipg_clk);
+
 #define _REGISTER_CLOCK(d, n, c) \
        { \
                .dev_id = d, \
@@ -837,6 +913,8 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
        _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
        _REGISTER_CLOCK("imx-keypad.0", NULL, kpp_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+       _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
 };

 static void clk_tree_init(void)
@@ -880,6 +958,14 @@ int __init mx51_clocks_init(unsigned long ckil,
unsigned long osc,
        /* set the usboh3_clk parent to pll2_sw_clk */
        clk_set_parent(&usboh3_clk, &pll2_sw_clk);

+       /* Set SDHC parents to be PLL2 */
+       clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
+       clk_set_parent(&esdhc2_clk, &pll2_sw_clk);
+
+       /* set SDHC root clock as 166.25MHZ*/
+       clk_set_rate(&esdhc1_clk, 166250000);
+       clk_set_rate(&esdhc2_clk, 166250000);
+
        /* System timer */
        mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
                MX51_MXC_INT_GPT);
diff --git a/arch/arm/mach-mx5/devices-imx51.h
b/arch/arm/mach-mx5/devices-imx51.h
new file mode 100644
index 0000000..1c43940
--- /dev/null
+++ b/arch/arm/mach-mx5/devices-imx51.h
@@ -0,0 +1,17 @@
+/*

+ * Copyright (C) 2010 Jason Wang <jason77.wang at gmail.com>

+ *

+ * based on mach-mx3/devices-imx35.h which is

+ * Copyright (C) 2010 Pengutronix

+ * Uwe Kleine-Koenig <u.kleine-koenig at pengutronix.de>

+ *

+ * This program is free software; you can redistribute it and/or
modify it under

+ * the terms of the GNU General Public License version 2 as published by the

+ * Free Software Foundation.

+ */

+#include <mach/mx51.h>

+#include <mach/devices-common.h>

+

+extern const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst;

+#define imx51_add_esdhc(id, pdata)     \

+       imx_add_esdhc(&imx51_esdhc_data[id], pdata)

diff --git a/arch/arm/plat-mxc/devices/Kconfig
b/arch/arm/plat-mxc/devices/Kconfig
index 9ab784b..4730d2c 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -13,3 +13,6 @@ config IMX_HAVE_PLATFORM_MXC_NAND

 config IMX_HAVE_PLATFORM_SPI_IMX
        bool
+
+config IMX_HAVE_PLATFORM_ESDHC
+       bool
diff --git a/arch/arm/plat-mxc/devices/Makefile
b/arch/arm/plat-mxc/devices/Makefile
index 347da51..81aa17e 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) +=  platform-spi_imx.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
diff --git a/arch/arm/plat-mxc/devices/platform-esdhc.c
b/arch/arm/plat-mxc/devices/platform-esdhc.c
new file mode 100644
index 0000000..668050b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-esdhc.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang at pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+#include <mach/esdhc.h>
+
+#define imx_esdhc_imx_data_entry_single(soc, _id, hwid) \
+       {                                                               \
+               .id = _id,                                              \
+               .iobase = soc ## _ESDHC ## hwid ## _BASE_ADDR,  \
+               .irq = soc ## _INT_ESDHC ## hwid,                       \
+       }
+
+#define imx_esdhc_imx_data_entry(soc, id, hwid)        \
+       [id] = imx_esdhc_imx_data_entry_single(soc, id, hwid)
+
+#ifdef CONFIG_ARCH_MX25
+const struct imx_esdhc_imx_data imx25_esdhc_data[] __initconst = {
+#define imx25_esdhc_data_entry(_id, _hwid)                             \
+       imx_esdhc_imx_data_entry(MX25, _id, _hwid)
+       imx25_esdhc_data_entry(0, 1),
+       imx25_esdhc_data_entry(1, 2),
+};
+#endif /* ifdef CONFIG_ARCH_MX25 */
+
+#ifdef CONFIG_ARCH_MX35
+const struct imx_esdhc_imx_data imx35_esdhc_data[] __initconst = {
+#define imx35_esdhc_data_entry(_id, _hwid)                           \
+       imx_esdhc_imx_data_entry(MX35, _id, _hwid)
+       imx35_esdhc_data_entry(0, 1),
+       imx35_esdhc_data_entry(1, 2),
+       imx35_esdhc_data_entry(2, 3),
+};
+#endif /* ifdef CONFIG_ARCH_MX35 */
+
+#ifdef CONFIG_ARCH_MX51
+const struct imx_esdhc_imx_data imx51_esdhc_data[] __initconst = {
+#define imx51_esdhc_data_entry(_id, _hwid)                             \
+       imx_esdhc_imx_data_entry(MX51, _id, _hwid)
+       imx51_esdhc_data_entry(0, 1),
+       imx51_esdhc_data_entry(1, 2),
+       imx51_esdhc_data_entry(2, 3),
+       imx51_esdhc_data_entry(3, 4),
+};
+#endif /* ifdef CONFIG_ARCH_MX51 */
+
+struct platform_device *__init imx_add_esdhc(
+               const struct imx_esdhc_imx_data *data,
+               const struct esdhc_platform_data *pdata)
+{
+       struct resource res[] = {
+               {
+                       .start = data->iobase,
+                       .end = data->iobase + SZ_16K - 1,
+                       .flags = IORESOURCE_MEM,
+               }, {
+                       .start = data->irq,
+                       .end = data->irq,
+                       .flags = IORESOURCE_IRQ,
+               },
+       };
+
+       return imx_add_platform_device("sdhci-esdhc-imx", data->id, res,
+                       ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h
b/arch/arm/plat-mxc/include/mach/devices-common.h
index c5f68c5..af7a232 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -58,3 +58,13 @@ struct platform_device *__init
imx_add_mxc_nand_v21(resource_size_t iobase,
 struct platform_device *__init imx_add_spi_imx(int id,
                resource_size_t iobase, resource_size_t iosize, int irq,
                const struct spi_imx_master *pdata);
+
+#include <mach/esdhc.h>
+struct imx_esdhc_imx_data {
+       int id;
+       resource_size_t iobase;
+       resource_size_t irq;
+};
+struct platform_device *__init imx_add_esdhc(
+               const struct imx_esdhc_imx_data *data,
+               const struct esdhc_platform_data *pdata);
diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h
b/arch/arm/plat-mxc/include/mach/esdhc.h
new file mode 100644
index 0000000..0724bcd
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/esdhc.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2010 Wolfram Sang <w.sang at pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2
+ * of the License.
+ */
+
+#ifndef __ASM_ARCH_IMX_ESDHC_H
+#define __ASM_ARCH_IMX_ESDHC_H
+
+struct esdhc_platform_data {
+       unsigned int wp_gpio;   /* write protect pin */
+};
+#endif /* __ASM_ARCH_IMX_ESDHC_H */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
index 21bfa46..935f790 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -45,6 +45,9 @@ typedef enum iomux_config {
                                PAD_CTL_PKE | PAD_CTL_HYS)
 #define MX51_GPIO_PAD_CTRL             (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \
                                PAD_CTL_SRE_FAST)
+#define MX51_SDHCI_PAD_CTRL    (PAD_CTL_DSE_HIGH | PAD_CTL_PUS_47K_UP | \
+                               PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_SRE_FAST | \
+                               PAD_CTL_DVS)

 /*
  * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
@@ -294,20 +297,32 @@ typedef enum iomux_config {
 #define MX51_PAD_DISP2_DAT13__DISP2_DAT13       IOMUX_PAD(0x790,
0x388, 0, 0x0,   0, NO_PAD_CTRL)
 #define MX51_PAD_DISP2_DAT14__DISP2_DAT14       IOMUX_PAD(0x794,
0x38C, 0, 0x0,   0, NO_PAD_CTRL)
 #define MX51_PAD_DISP2_DAT15__DISP2_DAT15       IOMUX_PAD(0x798,
0x390, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_CMD__SD1_CMD               IOMUX_PAD(0x79C,
0x394, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_CLK__SD1_CLK               IOMUX_PAD(0x7A0,
0x398, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA0__SD1_DATA0           IOMUX_PAD(0x7A4,
0x39C, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA1__SD1_DATA1           IOMUX_PAD(0x7A8,
0x3A0, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA2__SD1_DATA2           IOMUX_PAD(0x7AC,
0x3A4, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA3__SD1_DATA3           IOMUX_PAD(0x7B0,
0x3A8, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CMD__SD1_CMD              IOMUX_PAD(0x79C, 0x394,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_CLK__SD1_CLK              IOMUX_PAD(0x7A0, 0x398,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL | 
PAD_CTL_HYS)
+#define MX51_PAD_SD1_DATA0__SD1_DATA0          IOMUX_PAD(0x7A4, 0x39C,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_DATA1__SD1_DATA1          IOMUX_PAD(0x7A8, 0x3A0,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_DATA2__SD1_DATA2          IOMUX_PAD(0x7AC, 0x3A4,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD1_DATA3__SD1_DATA3          IOMUX_PAD(0x7B0, 0x3A8,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
 #define MX51_PAD_GPIO_1_0__GPIO_1_0            IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0,
 0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_1_1__GPIO_1_1            IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0,
 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_CMD__SD2_CMD               IOMUX_PAD(0x7BC,
0x3B4, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_CLK__SD2_CLK               IOMUX_PAD(0x7C0,
0x3B8, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA0__SD2_DATA0           IOMUX_PAD(0x7C4,
0x3BC, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA1__SD2_DATA1           IOMUX_PAD(0x7C8,
0x3C0, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA2__SD2_DATA2           IOMUX_PAD(0x7CC,
0x3C4, 0, 0x0,   0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA3__SD2_DATA3           IOMUX_PAD(0x7D0,
0x3C8, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CMD__SD2_CMD              IOMUX_PAD(0x7BC, 0x3B4,
IOMUX_CONFIG_SION, 0x0, 1, \
+                                                       MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD2_CLK__SD2_CLK              IOMUX_PAD(0x7C0, 0x3B8,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL | 
PAD_CTL_HYS)
+#define MX51_PAD_SD2_DATA0__SD2_DATA0          IOMUX_PAD(0x7C4, 0x3BC,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD2_DATA1__SD2_DATA1          IOMUX_PAD(0x7C8, 0x3C0,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD2_DATA2__SD2_DATA2          IOMUX_PAD(0x7CC, 0x3C4,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
+#define MX51_PAD_SD2_DATA3__SD2_DATA3          IOMUX_PAD(0x7D0, 0x3C8,
IOMUX_CONFIG_SION, 0x0, 0, \
+                                                       MX51_SDHCI_PAD_CTRL)
 #define MX51_PAD_GPIO_1_2__GPIO_1_2            IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0,
 0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_1_2__I2C2_SCL            IOMUX_PAD(0x7D4, 0x3CC, (2 |
IOMUX_CONFIG_SION), \
                                                        0x9b8,   3, 
MX51_I2C_PAD_CTRL)
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h
b/arch/arm/plat-mxc/include/mach/mx51.h
index 5aad344..5be17ae 100644
--- a/arch/arm/plat-mxc/include/mach/mx51.h
+++ b/arch/arm/plat-mxc/include/mach/mx51.h
@@ -76,13 +76,13 @@
 #define MX51_SPBA0_BASE_ADDR_VIRT      0xFB100000
 #define MX51_SPBA0_SIZE                        SZ_1M

-#define MX51_MMC_SDHC1_BASE_ADDR       (MX51_SPBA0_BASE_ADDR + 0x00004000)
-#define MX51_MMC_SDHC2_BASE_ADDR       (MX51_SPBA0_BASE_ADDR + 0x00008000)
+#define MX51_ESDHC1_BASE_ADDR          (MX51_SPBA0_BASE_ADDR + 0x00004000)
+#define MX51_ESDHC2_BASE_ADDR          (MX51_SPBA0_BASE_ADDR + 0x00008000)
 #define MX51_UART3_BASE_ADDR           (MX51_SPBA0_BASE_ADDR + 0x0000C000)
 #define MX51_CSPI1_BASE_ADDR           (MX51_SPBA0_BASE_ADDR + 0x00010000)
 #define MX51_SSI2_BASE_ADDR            (MX51_SPBA0_BASE_ADDR + 0x00014000)
-#define MX51_MMC_SDHC3_BASE_ADDR       (MX51_SPBA0_BASE_ADDR + 0x00020000)
-#define MX51_MMC_SDHC4_BASE_ADDR       (MX51_SPBA0_BASE_ADDR + 0x00024000)
+#define MX51_ESDHC3_BASE_ADDR          (MX51_SPBA0_BASE_ADDR + 0x00020000)
+#define MX51_ESDHC4_BASE_ADDR          (MX51_SPBA0_BASE_ADDR + 0x00024000)
 #define MX51_SPDIF_BASE_ADDR           (MX51_SPBA0_BASE_ADDR + 0x00028000)
 #define MX51_ATA_DMA_BASE_ADDR         (MX51_SPBA0_BASE_ADDR + 0x00030000)
 #define MX51_SLIM_DMA_BASE_ADDR                (MX51_SPBA0_BASE_ADDR + 
0x00034000)
@@ -319,10 +319,10 @@
  */
 #define MX51_MXC_INT_BASE      0
 #define MX51_MXC_INT_RESV0     0
-#define MX51_MXC_INT_MMC_SDHC1 1
-#define MX51_MXC_INT_MMC_SDHC2 2
-#define MX51_MXC_INT_MMC_SDHC3 3
-#define MX51_MXC_INT_MMC_SDHC4 4
+#define MX51_INT_ESDHC1                1
+#define MX51_INT_ESDHC2                2
+#define MX51_INT_ESDHC3                3
+#define MX51_INT_ESDHC4                4
 #define MX51_MXC_INT_RESV5     5
 #define MX51_MXC_INT_SDMA      6
 #define MX51_MXC_INT_IOMUX     7
-- 
1.7.1


-- 
Regards,
Shawn

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to