Correct Richard address ... On Mon, Oct 18, 2010 at 4:10 PM, Shawn Guo <shawn....@gmail.com> wrote: > 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 >
-- Regards, Shawn _______________________________________________ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev