
From: Rob Herring rob.herring@calxeda.com
Move the register definitions into the sdhci.c file. Set the base address from the board init code.
The Samsung SDHCI controller has extra registers. Make them conditional on CONFIG_MMC_S5P.
Signed-off-by: Rob Herring rob.herring@calxeda.com --- arch/arm/include/asm/arch-s5pc1xx/mmc.h | 72 --------------------------- arch/arm/include/asm/arch-s5pc2xx/mmc.h | 72 --------------------------- board/samsung/goni/goni.c | 4 +- board/samsung/universal_c210/universal.c | 6 +- drivers/mmc/sdhci.c | 79 +++++++++++++++++++++++------ include/sdhci.h | 18 +++++++ 6 files changed, 85 insertions(+), 166 deletions(-) delete mode 100644 arch/arm/include/asm/arch-s5pc1xx/mmc.h delete mode 100644 arch/arm/include/asm/arch-s5pc2xx/mmc.h create mode 100644 include/sdhci.h
diff --git a/arch/arm/include/asm/arch-s5pc1xx/mmc.h b/arch/arm/include/asm/arch-s5pc1xx/mmc.h deleted file mode 100644 index d458d3b..0000000 --- a/arch/arm/include/asm/arch-s5pc1xx/mmc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * (C) Copyright 2009 SAMSUNG Electronics - * Minkyu Kang mk7.kang@samsung.com - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASM_ARCH_MMC_H_ -#define __ASM_ARCH_MMC_H_ - -#ifndef __ASSEMBLY__ -struct s5p_mmc { - unsigned int sysad; - unsigned short blksize; - unsigned short blkcnt; - unsigned int argument; - unsigned short trnmod; - unsigned short cmdreg; - unsigned int rspreg0; - unsigned int rspreg1; - unsigned int rspreg2; - unsigned int rspreg3; - unsigned int bdata; - unsigned int prnsts; - unsigned char hostctl; - unsigned char pwrcon; - unsigned char blkgap; - unsigned char wakcon; - unsigned short clkcon; - unsigned char timeoutcon; - unsigned char swrst; - unsigned int norintsts; /* errintsts */ - unsigned int norintstsen; /* errintstsen */ - unsigned int norintsigen; /* errintsigen */ - unsigned short acmd12errsts; - unsigned char res1[2]; - unsigned int capareg; - unsigned char res2[4]; - unsigned int maxcurr; - unsigned char res3[0x34]; - unsigned int control2; - unsigned int control3; - unsigned char res4[4]; - unsigned int control4; - unsigned char res5[0x6e]; - unsigned short hcver; - unsigned char res6[0xFFF00]; -}; - -struct mmc_host { - struct s5p_mmc *reg; - unsigned int version; /* SDHCI spec. version */ - unsigned int clock; /* Current clock (MHz) */ -}; - -int s5p_mmc_init(int dev_index, int bus_width); - -#endif /* __ASSEMBLY__ */ -#endif diff --git a/arch/arm/include/asm/arch-s5pc2xx/mmc.h b/arch/arm/include/asm/arch-s5pc2xx/mmc.h deleted file mode 100644 index 04827ca..0000000 --- a/arch/arm/include/asm/arch-s5pc2xx/mmc.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * (C) Copyright 2009 SAMSUNG Electronics - * Minkyu Kang mk7.kang@samsung.com - * - * 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#ifndef __ASM_ARCH_MMC_H_ -#define __ASM_ARCH_MMC_H_ - -#ifndef __ASSEMBLY__ -struct s5p_mmc { - unsigned int sysad; - unsigned short blksize; - unsigned short blkcnt; - unsigned int argument; - unsigned short trnmod; - unsigned short cmdreg; - unsigned int rspreg0; - unsigned int rspreg1; - unsigned int rspreg2; - unsigned int rspreg3; - unsigned int bdata; - unsigned int prnsts; - unsigned char hostctl; - unsigned char pwrcon; - unsigned char blkgap; - unsigned char wakcon; - unsigned short clkcon; - unsigned char timeoutcon; - unsigned char swrst; - unsigned int norintsts; /* errintsts */ - unsigned int norintstsen; /* errintstsen */ - unsigned int norintsigen; /* errintsigen */ - unsigned short acmd12errsts; - unsigned char res1[2]; - unsigned int capareg; - unsigned char res2[4]; - unsigned int maxcurr; - unsigned char res3[0x34]; - unsigned int control2; - unsigned int control3; - unsigned char res4[4]; - unsigned int control4; - unsigned char res5[0x6e]; - unsigned short hcver; - unsigned char res6[0xFF00]; -}; - -struct mmc_host { - struct s5p_mmc *reg; - unsigned int version; /* SDHCI spec. version */ - unsigned int clock; /* Current clock (MHz) */ -}; - -int s5p_mmc_init(int dev_index, int bus_width); - -#endif /* __ASSEMBLY__ */ -#endif diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c index 581935d..8e56f93 100644 --- a/board/samsung/goni/goni.c +++ b/board/samsung/goni/goni.c @@ -23,8 +23,8 @@ */
#include <common.h> +#include <sdhci.h> #include <asm/arch/gpio.h> -#include <asm/arch/mmc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -93,6 +93,6 @@ int board_mmc_init(bd_t *bis) gpio_set_drv(&s5pc110_gpio->g0, i, GPIO_DRV_4X); }
- return s5p_mmc_init(0, 4); + return sdhci_mmc_init((void *)samsung_get_base_mmc(), 4); } #endif diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c index b65bc6e..27cdce4 100644 --- a/board/samsung/universal_c210/universal.c +++ b/board/samsung/universal_c210/universal.c @@ -23,10 +23,10 @@ */
#include <common.h> +#include <sdhci.h> #include <asm/io.h> #include <asm/arch/adc.h> #include <asm/arch/gpio.h> -#include <asm/arch/mmc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -217,7 +217,7 @@ int board_mmc_init(bd_t *bis) * mmc0 : eMMC (8-bit buswidth) * mmc2 : SD card (4-bit buswidth) */ - err = s5p_mmc_init(0, 8); + err = sdhci_mmc_init((void *)samsung_get_base_mmc(), 8);
/* * Check the T-flash detect pin @@ -241,7 +241,7 @@ int board_mmc_init(bd_t *bis) /* GPK2[0:6] drv 4x */ gpio_set_drv(&gpio2->k2, i, GPIO_DRV_4X); } - err = s5p_mmc_init(2, 4); + err = sdhci_mmc_init((void *)(samsung_get_base_mmc() + 0x20000), 4); }
return err; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 668c28b..f184821 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -21,17 +21,54 @@ #include <common.h> #include <mmc.h> #include <asm/io.h> -#include <asm/arch/mmc.h> + +struct sdhci_mmc { + unsigned int sysad; + unsigned short blksize; + unsigned short blkcnt; + unsigned int argument; + unsigned short trnmod; + unsigned short cmdreg; + unsigned int rspreg0; + unsigned int rspreg1; + unsigned int rspreg2; + unsigned int rspreg3; + unsigned int bdata; + unsigned int prnsts; + unsigned char hostctl; + unsigned char pwrcon; + unsigned char blkgap; + unsigned char wakcon; + unsigned short clkcon; + unsigned char timeoutcon; + unsigned char swrst; + unsigned int norintsts; /* errintsts */ + unsigned int norintstsen; /* errintstsen */ + unsigned int norintsigen; /* errintsigen */ + unsigned short acmd12errsts; + unsigned char res1[2]; + unsigned int capareg; + unsigned char res2[4]; + unsigned int maxcurr; + unsigned char res3[0x34]; + unsigned int control2; + unsigned int control3; + unsigned char res4[4]; + unsigned int control4; + unsigned char res5[0x6e]; + unsigned short hcver; +}; + +struct mmc_host { + struct sdhci_mmc *reg; + unsigned int version; /* SDHCI spec. version */ + unsigned int clock; /* Current clock (MHz) */ +};
/* support 4 mmc hosts */ struct mmc mmc_dev[4]; struct mmc_host mmc_host[4]; - -static inline struct s5p_mmc *s5p_get_base_mmc(int dev_index) -{ - unsigned long offset = dev_index * sizeof(struct s5p_mmc); - return (struct s5p_mmc *)(samsung_get_base_mmc() + offset); -} +int dev_count;
static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data) { @@ -254,6 +291,7 @@ static void mmc_change_clock(struct mmc_host *host, uint clock) unsigned long timeout; unsigned long ctrl2;
+#ifdef CONFIG_S5P_MMC /* * SELBASECLK[5:4] * 00/01 = HCLK @@ -264,7 +302,7 @@ static void mmc_change_clock(struct mmc_host *host, uint clock) ctrl2 &= ~(3 << 4); ctrl2 |= (2 << 4); writel(ctrl2, &host->reg->control2); - +#endif writew(0, &host->reg->clkcon);
/* XXX: we assume that clock is between 40MHz and 50MHz */ @@ -317,6 +355,7 @@ static void mmc_set_ios(struct mmc *mmc)
debug("bus_width: %x, clock: %d\n", mmc->bus_width, mmc->clock);
+#ifdef CONFIG_S5P_MMC /* * SELCLKPADDS[17:16] * 00 = 2mA @@ -346,7 +385,7 @@ static void mmc_set_ios(struct mmc *mmc) * 10 = Delay4 (inverter delay + 2ns) */ writel(0x8080, &host->reg->control3); - +#endif mmc_change_clock(host, mmc->clock);
ctrl = readb(&host->reg->hostctl); @@ -442,14 +481,20 @@ static int mmc_core_init(struct mmc *mmc) return 0; }
-static int s5p_mmc_initialize(int dev_index, int bus_width) +static int sdhci_mmc_initialize(void *base, int bus_width) { struct mmc *mmc; + struct mmc_host *host; + + if (dev_count >= 4) + return -1;
- mmc = &mmc_dev[dev_index]; + mmc = &mmc_dev[dev_count]; + host = &mmc_host[dev_count]; + dev_count++;
- sprintf(mmc->name, "SAMSUNG SD/MMC"); - mmc->priv = &mmc_host[dev_index]; + sprintf(mmc->name, "SDHCI SD/MMC"); + mmc->priv = host; mmc->send_cmd = mmc_send_cmd; mmc->set_ios = mmc_set_ios; mmc->init = mmc_core_init; @@ -464,15 +509,15 @@ static int s5p_mmc_initialize(int dev_index, int bus_width) mmc->f_min = 400000; mmc->f_max = 52000000;
- mmc_host[dev_index].clock = 0; - mmc_host[dev_index].reg = s5p_get_base_mmc(dev_index); + host->clock = 0; + host->reg = base; mmc->m_bmax = 0; mmc_register(mmc);
return 0; }
-int s5p_mmc_init(int dev_index, int bus_width) +int sdhci_mmc_init(void *base, int bus_width) { - return s5p_mmc_initialize(dev_index, bus_width); + return sdhci_mmc_initialize(base, bus_width); } diff --git a/include/sdhci.h b/include/sdhci.h new file mode 100644 index 0000000..cc29415 --- /dev/null +++ b/include/sdhci.h @@ -0,0 +1,18 @@ +/* + * Copyright 2011 Calxeda, Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see http://www.gnu.org/licenses/. + */ + +int sdhci_mmc_init(void *base, int bus_width); +