diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index df8d14974c90..69b48a7d1dbd 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig @@ -31,6 +31,17 @@ config S3C2416_PM help Internal config node to apply S3C2416 power management +config S3C2416_SETUP_SDHCI + bool + select S3C2416_SETUP_SDHCI_GPIO + help + Internal helper functions for S3C2416 based SDHCI systems + +config S3C2416_SETUP_SDHCI_GPIO + bool + help + Common setup code for SDHCI gpio. + menu "S3C2416 Machines" config MACH_SMDK2416 @@ -42,6 +53,7 @@ config MACH_SMDK2416 select S3C_DEV_HSMMC1 select S3C_DEV_NAND select S3C_DEV_USB_HOST + select S3C2416_SETUP_SDHCI select S3C2416_PM if PM help Say Y here if you are using an SMDK2416 diff --git a/arch/arm/mach-s3c2416/Makefile b/arch/arm/mach-s3c2416/Makefile index ef038d62ffdb..7b805b279caf 100644 --- a/arch/arm/mach-s3c2416/Makefile +++ b/arch/arm/mach-s3c2416/Makefile @@ -14,6 +14,10 @@ obj-$(CONFIG_CPU_S3C2416) += irq.o obj-$(CONFIG_S3C2416_PM) += pm.o #obj-$(CONFIG_S3C2416_DMA) += dma.o +# Device setup +obj-$(CONFIG_S3C2416_SETUP_SDHCI) += setup-sdhci.o +obj-$(CONFIG_S3C2416_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o + # Machine support obj-$(CONFIG_MACH_SMDK2416) += mach-smdk2416.o diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c index 63f39cdc0972..ba7fd8737434 100644 --- a/arch/arm/mach-s3c2416/s3c2416.c +++ b/arch/arm/mach-s3c2416/s3c2416.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -115,6 +116,10 @@ void __init s3c2416_map_io(void) s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_updown; s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_updown; + /* initialize device information early */ + s3c2416_default_sdhci0(); + s3c2416_default_sdhci1(); + iotable_init(s3c2416_iodesc, ARRAY_SIZE(s3c2416_iodesc)); } diff --git a/arch/arm/mach-s3c2416/setup-sdhci-gpio.c b/arch/arm/mach-s3c2416/setup-sdhci-gpio.c new file mode 100644 index 000000000000..f65cb3ef16ce --- /dev/null +++ b/arch/arm/mach-s3c2416/setup-sdhci-gpio.c @@ -0,0 +1,34 @@ +/* linux/arch/arm/plat-s3c2416/setup-sdhci-gpio.c + * + * Copyright 2010 Promwad Innovation Company + * Yauhen Kharuzhy + * + * S3C2416 - Helper functions for setting up SDHCI device(s) GPIO (HSMMC) + * + * Based on mach-s3c64xx/setup-sdhci-gpio.c + * + * 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 +#include +#include +#include +#include +#include + +#include +#include + +void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) +{ + s3c_gpio_cfgrange_nopull(S3C2410_GPE(5), 2 + width, S3C_GPIO_SFN(2)); +} + +void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) +{ + s3c_gpio_cfgrange_nopull(S3C2410_GPL(0), width, S3C_GPIO_SFN(2)); + s3c_gpio_cfgrange_nopull(S3C2410_GPL(8), 2, S3C_GPIO_SFN(2)); +} diff --git a/arch/arm/mach-s3c2416/setup-sdhci.c b/arch/arm/mach-s3c2416/setup-sdhci.c new file mode 100644 index 000000000000..ed34fad8f2c6 --- /dev/null +++ b/arch/arm/mach-s3c2416/setup-sdhci.c @@ -0,0 +1,61 @@ +/* linux/arch/arm/mach-s3c2416/setup-sdhci.c + * + * Copyright 2010 Promwad Innovation Company + * Yauhen Kharuzhy + * + * S3C2416 - Helper functions for settign up SDHCI device(s) (HSMMC) + * + * Based on mach-s3c64xx/setup-sdhci.c + * + * 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 +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ + +char *s3c2416_hsmmc_clksrcs[4] = { + [0] = "hsmmc", + [1] = "hsmmc", + [2] = "hsmmc-if", + /* [3] = "48m", - note not successfully used yet */ +}; + +void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev, + void __iomem *r, + struct mmc_ios *ios, + struct mmc_card *card) +{ + u32 ctrl2, ctrl3; + + ctrl2 = __raw_readl(r + S3C_SDHCI_CONTROL2); + ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK; + ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR | + S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK | + S3C_SDHCI_CTRL2_ENFBCLKRX | + S3C_SDHCI_CTRL2_DFCNT_NONE | + S3C_SDHCI_CTRL2_ENCLKOUTHOLD); + + if (ios->clock < 25 * 1000000) + ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 | + S3C_SDHCI_CTRL3_FCSEL2 | + S3C_SDHCI_CTRL3_FCSEL1 | + S3C_SDHCI_CTRL3_FCSEL0); + else + ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0); + + __raw_writel(ctrl2, r + S3C_SDHCI_CONTROL2); + __raw_writel(ctrl3, r + S3C_SDHCI_CONTROL3); +} diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h index 85853f8c4c5d..5a41a0b69eec 100644 --- a/arch/arm/plat-samsung/include/plat/sdhci.h +++ b/arch/arm/plat-samsung/include/plat/sdhci.h @@ -107,6 +107,8 @@ extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata; /* Helper function availablity */ +extern void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *, int w); +extern void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *, int w); extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w); extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w); extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w); @@ -122,6 +124,39 @@ extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w); extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w); extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w); +/* S3C2416 SDHCI setup */ + +#ifdef CONFIG_S3C2416_SETUP_SDHCI +extern char *s3c2416_hsmmc_clksrcs[4]; + +extern void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev, + void __iomem *r, + struct mmc_ios *ios, + struct mmc_card *card); + +static inline void s3c2416_default_sdhci0(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC + s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs; + s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio; + s3c_hsmmc0_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card; +#endif /* CONFIG_S3C_DEV_HSMMC */ +} + +static inline void s3c2416_default_sdhci1(void) +{ +#ifdef CONFIG_S3C_DEV_HSMMC1 + s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs; + s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio; + s3c_hsmmc1_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card; +#endif /* CONFIG_S3C_DEV_HSMMC1 */ +} + +#else +static inline void s3c2416_default_sdhci0(void) { } +static inline void s3c2416_default_sdhci1(void) { } + +#endif /* CONFIG_S3C2416_SETUP_SDHCI */ /* S3C64XX SDHCI setup */ #ifdef CONFIG_S3C64XX_SETUP_SDHCI