[U-Boot] [PATCH] mmc: sdhci: rework Samsung specfic code

Rob Herring robherring2 at gmail.com
Tue Jun 14 16:48:10 CEST 2011


From: Rob Herring <rob.herring at calxeda.com>

Create a common header sdhci.h and move register defintions there. 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 at calxeda.com>
---
Minkyu Kang,

Please take a look at the updated patch. I've implemented most

I moved the register definitions, but kept "struct mmc_host" within the .c
file. It is private to the driver.

I'm not sure if other devices have the same offsets. If so, the macro for the
device offset could be made more generic. I find the whole use of indexes to
calculate the base addresses to be fragile. It will work for some chips, but
is easily broken.

Rob

 arch/arm/include/asm/arch-s5pc1xx/mmc.h  |   73 ------------------------------
 arch/arm/include/asm/arch-s5pc2xx/cpu.h  |    4 ++
 arch/arm/include/asm/arch-s5pc2xx/mmc.h  |   73 ------------------------------
 board/samsung/goni/goni.c                |    4 +-
 board/samsung/universal_c210/universal.c |    6 +-
 drivers/mmc/sdhci.c                      |   31 +++++++------
 include/sdhci.h                          |   62 +++++++++++++++++++++++++
 7 files changed, 88 insertions(+), 165 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 adef4ee..0000000
--- a/arch/arm/include/asm/arch-s5pc1xx/mmc.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * (C) Copyright 2009 SAMSUNG Electronics
- * Minkyu Kang <mk7.kang at 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 dev_index;
-};
-
-int s5p_mmc_init(int dev_index, int bus_width);
-
-#endif	/* __ASSEMBLY__ */
-#endif
diff --git a/arch/arm/include/asm/arch-s5pc2xx/cpu.h b/arch/arm/include/asm/arch-s5pc2xx/cpu.h
index f9015c7..8113c90 100644
--- a/arch/arm/include/asm/arch-s5pc2xx/cpu.h
+++ b/arch/arm/include/asm/arch-s5pc2xx/cpu.h
@@ -108,6 +108,10 @@ SAMSUNG_BASE(uart, UART_BASE)
 SAMSUNG_BASE(usb_phy, USBPHY_BASE)
 SAMSUNG_BASE(usb_otg, USBOTG_BASE)
 SAMSUNG_BASE(watchdog, WATCHDOG_BASE)
+
+#define samsung_get_base_mmc_offset(idx)	(samsung_get_base_mmc() + \
+						 0x10000 * (idx))
+
 #endif
 
 #endif	/* _S5PC2XX_CPU_H */
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 30f82b8..0000000
--- a/arch/arm/include/asm/arch-s5pc2xx/mmc.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * (C) Copyright 2009 SAMSUNG Electronics
- * Minkyu Kang <mk7.kang at 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 dev_index;
-};
-
-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..047300b 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(0, samsung_get_base_mmc(), 4);
 }
 #endif
diff --git a/board/samsung/universal_c210/universal.c b/board/samsung/universal_c210/universal.c
index b65bc6e..cd67d8d 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(0, samsung_get_base_mmc_offset(0), 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(2, samsung_get_base_mmc_offset(2), 4);
 	}
 
 	return err;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 280738f..4bff345 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -20,20 +20,21 @@
 
 #include <common.h>
 #include <mmc.h>
+#include <sdhci.h>
 #include <asm/io.h>
-#include <asm/arch/mmc.h>
 #include <asm/arch/clk.h>
 
+struct mmc_host {
+	struct sdhci_mmc *reg;
+	unsigned int version;	/* SDHCI spec. version */
+	unsigned int clock;	/* Current clock (MHz) */
+	int dev_index;
+};
+
 /* 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);
-}
-
 static void mmc_prepare_data(struct mmc_host *host, struct mmc_data *data)
 {
 	unsigned char ctrl;
@@ -255,6 +256,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
@@ -265,7 +267,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 */
@@ -320,6 +322,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
@@ -349,7 +352,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);
@@ -445,13 +448,13 @@ 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(int dev_index, void *base, int bus_width)
 {
 	struct mmc *mmc;
 
 	mmc = &mmc_dev[dev_index];
 
-	sprintf(mmc->name, "SAMSUNG SD/MMC");
+	sprintf(mmc->name, "SDHCI SD/MMC");
 	mmc->priv = &mmc_host[dev_index];
 	mmc->send_cmd = mmc_send_cmd;
 	mmc->set_ios = mmc_set_ios;
@@ -469,14 +472,14 @@ static int s5p_mmc_initialize(int dev_index, int bus_width)
 
 	mmc_host[dev_index].dev_index = dev_index;
 	mmc_host[dev_index].clock = 0;
-	mmc_host[dev_index].reg = s5p_get_base_mmc(dev_index);
+	mmc_host[dev_index].reg = base;
 	mmc->b_max = 0;
 	mmc_register(mmc);
 
 	return 0;
 }
 
-int s5p_mmc_init(int dev_index, int bus_width)
+int sdhci_mmc_init(int dev_index, unsigned int base, int bus_width)
 {
-	return s5p_mmc_initialize(dev_index, bus_width);
+	return sdhci_mmc_initialize(dev_index, (void *)base, bus_width);
 }
diff --git a/include/sdhci.h b/include/sdhci.h
new file mode 100644
index 0000000..8ef381b
--- /dev/null
+++ b/include/sdhci.h
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright 2009 SAMSUNG Electronics
+ * Minkyu Kang <mk7.kang at 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 _SDHCI_H_
+#define _SDHCI_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;
+};
+
+int sdhci_mmc_init(int dev_index, unsigned int base, int bus_width);
+
+#endif
-- 
1.7.4.1



More information about the U-Boot mailing list