[U-Boot] [PATCH/RFC] Support HSMMC2 and 3 on OMAP3.

Hugo Vincent hugo.vincent at gmail.com
Sun Jun 28 04:21:54 CEST 2009


Hi Minkyu

I've resent V2 of the patch to the list; hopefully it addresses your  
concerns.

On 28/06/2009, at 4:35 AM, Minkyu Kang wrote:
> Hi Hugo Vincent,
>
> 2009/6/27 Hugo Vincent <hugo.vincent at gmail.com>:
>> 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.
>>
>> 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/common/cmd_mmc.c b/common/cmd_mmc.c
>> index 039fe59..7b99603 100644
>> --- a/common/cmd_mmc.c
>> +++ b/common/cmd_mmc.c
>> @@ -65,11 +65,10 @@ int do_mmc (cmd_tbl_t *cmdtp, int flag, int argc,
>> char *argv[])
>>                        }
>>                } else if (argc == 3) {
>>                        dev = (int)simple_strtoul(argv[2], NULL, 10);
>> -
>> -#ifdef CONFIG_SYS_MMC_SET_DEV
>> -                       if (mmc_set_dev(dev) != 0)
>> +                       if (mmc_legacy_init(dev) != 0) {
>> +                               puts("No MMC card found\n");
>>                                return 1;
>> -#endif
>> +                       }
>>                        curr_device = dev;
>>                } else {
>>                        cmd_usage(cmdtp);
>
> why you reinit at "mmc device" command.
> If you want to device init and device selecting at one time.
> you can use mmc init command
> e.g: # mmc init <dev>

Reverted to how it was and defined CONFIG_SYS_MMC_SET_DEV in my board  
config.

>> diff --git a/drivers/mmc/omap3_mmc.c b/drivers/mmc/omap3_mmc.c
>> index 234fddf..a53fc3e 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)
>> @@ -135,7 +138,8 @@ unsigned char mmc_init_setup(void)
>>  {
>>        unsigned int reg_val;
>>
>> -       mmc_board_init();
>> +       if (mmc_get_dev_id() == 1)
>> +               mmc_board_init();
>
> do not need to init for mmc2/3 about VMMC and devconf?

There doesn't seem to be much commonality amongst different OMAP35xx  
boards as to how MMC2 and 3 are powered. My board (which uses a  
Gumstix Overo) only uses the TWL4030 for powering MMC1, whereas 2 and  
3 are powered externally. I've updated my patch with a comment to that  
effect. Note that some boards use a non-transparent transceiver/level  
translator on MMC2 that requires direction signals from the OMAP;  
supporting this would take a bit more work.

Similarly, PBIAS setup is only for MMC1.

>>        writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
>>                &mmc_base->sysconfig);
>> @@ -528,23 +532,58 @@ 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_id(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_id(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:
>> +                       return 1;
>> +       }
>> +}
>> +
> please check the style

Hope V2 is better. Please advise.

>
>> +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];
>>
>> _______________________________________________
>> U-Boot mailing list
>> U-Boot at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>>
>
> thanks.

Many thanks,
Hugo Vincent


More information about the U-Boot mailing list