Hi, On 8/28/12, snow.jh...@gmail.com <snow.jh...@gmail.com> wrote: > From: Jeong-Hyeon Kim <jh...@insignal.co.kr> > > - Fixed MPLL register address > It's different between Exynos4210 and Exynos4412. > > - Added pinmux functions for Exynos4 > > - Added extended gpios for Exynos4412 > Exynos4412 has more gpios than Exynos4210. > > Signed-off-by: Jeong-Hyeon Kim <jh...@insignal.co.kr> > --- > arch/arm/cpu/armv7/exynos/clock.c | 11 ++ > arch/arm/cpu/armv7/exynos/pinmux.c | 241 > ++++++++++++++++++++++++++++++ > arch/arm/include/asm/arch-exynos/clock.h | 27 ++++ > arch/arm/include/asm/arch-exynos/cpu.h | 4 + > arch/arm/include/asm/arch-exynos/gpio.h | 21 +++- > 5 files changed, 303 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/cpu/armv7/exynos/clock.c > b/arch/arm/cpu/armv7/exynos/clock.c > index 680aeeb..84a6725 100644 > --- a/arch/arm/cpu/armv7/exynos/clock.c > +++ b/arch/arm/cpu/armv7/exynos/clock.c > @@ -79,14 +79,25 @@ static unsigned long exynos4_get_pll_clk(int pllreg) > /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */ > fout = (m + k / 65536) * (freq / (p * (1 << s))); > } else if (pllreg == VPLL) { > +#ifdef CONFIG_EXYNOS4210 we don't like the ifdefy at here. How about to check soc_is_4210 and soc_is_4412? > k = k & 0xfff; > /* FOUT = (MDIV + K / 1024) * FIN / (PDIV * 2^SDIV) */ > fout = (m + k / 1024) * (freq / (p * (1 << s))); > +#else > + k = k & 0xffff; > + /* FOUT = (MDIV + K / 65536) * FIN / (PDIV * 2^SDIV) */ > + fout = (m + k / 65536) * (freq / (p * (1 << s))); > +#endif > } else { > +#ifdef CONFIG_EXYNOS4210 ditto > if (s < 1) > s = 1; > /* FOUT = MDIV * FIN / (PDIV * 2^(SDIV - 1)) */ > fout = m * (freq / (p * (1 << (s - 1)))); > +#else > + /* FOUT = MDIV * FIN / (PDIV * 2^SDIV) */ > + fout = m * (freq / (p * (1 << s))); > +#endif > } > > return fout; > diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c > b/arch/arm/cpu/armv7/exynos/pinmux.c > index 7776add..0746878 100644 > --- a/arch/arm/cpu/armv7/exynos/pinmux.c > +++ b/arch/arm/cpu/armv7/exynos/pinmux.c > @@ -26,6 +26,245 @@ > #include <asm/arch/pinmux.h> > #include <asm/arch/sromc.h> > > +static void exynos4_uart_config(int peripheral) > +{ > + struct exynos4_gpio_part1 *gpio1 = > + (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1(); > + struct s5p_gpio_bank *bank; > + int i, start, count; > + > + switch (peripheral) { > + case PERIPH_ID_UART0: > + bank = &gpio1->a0; > + start = 0; > + count = 4; > + break; > + case PERIPH_ID_UART1: > + bank = &gpio1->a0; > + start = 4; > + count = 4; > + break; > + case PERIPH_ID_UART2: > + bank = &gpio1->a1; > + start = 0; > + count = 4; > + break; > + case PERIPH_ID_UART3: > + bank = &gpio1->a1; > + start = 4; > + count = 2; > + break; > + } > + for (i = start; i < start + count; i++) { > + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); > + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); > + } > +} > + > +static int exynos4_mmc_config(int peripheral, int flags) > +{ > + struct exynos4_gpio_part2 *gpio2 = > + (struct exynos4_gpio_part2 *) samsung_get_base_gpio_part2(); > + struct s5p_gpio_bank *bank, *bank_ext; > + int i, start = 0, gpio_func = 0; > + > + switch (peripheral) { > + case PERIPH_ID_SDMMC0: > + bank = &gpio2->k0; > + bank_ext = &gpio2->k1; > + start = 3; > + gpio_func = GPIO_FUNC(0x2); > + break; > + case PERIPH_ID_SDMMC1: > + bank = &gpio2->k1; > + bank_ext = NULL; > + break; > + case PERIPH_ID_SDMMC2: > + bank = &gpio2->k2; > + bank_ext = &gpio2->k3; > + start = 3; > + gpio_func = GPIO_FUNC(0x3); > + break; > + case PERIPH_ID_SDMMC3: > + bank = &gpio2->k3; > + bank_ext = NULL; > + break; > + } > + if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) { > + debug("SDMMC device %d does not support 8bit mode", > + peripheral); > + return -1; > + } > + if (flags & PINMUX_FLAG_8BIT_MODE) { > + for (i = start; i <= (start + 3); i++) { > + s5p_gpio_cfg_pin(bank_ext, i, gpio_func); > + s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP); > + s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X); > + } > + } > + for (i = 0; i < 2; i++) { > + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); > + s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE); > + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); > + } > + for (i = 3; i <= 6; i++) { > + s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2)); > + s5p_gpio_set_pull(bank, i, GPIO_PULL_UP); > + s5p_gpio_set_drv(bank, i, GPIO_DRV_4X); > + } > + return 0; > +} > + > +static void exynos4_sromc_config(int flags) > +{ > + struct exynos4_gpio_part2 *gpio2 = > + (struct exynos4_gpio_part2 *) samsung_get_base_gpio_part2(); > + int i; > + > + /* > + * SROM:CS1 and EBI > + * > + * GPY0[0] SROM_CSn[0] > + * GPY0[1] SROM_CSn[1](2) > + * GPY0[2] SROM_CSn[2] > + * GPY0[3] SROM_CSn[3] > + * GPY0[4] EBI_OEn(2) > + * GPY0[5] EBI_EEn(2) > + * > + * GPY1[0] EBI_BEn[0](2) > + * GPY1[1] EBI_BEn[1](2) > + * GPY1[2] SROM_WAIT(2) > + * GPY1[3] EBI_DATA_RDn(2) > + */ > + s5p_gpio_cfg_pin(&gpio2->y0, (flags & PINMUX_FLAG_BANK), > + GPIO_FUNC(2)); > + s5p_gpio_cfg_pin(&gpio2->y0, 4, GPIO_FUNC(2)); > + s5p_gpio_cfg_pin(&gpio2->y0, 5, GPIO_FUNC(2)); > + > + for (i = 0; i < 4; i++) > + s5p_gpio_cfg_pin(&gpio2->y1, i, GPIO_FUNC(2)); > + > + /* > + * EBI: 8 Addrss Lines > + * > + * GPY3[0] EBI_ADDR[0](2) > + * GPY3[1] EBI_ADDR[1](2) > + * GPY3[2] EBI_ADDR[2](2) > + * GPY3[3] EBI_ADDR[3](2) > + * GPY3[4] EBI_ADDR[4](2) > + * GPY3[5] EBI_ADDR[5](2) > + * GPY3[6] EBI_ADDR[6](2) > + * GPY3[7] EBI_ADDR[7](2) > + * > + * EBI: 16 Data Lines > + * > + * GPY5[0] EBI_DATA[0](2) > + * GPY5[1] EBI_DATA[1](2) > + * GPY5[2] EBI_DATA[2](2) > + * GPY5[3] EBI_DATA[3](2) > + * GPY5[4] EBI_DATA[4](2) > + * GPY5[5] EBI_DATA[5](2) > + * GPY5[6] EBI_DATA[6](2) > + * GPY5[7] EBI_DATA[7](2) > + * > + * GPY6[0] EBI_DATA[8](2) > + * GPY6[1] EBI_DATA[9](2) > + * GPY6[2] EBI_DATA[10](2) > + * GPY6[3] EBI_DATA[11](2) > + * GPY6[4] EBI_DATA[12](2) > + * GPY6[5] EBI_DATA[13](2) > + * GPY6[6] EBI_DATA[14](2) > + * GPY6[7] EBI_DATA[15](2) > + */ > + for (i = 0; i < 8; i++) { > + s5p_gpio_cfg_pin(&gpio2->y3, i, GPIO_FUNC(2)); > + s5p_gpio_set_pull(&gpio2->y3, i, GPIO_PULL_UP); > + > + s5p_gpio_cfg_pin(&gpio2->y5, i, GPIO_FUNC(2)); > + s5p_gpio_set_pull(&gpio2->y5, i, GPIO_PULL_UP); > + > + s5p_gpio_cfg_pin(&gpio2->y6, i, GPIO_FUNC(2)); > + s5p_gpio_set_pull(&gpio2->y6, i, GPIO_PULL_UP); > + } > +} > + > +static void exynos4_i2c_config(int peripheral, int flags) > +{ > + > + struct exynos4_gpio_part1 *gpio1 = > + (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1(); > + > + switch (peripheral) { > + case PERIPH_ID_I2C0: > + s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2)); > + s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2)); > + break; > + case PERIPH_ID_I2C1: > + s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2)); > + s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2)); > + break; > + case PERIPH_ID_I2C2: > + s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3)); > + s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3)); > + break; > + case PERIPH_ID_I2C3: > + s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3)); > + s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3)); > + break; > + case PERIPH_ID_I2C4: > + s5p_gpio_cfg_pin(&gpio1->b, 0, GPIO_FUNC(0x3)); > + s5p_gpio_cfg_pin(&gpio1->b, 1, GPIO_FUNC(0x3)); > + break; > + case PERIPH_ID_I2C5: > + s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3)); > + s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3)); > + break; > + case PERIPH_ID_I2C6: > + s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4)); > + s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4)); > + break; > + case PERIPH_ID_I2C7: > + s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3)); > + s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3)); > + break; > + } > +} > + > +static int exynos4_pinmux_config(int peripheral, int flags) > +{ > + switch (peripheral) { > + case PERIPH_ID_UART0: > + case PERIPH_ID_UART1: > + case PERIPH_ID_UART2: > + case PERIPH_ID_UART3: > + exynos4_uart_config(peripheral); > + break; > + case PERIPH_ID_SDMMC0: > + case PERIPH_ID_SDMMC1: > + case PERIPH_ID_SDMMC2: > + case PERIPH_ID_SDMMC3: > + return exynos4_mmc_config(peripheral, flags); > + case PERIPH_ID_SROMC: > + exynos4_sromc_config(flags); > + break; > + case PERIPH_ID_I2C0: > + case PERIPH_ID_I2C1: > + case PERIPH_ID_I2C2: > + case PERIPH_ID_I2C3: > + case PERIPH_ID_I2C4: > + case PERIPH_ID_I2C5: > + case PERIPH_ID_I2C6: > + case PERIPH_ID_I2C7: > + exynos4_i2c_config(peripheral, flags); > + break; > + default: > + debug("%s: invalid peripheral %d", __func__, peripheral); > + return -1; > + } > + > + return 0; > +} > + > static void exynos5_uart_config(int peripheral) > { > struct exynos5_gpio_part1 *gpio1 = > @@ -269,6 +508,8 @@ int exynos_pinmux_config(int peripheral, int flags) > { > if (cpu_is_exynos5()) > return exynos5_pinmux_config(peripheral, flags); > + else if (cpu_is_exynos4()) > + return exynos4_pinmux_config(peripheral, flags); > else { > debug("pinmux functionality not supported\n"); > return -1; > diff --git a/arch/arm/include/asm/arch-exynos/clock.h > b/arch/arm/include/asm/arch-exynos/clock.h > index fce38ef..e238810 100644 > --- a/arch/arm/include/asm/arch-exynos/clock.h > +++ b/arch/arm/include/asm/arch-exynos/clock.h > @@ -57,10 +57,20 @@ struct exynos4_clock { > unsigned char res16[0xec]; > unsigned int epll_con0; > unsigned int epll_con1; > +#ifdef CONFIG_EXYNOS4210 like above, how about to define 4412 specific clock? e.g., exynos4412_clock? > unsigned char res17[0x8]; > +#else > + unsigned int epll_con2; > + unsigned char res17[0x4]; > +#endif > unsigned int vpll_con0; > unsigned int vpll_con1; > +#ifdef CONFIG_EXYNOS4210 > unsigned char res18[0xe8]; > +#else > + unsigned int vpll_con2; > + unsigned char res18[0xe4]; > +#endif > unsigned int src_top0; > unsigned int src_top1; > unsigned char res19[0x8]; > @@ -161,7 +171,16 @@ struct exynos4_clock { > unsigned char res38[0x8c]; > unsigned int clkout_cmu_top; > unsigned int clkout_cmu_top_div_stat; > +#ifdef CONFIG_EXYNOS4210 > unsigned char res39[0x37f8]; > +#else > + unsigned char res39[0x3600]; > + unsigned int mpll_lock; > + unsigned char res3a[0xfc]; > + unsigned int mpll_con0; > + unsigned int mpll_con1; > + unsigned char res3b[0xf0]; > +#endif > unsigned int src_dmc; > unsigned char res40[0xfc]; > unsigned int src_mask_dmc; > @@ -195,14 +214,22 @@ struct exynos4_clock { > unsigned int maxperf; > unsigned char res51[0x2f78]; > unsigned int apll_lock; > +#ifdef CONFIG_EXYNOS4210 > unsigned char res52[0x4]; > unsigned int mpll_lock; > +#else > + unsigned char res52[0x8]; > +#endif > unsigned char res53[0xf4]; > unsigned int apll_con0; > unsigned int apll_con1; > +#ifdef CONFIG_EXYNOS4210 > unsigned int mpll_con0; > unsigned int mpll_con1; > unsigned char res54[0xf0]; > +#else > + unsigned char res54[0xf8]; > +#endif > unsigned int src_cpu; > unsigned char res55[0x1fc]; > unsigned int mux_stat_cpu; > diff --git a/arch/arm/include/asm/arch-exynos/cpu.h > b/arch/arm/include/asm/arch-exynos/cpu.h > index 2cd4ae1..d1117c0 100644 > --- a/arch/arm/include/asm/arch-exynos/cpu.h > +++ b/arch/arm/include/asm/arch-exynos/cpu.h > @@ -55,7 +55,11 @@ > #define EXYNOS4_MODEM_BASE 0x13A00000 > #define EXYNOS4_USBPHY_CONTROL 0x10020704 > > +#ifdef CONFIG_EXYNOS4412 > +#define EXYNOS4_GPIO_PART4_BASE 0x106E0000 > +#else > #define EXYNOS4_GPIO_PART4_BASE DEVICE_NOT_AVAILABLE > +#endif if it's only valid at exynos4412, then make it variable and configure it at runtime e.g.,
#define EXYNOS4412_GPIO_PART4_BASE 0x106E0000 #define EXYNOS4_GPIO_PART4_BASE DEVICE_NOT_AVAILABLE int exynos4_get_gpio_part4_base(void) { if (cpu_is_exynos4412()) return EXYNOS4412_GPIO_PART4_BASE; return EXYNOS4_GPIO_PART4_BASE; } Thank you, Kyungmin Park > #define EXYNOS4_DP_BASE DEVICE_NOT_AVAILABLE > > /* EXYNOS5 */ > diff --git a/arch/arm/include/asm/arch-exynos/gpio.h > b/arch/arm/include/asm/arch-exynos/gpio.h > index 97be4ea..9539aa0 100644 > --- a/arch/arm/include/asm/arch-exynos/gpio.h > +++ b/arch/arm/include/asm/arch-exynos/gpio.h > @@ -49,6 +49,9 @@ struct exynos4_gpio_part1 { > struct s5p_gpio_bank f1; > struct s5p_gpio_bank f2; > struct s5p_gpio_bank f3; > + struct s5p_gpio_bank res1[2]; > + struct s5p_gpio_bank j0; > + struct s5p_gpio_bank j1; > }; > > struct exynos4_gpio_part2 { > @@ -68,7 +71,13 @@ struct exynos4_gpio_part2 { > struct s5p_gpio_bank y4; > struct s5p_gpio_bank y5; > struct s5p_gpio_bank y6; > - struct s5p_gpio_bank res1[80]; > + struct s5p_gpio_bank res1[3]; > + struct s5p_gpio_bank m0; > + struct s5p_gpio_bank m1; > + struct s5p_gpio_bank m2; > + struct s5p_gpio_bank m3; > + struct s5p_gpio_bank m4; > + struct s5p_gpio_bank res2[72]; > struct s5p_gpio_bank x0; > struct s5p_gpio_bank x1; > struct s5p_gpio_bank x2; > @@ -79,6 +88,16 @@ struct exynos4_gpio_part3 { > struct s5p_gpio_bank z; > }; > > +struct exynos4_gpio_part4 { > + struct s5p_gpio_bank v0; > + struct s5p_gpio_bank v1; > + struct s5p_gpio_bank res1[1]; > + struct s5p_gpio_bank v2; > + struct s5p_gpio_bank v3; > + struct s5p_gpio_bank res2[1]; > + struct s5p_gpio_bank v4; > +}; > + > struct exynos5_gpio_part1 { > struct s5p_gpio_bank a0; > struct s5p_gpio_bank a1; > -- > 1.7.1 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot