[U-Boot] [PATCH V2] Support HSMMC2 and 3 on OMAP3
Hugo Vincent
hugo.vincent at gmail.com
Sun Jun 28 04:21:14 CEST 2009
Adds support for the second and third HSMMC controllers on OMAP3 SoCs.
Tested working on Gumstix Overo with a custom base-board containing
external SD/MMC slots.
Version 2 incorporating changes suggested by Minkyu Kang <promsoft at gmail.com
>
Signed-off-by: Hugo Vincent <hugo.vincent at gmail.com>
diff --git a/board/omap3/overo/overo.h b/board/omap3/overo/overo.h
index 4c06e6e..84c09da 100644
--- a/board/omap3/overo/overo.h
+++ b/board/omap3/overo/overo.h
@@ -292,7 +292,7 @@ const omap3_sysinfo sysinfo = {
MUX_VAL(CP(SYS_OFF_MODE), (IEN | PTD | DIS | M0)) /*SYS_OFF_MODE*/\
MUX_VAL(CP(SYS_CLKOUT1), (IEN | PTD | DIS | M0)) /*SYS_CLKOUT1*/\
MUX_VAL(CP(SYS_CLKOUT2), (IEN | PTU | EN | M4)) /*GPIO_186*/\
- MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTU | EN | M2)) /*MMC3_CLK*/\
+ MUX_VAL(CP(ETK_CLK_ES2), (IEN | PTU | EN | M2)) /*MMC3_CLK*/\
MUX_VAL(CP(ETK_CTL_ES2), (IEN | PTU | EN | M2)) /*MMC3_CMD*/\
MUX_VAL(CP(ETK_D0_ES2), (IEN | PTU | EN | M4)) /*GPIO_14*/\
MUX_VAL(CP(ETK_D1_ES2), (IEN | PTD | EN | M4)) /*GPIO_15 -
X_GATE*/\
diff --git a/drivers/mmc/omap3_mmc.c b/drivers/mmc/omap3_mmc.c
index 234fddf..813839b 100644
--- a/drivers/mmc/omap3_mmc.c
+++ b/drivers/mmc/omap3_mmc.c
@@ -50,12 +50,15 @@ const unsigned short mmc_transspeed_val[15][4] = {
};
mmc_card_data cur_card_data;
-static block_dev_desc_t mmc_blk_dev;
-static hsmmc_t *mmc_base = (hsmmc_t *)OMAP_HSMMC_BASE;
+static block_dev_desc_t mmc_blk_dev[3];
+static hsmmc_t *mmc_base = (hsmmc_t *)OMAP_HSMMC_BASE1;
block_dev_desc_t *mmc_get_dev(int dev)
{
- return (block_dev_desc_t *) &mmc_blk_dev;
+ if (dev >= 1 && dev <= 3)
+ return (block_dev_desc_t *) &mmc_blk_dev[dev-1];
+ else
+ return NULL;
}
void twl4030_mmc_config(void)
@@ -75,14 +78,22 @@ unsigned char mmc_board_init(void)
{
t2_t *t2_base = (t2_t *)T2_BASE;
- twl4030_mmc_config();
+ /*
+ * Power and transceiver setup for MMC controllers other than the
first
+ * differs between OMAP3xxx implementations. On at least Gumstix
Overo,
+ * no setup is required. FIXME HSMMC2 may require MMCSDIO2ADPCLKISEL
+ */
+ if (mmc_get_dev_id() == 1)
+ {
+ twl4030_mmc_config();
- writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 |
- PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0,
- &t2_base->pbias_lite);
+ writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 |
+ PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0,
+ &t2_base->pbias_lite);
- writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL,
- &t2_base->devconf0);
+ writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL,
+ &t2_base->devconf0);
+ }
return 1;
}
@@ -528,23 +539,59 @@ unsigned long mmc_bread(int dev_num, unsigned
long blknr, lbaint_t blkcnt,
return 1;
}
-int mmc_legacy_init(int verbose)
+int mmc_legacy_init(int dev)
{
+ mmc_set_dev(dev);
if (configure_mmc(&cur_card_data) != 1)
return 1;
- mmc_blk_dev.if_type = IF_TYPE_MMC;
- mmc_blk_dev.part_type = PART_TYPE_DOS;
- mmc_blk_dev.dev = 0;
- mmc_blk_dev.lun = 0;
- mmc_blk_dev.type = 0;
+ block_dev_desc_t *mmcdev = mmc_get_dev(dev);
+ if (mmcdev == NULL)
+ return 1;
+
+ mmcdev->if_type = IF_TYPE_MMC;
+ mmcdev->part_type = PART_TYPE_DOS;
+ mmcdev->dev = dev;
+ mmcdev->lun = 0;
+ mmcdev->type = 0;
/* FIXME fill in the correct size (is set to 32MByte) */
- mmc_blk_dev.blksz = MMCSD_SECTOR_SIZE;
- mmc_blk_dev.lba = 0x10000;
- mmc_blk_dev.removable = 0;
- mmc_blk_dev.block_read = mmc_bread;
+ mmcdev->blksz = MMCSD_SECTOR_SIZE;
+ mmcdev->lba = 0x10000;
+ mmcdev->removable = 0;
+ mmcdev->block_read = mmc_bread;
- fat_register_device(&mmc_blk_dev, 1);
+ fat_register_device(mmcdev, 1);
return 0;
}
+
+int mmc_set_dev(int devnum)
+{
+ switch (devnum) {
+ case 1:
+ mmc_base = (hsmmc_t *)OMAP_HSMMC_BASE1;
+ return 0;
+ case 2:
+ mmc_base = (hsmmc_t *)OMAP_HSMMC_BASE2;
+ return 0;
+ case 3:
+ mmc_base = (hsmmc_t *)OMAP_HSMMC_BASE3;
+ return 0;
+ default:
+ puts("No such MMC device\n");
+ return 1;
+ }
+}
+
+int mmc_get_dev_id()
+{
+ if (mmc_base == (hsmmc_t *)OMAP_HSMMC_BASE1)
+ return 1;
+ else if (mmc_base == (hsmmc_t *)OMAP_HSMMC_BASE2)
+ return 2;
+ else if (mmc_base == (hsmmc_t *)OMAP_HSMMC_BASE3)
+ return 3;
+ else
+ return -1;
+}
+
diff --git a/include/asm-arm/arch-omap3/clocks.h b/include/asm-arm/
arch-omap3/clocks.h
index 71a0cb6..7dc9366 100644
--- a/include/asm-arm/arch-omap3/clocks.h
+++ b/include/asm-arm/arch-omap3/clocks.h
@@ -31,8 +31,8 @@
#define S38_4M 38400000
#define FCK_IVA2_ON 0x00000001
-#define FCK_CORE1_ON 0x03fffe29
-#define ICK_CORE1_ON 0x3ffffffb
+#define FCK_CORE1_ON 0x43fffe29
+#define ICK_CORE1_ON 0x7ffffffb
#define ICK_CORE2_ON 0x0000001f
#define FCK_WKUP_ON 0x000000e9
#define ICK_WKUP_ON 0x0000003f
diff --git a/include/asm-arm/arch-omap3/mmc_host_def.h b/include/asm-
arm/arch-omap3/mmc_host_def.h
index aa751c9..606a1d0 100644
--- a/include/asm-arm/arch-omap3/mmc_host_def.h
+++ b/include/asm-arm/arch-omap3/mmc_host_def.h
@@ -44,7 +44,9 @@ typedef struct t2 {
/*
* OMAP HSMMC register definitions
*/
-#define OMAP_HSMMC_BASE 0x4809C000
+#define OMAP_HSMMC_BASE1 0x4809C000
+#define OMAP_HSMMC_BASE2 0x480B4000
+#define OMAP_HSMMC_BASE3 0x480AD000
typedef struct hsmmc {
unsigned char res1[0x10];
diff --git a/include/configs/omap3_overo.h b/include/configs/
omap3_overo.h
index fae46ff..bc35b9a 100644
--- a/include/configs/omap3_overo.h
+++ b/include/configs/omap3_overo.h
@@ -89,6 +89,7 @@
#define CONFIG_MMC 1
#define CONFIG_OMAP3_MMC 1
#define CONFIG_DOS_PARTITION 1
+#define CONFIG_SYS_MMC_SET_DEV 1
/* commands to include */
#include <config_cmd_default.h>
More information about the U-Boot
mailing list