[U-Boot] [PATCH V2] Support HSMMC2 and 3 on OMAP3

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@gmail.com
Signed-off-by: Hugo Vincent hugo.vincent@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>

On 14:21 Sun 28 Jun , Hugo Vincent wrote:
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@gmail.com
you patch is line wrapped It's not clear to me but how do you select the mmc controler??
Signed-off-by: Hugo Vincent hugo.vincent@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
please split in 2 patch one for the driver one for the board
@@ -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];
please add space before & after '-'
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);
var must be declare at the begenning of the function
- if (mmcdev == NULL)
if (!mmcdev)
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;
please use switch
Best Regards, J.
participants (2)
-
Hugo Vincent
-
Jean-Christophe PLAGNIOL-VILLARD