* [PATCH] mx51: add resources for SD/MMC on i.MX51 @ 2010-10-11 16:05 Eric Bénard 2010-10-11 16:28 ` Wolfram Sang 0 siblings, 1 reply; 9+ messages in thread From: Eric Bénard @ 2010-10-11 16:05 UTC (permalink / raw) To: linux-arm-kernel the attached patch allows SD to work on i.MX51 with Wolfram's drivers Tested on i.MX51. From: Richard Zhu <r65037@freescale.com> Signed-off-by: Eric B?nard <eric@eukrea.com> --- arch/arm/mach-mx5/clock-mx51.c | 193 +++++++++++++++++++++++++++ arch/arm/mach-mx5/devices-imx51.h | 9 ++ arch/arm/plat-mxc/include/mach/iomux-mx51.h | 33 +++-- 3 files changed, 221 insertions(+), 14 deletions(-) diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 21cecc0..eee2814 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -41,6 +41,35 @@ static struct clk usboh3_clk; #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) +{ + u32 min_pre, temp_pre, old_err, err; + + if (div >= 512) { + *pre = 8; + *post = 64; + } else if (div >= 8) { + min_pre = (div - 1) / 64 + 1; + old_err = 8; + for (temp_pre = 8; 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 + *pre - 1) / *pre; + } else if (div < 8) { + *pre = div; + *post = 1; + } +} + static void _clk_ccgr_setclk(struct clk *clk, unsigned mode) { u32 reg = __raw_readl(clk->enable_reg); @@ -893,6 +922,160 @@ static struct clk ecspi_main_clk = { .set_parent = clk_ecspi_set_parent, }; +static int _clk_esdhc1_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_ESDHC1_MSHC1_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET; + __raw_writel(reg, MXC_CCM_CSCMR1); + + return 0; +} + +static unsigned long _clk_esdhc1_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_ESDHC1_MSHC1_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET) + 1; + + return parent_rate / (prediv * podf); +} + +static int _clk_esdhc1_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); + + /* Set sdhc1 clock divider */ + reg = __raw_readl(MXC_CCM_CSCDR1) & + ~(MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK + | MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK); + reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CSCDR1); + + return 0; +} + +static struct clk esdhc1_clk[] = { + { + .id = 0, + .parent = &pll2_sw_clk, + .secondary = &esdhc1_clk[1], + .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET, + .enable_reg = MXC_CCM_CCGR3, + .get_rate = _clk_esdhc1_get_rate, + .set_rate = _clk_esdhc1_set_rate, + .enable = _clk_max_enable, + .disable = _clk_max_disable, + .set_parent = _clk_esdhc1_set_parent, + }, + { + .id = 0, + .parent = &ipg_clk, + .secondary = NULL, + .enable = _clk_max_enable, + .enable_reg = MXC_CCM_CCGR3, + .enable_shift = MXC_CCM_CCGRx_CG0_OFFSET, + .disable = _clk_max_disable, + } +}; + +static int _clk_esdhc2_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_ESDHC2_MSHC2_CLK_SEL_MASK; + reg |= mux << MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET; + + __raw_writel(reg, MXC_CCM_CSCMR1); + return 0; +} + +static unsigned long _clk_esdhc2_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_ESDHC2_MSHC2_CLK_PRED_MASK) >> + MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET) + 1; + podf = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK) >> + MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET) + 1; + + return parent_rate / (prediv * podf); +} + +static int _clk_esdhc2_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); + + /* Set sdhc1 clock divider */ + reg = __raw_readl(MXC_CCM_CSCDR1) & + ~(MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK + | MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK); + reg |= (post - 1) << MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET; + reg |= (pre - 1) << MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET; + __raw_writel(reg, MXC_CCM_CSCDR1); + + return 0; +} + +static struct clk esdhc2_clk[] = { + { + .id = 1, + .parent = &pll2_sw_clk, + .secondary = &esdhc2_clk[1], + .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET, + .enable_reg = MXC_CCM_CCGR3, + .get_rate = _clk_esdhc2_get_rate, + .set_rate = _clk_esdhc2_set_rate, + .enable = _clk_max_enable, + .disable = _clk_max_disable, + .set_parent = _clk_esdhc2_set_parent, + }, + { + .id = 1, + .parent = &ipg_clk, + .secondary = NULL, + .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET, + .enable_reg = MXC_CCM_CCGR3, + .enable = _clk_max_enable, + .disable = _clk_max_disable, + } +}; + #define DEFINE_CLOCK_FULL(name, i, er, es, gr, sr, e, d, p, s) \ static struct clk name = { \ .id = i, \ @@ -1014,6 +1197,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_clk) + _REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk[0]) + _REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk[0]) }; static void clk_tree_init(void) @@ -1057,6 +1242,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[0], &pll2_sw_clk); + clk_set_parent(&esdhc2_clk[0], &pll2_sw_clk); + + /* set SDHC root clock as 166.25MHZ*/ + clk_set_rate(&esdhc1_clk[0], 166250000); + clk_set_rate(&esdhc2_clk[0], 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 index c233379..547432d 100644 --- a/arch/arm/mach-mx5/devices-imx51.h +++ b/arch/arm/mach-mx5/devices-imx51.h @@ -36,3 +36,12 @@ extern const struct imx_spi_imx_data imx51_cspi_data __initconst; extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst; #define imx51_add_ecspi(id, pdata) \ imx_add_spi_imx(&imx51_ecspi_data[id], pdata) + +#define imx51_add_esdhc0(pdata) \ + imx_add_esdhc(0, MX51_MMC_SDHC1_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC1, pdata) +#define imx51_add_esdhc1(pdata) \ + imx_add_esdhc(1, MX51_MMC_SDHC2_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC2, pdata) +#define imx51_add_esdhc2(pdata) \ + imx_add_esdhc(2, MX51_MMC_SDHC3_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC3, pdata) +#define imx51_add_esdhc3(pdata) \ + imx_add_esdhc(3, MX51_MMC_SDHC4_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC4, pdata) diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h index 633650d..4b8c61e 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h @@ -47,6 +47,9 @@ typedef enum iomux_config { PAD_CTL_SRE_FAST) #define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \ 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) #define MX51_PAD_CTRL_1 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \ PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_HYS) @@ -333,20 +336,22 @@ 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_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, IOMUX_CONFIG_GPIO, 0x0, 0, MX51_SDHCI_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) @@ -355,7 +360,7 @@ typedef enum iomux_config { 0x9bc, 3, MX51_I2C_PAD_CTRL) #define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, IOMUX_CONFIG_GPIO, 0x0, 1, NO_PAD_CTRL) #define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, MX51_GPIO_PAD_CTRL) -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH] mx51: add resources for SD/MMC on i.MX51 2010-10-11 16:05 [PATCH] mx51: add resources for SD/MMC on i.MX51 Eric Bénard @ 2010-10-11 16:28 ` Wolfram Sang 2010-10-11 16:55 ` Eric Bénard 0 siblings, 1 reply; 9+ messages in thread From: Wolfram Sang @ 2010-10-11 16:28 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 11, 2010 at 06:05:42PM +0200, Eric B?nard wrote: > the attached patch allows SD to work on i.MX51 with Wolfram's drivers > Tested on i.MX51. > > From: Richard Zhu <r65037@freescale.com> > Signed-off-by: Eric B?nard <eric@eukrea.com> Hmm, Uwe had some (valid IMHO) comments about this patch which have not all been addressed so far. Richard, are you still working on this? Regards, Wolfram -- Pengutronix e.K. | Wolfram Sang | Industrial Linux Solutions | http://www.pengutronix.de/ | -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101011/a0c2ff0c/attachment.sig> ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] mx51: add resources for SD/MMC on i.MX51 2010-10-11 16:28 ` Wolfram Sang @ 2010-10-11 16:55 ` Eric Bénard 2010-10-11 17:04 ` Wolfram Sang 0 siblings, 1 reply; 9+ messages in thread From: Eric Bénard @ 2010-10-11 16:55 UTC (permalink / raw) To: linux-arm-kernel Hi Wolfram, Le 11/10/2010 18:28, Wolfram Sang a ?crit : > On Mon, Oct 11, 2010 at 06:05:42PM +0200, Eric B?nard wrote: >> the attached patch allows SD to work on i.MX51 with Wolfram's drivers >> Tested on i.MX51. >> >> From: Richard Zhu<r65037@freescale.com> >> Signed-off-by: Eric B?nard<eric@eukrea.com> > > Hmm, Uwe had some (valid IMHO) comments about this patch which have not all > been addressed so far. Richard, are you still working on this? > OK, is this this review http://lists.infradead.org/pipermail/linux-arm-kernel/2010-September/027269.html ? If yes, I can submit a fixed patch asap. Eric ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] mx51: add resources for SD/MMC on i.MX51 2010-10-11 16:55 ` Eric Bénard @ 2010-10-11 17:04 ` Wolfram Sang 2010-10-12 7:31 ` [PATCH 1/2] clock-mx51: factorize clk_set_parent and clk_get_rate Eric Bénard 2010-10-12 7:31 ` [PATCH 2/2] mx51: add resources for SD/MMC on i.MX51 Eric Bénard 0 siblings, 2 replies; 9+ messages in thread From: Wolfram Sang @ 2010-10-11 17:04 UTC (permalink / raw) To: linux-arm-kernel On Mon, Oct 11, 2010 at 06:55:38PM +0200, Eric B?nard wrote: > Hi Wolfram, > > Le 11/10/2010 18:28, Wolfram Sang a ?crit : >> On Mon, Oct 11, 2010 at 06:05:42PM +0200, Eric B?nard wrote: >>> the attached patch allows SD to work on i.MX51 with Wolfram's drivers >>> Tested on i.MX51. >>> >>> From: Richard Zhu<r65037@freescale.com> >>> Signed-off-by: Eric B?nard<eric@eukrea.com> >> >> Hmm, Uwe had some (valid IMHO) comments about this patch which have not all >> been addressed so far. Richard, are you still working on this? >> > OK, is this this review > http://lists.infradead.org/pipermail/linux-arm-kernel/2010-September/027269.html > ? If yes, I can submit a fixed patch asap. Yes, that is the one. Sorry, I also wanted to give a pointer to this mail but it dropped off my mind. Patch would be awesome! Regards, Wolfram -- Pengutronix e.K. | Wolfram Sang | Industrial Linux Solutions | http://www.pengutronix.de/ | -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: Digital signature URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20101011/0d9efbae/attachment.sig> ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/2] clock-mx51: factorize clk_set_parent and clk_get_rate 2010-10-11 17:04 ` Wolfram Sang @ 2010-10-12 7:31 ` Eric Bénard 2010-10-12 7:31 ` [PATCH 2/2] mx51: add resources for SD/MMC on i.MX51 Eric Bénard 1 sibling, 0 replies; 9+ messages in thread From: Eric Bénard @ 2010-10-12 7:31 UTC (permalink / raw) To: linux-arm-kernel Signed-off-by: Eric B?nard <eric@eukrea.com> --- arch/arm/mach-mx5/clock-mx51.c | 142 ++++++++++++++-------------------------- 1 files changed, 48 insertions(+), 94 deletions(-) diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 21cecc0..7deb683 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -544,35 +544,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; -} - #define clk_nfc_set_parent NULL static unsigned long clk_nfc_get_rate(struct clk *clk) @@ -631,35 +602,6 @@ static int clk_nfc_set_rate(struct clk *clk, unsigned long rate) 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; @@ -786,18 +728,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, @@ -857,35 +787,59 @@ static struct clk emi_slow_clk = { .secondary = s, \ } -/* eCSPI */ -static unsigned long clk_ecspi_get_rate(struct clk *clk) -{ - u32 reg, pred, podf; - - reg = __raw_readl(MXC_CCM_CSCDR2); - - pred = (reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >> - MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET; - podf = (reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >> - MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET; - - return DIV_ROUND_CLOSEST(clk_get_rate(clk->parent), - (pred + 1) * (podf + 1)); +#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; \ } -static int clk_ecspi_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg, mux; +/* UART */ +CLK_GET_RATE(uart, 1, UART) +CLK_SET_PARENT(uart, 1, UART) - mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, - &lp_apm_clk); +static struct clk uart_root_clk = { + .parent = &pll2_sw_clk, + .get_rate = clk_uart_get_rate, + .set_parent = clk_uart_set_parent, +}; - reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK; - reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; - __raw_writel(reg, MXC_CCM_CSCMR1); +/* USBOH3 */ +CLK_GET_RATE(usboh3, 1, USBOH3) +CLK_SET_PARENT(usboh3, 1, USBOH3) - return 0; -} +static struct clk usboh3_clk = { + .parent = &pll2_sw_clk, + .get_rate = clk_usboh3_get_rate, + .set_parent = clk_usboh3_set_parent, +}; + +/* eCSPI */ +CLK_GET_RATE(ecspi, 2, CSPI) +CLK_SET_PARENT(ecspi, 1, CSPI) static struct clk ecspi_main_clk = { .parent = &pll3_sw_clk, -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] mx51: add resources for SD/MMC on i.MX51 2010-10-11 17:04 ` Wolfram Sang 2010-10-12 7:31 ` [PATCH 1/2] clock-mx51: factorize clk_set_parent and clk_get_rate Eric Bénard @ 2010-10-12 7:31 ` Eric Bénard 2010-10-12 8:18 ` Uwe Kleine-König 1 sibling, 1 reply; 9+ messages in thread From: Eric Bénard @ 2010-10-12 7:31 UTC (permalink / raw) To: linux-arm-kernel the attached patch allows SD to work on i.MX51 with Wolfram's drivers Tested on i.MX51. Based on original patch from: Richard Zhu <r65037@freescale.com> Signed-off-by: Eric B?nard <eric@eukrea.com> --- arch/arm/mach-mx5/clock-mx51.c | 102 ++++++++++++++++++++++++++- arch/arm/mach-mx5/devices-imx51.h | 9 +++ arch/arm/plat-mxc/include/mach/iomux-mx51.h | 45 ++++++++---- 3 files changed, 140 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 7deb683..9e8b268 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -41,6 +41,34 @@ static struct clk usboh3_clk; #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) +{ + if (div >= 512) { + *pre = 8; + *post = 64; + } else if (div >= 8) { + u32 min_pre, temp_pre, old_err, err; + min_pre = (div - 1) / 64 + 1; + old_err = 8; + for (temp_pre = 8; 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 + *pre - 1) / *pre; + } else { + *pre = div; + *post = 1; + } +} + static void _clk_ccgr_setclk(struct clk *clk, unsigned mode) { u32 reg = __raw_readl(clk->enable_reg); @@ -772,7 +800,7 @@ static struct clk emi_slow_clk = { .get_rate = clk_emi_slow_get_rate, }; -#define DEFINE_CLOCK1(name, i, er, es, pfx, p, s) \ +#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ static struct clk name = { \ .id = i, \ .enable_reg = er, \ @@ -787,6 +815,20 @@ static struct clk emi_slow_clk = { .secondary = 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 = 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 CLK_GET_RATE(name, nr, bitsname) \ static unsigned long clk_##name##_get_rate(struct clk *clk) \ { \ @@ -817,6 +859,33 @@ static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \ 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); \ + \ + /* 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) @@ -847,6 +916,15 @@ static struct clk ecspi_main_clk = { .set_parent = clk_ecspi_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, \ @@ -900,7 +978,7 @@ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, NULL, NULL, &ipg_clk, NULL); /* NFC */ -DEFINE_CLOCK1(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, +DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, clk_nfc, &emi_slow_clk, NULL); /* SSI */ @@ -935,6 +1013,16 @@ DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET, DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET, NULL, NULL, &ahb_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, \ @@ -968,6 +1056,8 @@ static struct clk_lookup lookups[] = { _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_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) @@ -1011,6 +1101,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 index c233379..547432d 100644 --- a/arch/arm/mach-mx5/devices-imx51.h +++ b/arch/arm/mach-mx5/devices-imx51.h @@ -36,3 +36,12 @@ extern const struct imx_spi_imx_data imx51_cspi_data __initconst; extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst; #define imx51_add_ecspi(id, pdata) \ imx_add_spi_imx(&imx51_ecspi_data[id], pdata) + +#define imx51_add_esdhc0(pdata) \ + imx_add_esdhc(0, MX51_MMC_SDHC1_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC1, pdata) +#define imx51_add_esdhc1(pdata) \ + imx_add_esdhc(1, MX51_MMC_SDHC2_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC2, pdata) +#define imx51_add_esdhc2(pdata) \ + imx_add_esdhc(2, MX51_MMC_SDHC3_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC3, pdata) +#define imx51_add_esdhc3(pdata) \ + imx_add_esdhc(3, MX51_MMC_SDHC4_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC4, pdata) diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h index 5160f10..c5adb42 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h @@ -47,6 +47,9 @@ typedef enum iomux_config { PAD_CTL_SRE_FAST) #define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \ 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) #define MX51_PAD_CTRL_1 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \ PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_HYS) @@ -333,26 +336,39 @@ 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_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) #define MX51_PAD_SD1_CMD__AUD5_RXFS IOMUX_PAD(0x79C, 0x394, 1, 0x8e0, 1, NO_PAD_CTRL) -#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_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_CLK__AUD5_RXC IOMUX_PAD(0x7A0, 0x398, 1, 0x8dc, 1, NO_PAD_CTRL) -#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, IOMUX_CONFIG_SION, 0x0, 0, \ + MX51_SDHCI_PAD_CTRL) #define MX51_PAD_SD1_DATA0__AUD5_TXD IOMUX_PAD(0x7A4, 0x39C, 1, 0x8d8, 2, NO_PAD_CTRL) -#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_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_DATA1__AUD5_RXD IOMUX_PAD(0x7A8, 0x3A0, 1, 0x8d4, 2, NO_PAD_CTRL) -#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_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_DATA2__AUD5_TXC IOMUX_PAD(0x7AC, 0x3A4, 1, 0x8e4, 2, NO_PAD_CTRL) -#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_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_SD1_DATA3__AUD5_TXFS IOMUX_PAD(0x7B0, 0x3A8, 1, 0x8e8, 2, 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_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_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, IOMUX_CONFIG_GPIO, 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) @@ -361,7 +377,8 @@ typedef enum iomux_config { 0x9bc, 3, MX51_I2C_PAD_CTRL) #define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL) #define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL) -#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL) +#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, IOMUX_CONFIG_GPIO, 0x0, 1, \ + NO_PAD_CTRL) #define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL) #define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, MX51_GPIO_PAD_CTRL) -- 1.7.0.4 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/2] mx51: add resources for SD/MMC on i.MX51 2010-10-12 7:31 ` [PATCH 2/2] mx51: add resources for SD/MMC on i.MX51 Eric Bénard @ 2010-10-12 8:18 ` Uwe Kleine-König 2010-10-12 8:50 ` Eric Bénard 0 siblings, 1 reply; 9+ messages in thread From: Uwe Kleine-König @ 2010-10-12 8:18 UTC (permalink / raw) To: linux-arm-kernel Hi Eric, great you pick up this topic. On Tue, Oct 12, 2010 at 09:31:25AM +0200, Eric B?nard wrote: > the attached patch allows SD to work on i.MX51 with Wolfram's drivers > Tested on i.MX51. > > Based on original patch from: Richard Zhu <r65037@freescale.com> > Signed-off-by: Eric B?nard <eric@eukrea.com> > --- > arch/arm/mach-mx5/clock-mx51.c | 102 ++++++++++++++++++++++++++- > arch/arm/mach-mx5/devices-imx51.h | 9 +++ > arch/arm/plat-mxc/include/mach/iomux-mx51.h | 45 ++++++++---- > 3 files changed, 140 insertions(+), 16 deletions(-) > > diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c > index 7deb683..9e8b268 100644 > --- a/arch/arm/mach-mx5/clock-mx51.c > +++ b/arch/arm/mach-mx5/clock-mx51.c > @@ -41,6 +41,34 @@ static struct clk usboh3_clk; > > #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ > > +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) > +{ I asked for a comment here. E.g. valid ranges of pre and post and the task solved here (I assume it's "Find pre and post with pre * post = div"?). > + if (div >= 512) { > + *pre = 8; > + *post = 64; > + } else if (div >= 8) { > + u32 min_pre, temp_pre, old_err, err; > + min_pre = (div - 1) / 64 + 1; min_pre = DIV_ROUND_UP(div, 64); ? > + old_err = 8; > + for (temp_pre = 8; 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 + *pre - 1) / *pre; *post = DIV_ROUND_UP(div, *pre); I don't know if DIV_ROUND_UP is sensible, maybe use DIV_ROUND_CLOSEST? I'd look into that when the comment above is in place. > + } else { > + *pre = div; > + *post = 1; > + } > +} > + > static void _clk_ccgr_setclk(struct clk *clk, unsigned mode) > { > u32 reg = __raw_readl(clk->enable_reg); > @@ -772,7 +800,7 @@ static struct clk emi_slow_clk = { > .get_rate = clk_emi_slow_get_rate, > }; > > -#define DEFINE_CLOCK1(name, i, er, es, pfx, p, s) \ > +#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ This is IMHO a good idea, but it should go in a seperate patch. These clock changes are very sensible and so a working bisection is important here. > static struct clk name = { \ > .id = i, \ > .enable_reg = er, \ > @@ -787,6 +815,20 @@ static struct clk emi_slow_clk = { > .secondary = 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 = 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 CLK_GET_RATE(name, nr, bitsname) \ > static unsigned long clk_##name##_get_rate(struct clk *clk) \ > { \ > @@ -817,6 +859,33 @@ static int clk_##name##_set_parent(struct clk *clk, struct clk *parent) \ > 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); \ > + \ > + /* 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) > @@ -847,6 +916,15 @@ static struct clk ecspi_main_clk = { > .set_parent = clk_ecspi_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, \ > @@ -900,7 +978,7 @@ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, > NULL, NULL, &ipg_clk, NULL); > > /* NFC */ > -DEFINE_CLOCK1(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, > +DEFINE_CLOCK_CCGR(nfc_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG10_OFFSET, > clk_nfc, &emi_slow_clk, NULL); > > /* SSI */ > @@ -935,6 +1013,16 @@ DEFINE_CLOCK(cspi_clk, 0, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG13_OFFSET, > DEFINE_CLOCK(sdma_clk, 1, MXC_CCM_CCGR4, MXC_CCM_CCGRx_CG15_OFFSET, > NULL, NULL, &ahb_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, \ > @@ -968,6 +1056,8 @@ static struct clk_lookup lookups[] = { > _REGISTER_CLOCK("imx51-ecspi.0", NULL, ecspi1_clk) > _REGISTER_CLOCK("imx51-ecspi.1", NULL, ecspi2_clk) > _REGISTER_CLOCK("imx51-cspi.0", NULL, cspi_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) > @@ -1011,6 +1101,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 > index c233379..547432d 100644 > --- a/arch/arm/mach-mx5/devices-imx51.h > +++ b/arch/arm/mach-mx5/devices-imx51.h > @@ -36,3 +36,12 @@ extern const struct imx_spi_imx_data imx51_cspi_data __initconst; > extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst; > #define imx51_add_ecspi(id, pdata) \ > imx_add_spi_imx(&imx51_ecspi_data[id], pdata) > + > +#define imx51_add_esdhc0(pdata) \ > + imx_add_esdhc(0, MX51_MMC_SDHC1_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC1, pdata) > +#define imx51_add_esdhc1(pdata) \ > + imx_add_esdhc(1, MX51_MMC_SDHC2_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC2, pdata) > +#define imx51_add_esdhc2(pdata) \ > + imx_add_esdhc(2, MX51_MMC_SDHC3_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC3, pdata) > +#define imx51_add_esdhc3(pdata) \ > + imx_add_esdhc(3, MX51_MMC_SDHC4_BASE_ADDR, SZ_16K, MX51_MXC_INT_MMC_SDHC4, pdata) I'd prefer to have these values in a struct. This makes calling the function much cheaper. Look above, imx51_add_ecspi uses it. > diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h > index 5160f10..c5adb42 100644 > --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h > +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h Changes to this file deserve to be in a seperate patch, too. > @@ -47,6 +47,9 @@ typedef enum iomux_config { > PAD_CTL_SRE_FAST) > #define MX51_ECSPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \ > 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) > > #define MX51_PAD_CTRL_1 (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \ > PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_HYS) > @@ -333,26 +336,39 @@ 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_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, IOMUX_CONFIG_SION, 0x0, 0, \ > + MX51_SDHCI_PAD_CTRL) > #define MX51_PAD_SD1_CMD__AUD5_RXFS IOMUX_PAD(0x79C, 0x394, 1, 0x8e0, 1, NO_PAD_CTRL) > -#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_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_CLK__AUD5_RXC IOMUX_PAD(0x7A0, 0x398, 1, 0x8dc, 1, NO_PAD_CTRL) > -#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL) > +#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, IOMUX_CONFIG_SION, 0x0, 0, \ > + MX51_SDHCI_PAD_CTRL) > #define MX51_PAD_SD1_DATA0__AUD5_TXD IOMUX_PAD(0x7A4, 0x39C, 1, 0x8d8, 2, NO_PAD_CTRL) > -#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_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_DATA1__AUD5_RXD IOMUX_PAD(0x7A8, 0x3A0, 1, 0x8d4, 2, NO_PAD_CTRL) > -#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_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_DATA2__AUD5_TXC IOMUX_PAD(0x7AC, 0x3A4, 1, 0x8e4, 2, NO_PAD_CTRL) > -#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_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_SD1_DATA3__AUD5_TXFS IOMUX_PAD(0x7B0, 0x3A8, 1, 0x8e8, 2, 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_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_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, IOMUX_CONFIG_GPIO, 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) > @@ -361,7 +377,8 @@ typedef enum iomux_config { > 0x9bc, 3, MX51_I2C_PAD_CTRL) > #define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL) > #define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL) > -#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL) > +#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, IOMUX_CONFIG_GPIO, 0x0, 1, \ > + NO_PAD_CTRL) > #define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, MX51_GPIO_PAD_CTRL) > #define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL) > #define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, MX51_GPIO_PAD_CTRL) > -- > 1.7.0.4 > > -- Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ | ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] mx51: add resources for SD/MMC on i.MX51 2010-10-12 8:18 ` Uwe Kleine-König @ 2010-10-12 8:50 ` Eric Bénard 2010-10-12 9:32 ` Uwe Kleine-König 0 siblings, 1 reply; 9+ messages in thread From: Eric Bénard @ 2010-10-12 8:50 UTC (permalink / raw) To: linux-arm-kernel Hi Uwe, Le 12/10/2010 10:18, Uwe Kleine-K?nig a ?crit : > On Tue, Oct 12, 2010 at 09:31:25AM +0200, Eric B?nard wrote: >> the attached patch allows SD to work on i.MX51 with Wolfram's drivers >> Tested on i.MX51. >> >> Based on original patch from: Richard Zhu<r65037@freescale.com> >> Signed-off-by: Eric B?nard<eric@eukrea.com> >> --- >> arch/arm/mach-mx5/clock-mx51.c | 102 ++++++++++++++++++++++++++- >> arch/arm/mach-mx5/devices-imx51.h | 9 +++ >> arch/arm/plat-mxc/include/mach/iomux-mx51.h | 45 ++++++++---- >> 3 files changed, 140 insertions(+), 16 deletions(-) >> >> diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c >> index 7deb683..9e8b268 100644 >> --- a/arch/arm/mach-mx5/clock-mx51.c >> +++ b/arch/arm/mach-mx5/clock-mx51.c >> @@ -41,6 +41,34 @@ static struct clk usboh3_clk; >> >> #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ >> >> +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) >> +{ > I asked for a comment here. E.g. valid ranges of pre and post and the > task solved here (I assume it's "Find pre and post with pre * post = > div"?). > will try to write something. Richard : do you have a comment in mind for this function ? >> + } >> + *post = (div + *pre - 1) / *pre; > *post = DIV_ROUND_UP(div, *pre); > > I don't know if DIV_ROUND_UP is sensible, maybe use DIV_ROUND_CLOSEST? > I'd look into that when the comment above is in place. > if you have an opinion before, this would be great to avoid a n+1 version of this patch ;-) >> -#define DEFINE_CLOCK1(name, i, er, es, pfx, p, s) \ >> +#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ > This is IMHO a good idea, but it should go in a seperate patch. These > clock changes are very sensible and so a working bisection is important > here. > there is no clock change here only a define rename to avoid having DEFINE_CLOCK1, DEFINE_CLOCK2 ... is a separate patch really needed ? Eric ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 2/2] mx51: add resources for SD/MMC on i.MX51 2010-10-12 8:50 ` Eric Bénard @ 2010-10-12 9:32 ` Uwe Kleine-König 0 siblings, 0 replies; 9+ messages in thread From: Uwe Kleine-König @ 2010-10-12 9:32 UTC (permalink / raw) To: linux-arm-kernel Hi Eric, On Tue, Oct 12, 2010 at 10:50:52AM +0200, Eric B?nard wrote: > Le 12/10/2010 10:18, Uwe Kleine-K?nig a ?crit : >> On Tue, Oct 12, 2010 at 09:31:25AM +0200, Eric B?nard wrote: >>> the attached patch allows SD to work on i.MX51 with Wolfram's drivers >>> Tested on i.MX51. >>> >>> Based on original patch from: Richard Zhu<r65037@freescale.com> >>> Signed-off-by: Eric B?nard<eric@eukrea.com> >>> --- >>> arch/arm/mach-mx5/clock-mx51.c | 102 ++++++++++++++++++++++++++- >>> arch/arm/mach-mx5/devices-imx51.h | 9 +++ >>> arch/arm/plat-mxc/include/mach/iomux-mx51.h | 45 ++++++++---- >>> 3 files changed, 140 insertions(+), 16 deletions(-) >>> >>> diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c >>> index 7deb683..9e8b268 100644 >>> --- a/arch/arm/mach-mx5/clock-mx51.c >>> +++ b/arch/arm/mach-mx5/clock-mx51.c >>> @@ -41,6 +41,34 @@ static struct clk usboh3_clk; >>> >>> #define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ >>> >>> +static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) >>> +{ >> I asked for a comment here. E.g. valid ranges of pre and post and the >> task solved here (I assume it's "Find pre and post with pre * post = >> div"?). >> > will try to write something. > Richard : do you have a comment in mind for this function ? > > >> + } > >> + *post = (div + *pre - 1) / *pre; > > *post = DIV_ROUND_UP(div, *pre); > > > > I don't know if DIV_ROUND_UP is sensible, maybe use DIV_ROUND_CLOSEST? > > I'd look into that when the comment above is in place. > > > if you have an opinion before, this would be great to avoid a n+1 > version of this patch ;-) I'm lazy. To analyse this I need to know how pre and post are used. I assume you (and/or Richard) already know that so I'm not keen to search this info in the reference manuals. See it as a quality test for the comment I asked for :-) >>> -#define DEFINE_CLOCK1(name, i, er, es, pfx, p, s) \ >>> +#define DEFINE_CLOCK_CCGR(name, i, er, es, pfx, p, s) \ >> This is IMHO a good idea, but it should go in a seperate patch. These >> clock changes are very sensible and so a working bisection is important >> here. >> > there is no clock change here only a define rename to avoid having > DEFINE_CLOCK1, DEFINE_CLOCK2 ... is a separate patch really needed ? Yep, please do. I don't hope your patch breaks anything, but if it does, it's easier to find out the actual breakage if there is no noise in the patch. Uwe -- Pengutronix e.K. | Uwe Kleine-K?nig | Industrial Linux Solutions | http://www.pengutronix.de/ | ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-10-12 9:32 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-10-11 16:05 [PATCH] mx51: add resources for SD/MMC on i.MX51 Eric Bénard 2010-10-11 16:28 ` Wolfram Sang 2010-10-11 16:55 ` Eric Bénard 2010-10-11 17:04 ` Wolfram Sang 2010-10-12 7:31 ` [PATCH 1/2] clock-mx51: factorize clk_set_parent and clk_get_rate Eric Bénard 2010-10-12 7:31 ` [PATCH 2/2] mx51: add resources for SD/MMC on i.MX51 Eric Bénard 2010-10-12 8:18 ` Uwe Kleine-König 2010-10-12 8:50 ` Eric Bénard 2010-10-12 9:32 ` Uwe Kleine-König
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).