OMAP: mmc: add support for second and third mmc channels
authorSteve Sakoman <steve@sakoman.com>
Thu, 29 Apr 2010 17:28:14 +0000 (10:28 -0700)
committerSandeep Paulraj <s-paulraj@ti.com>
Mon, 5 Jul 2010 23:59:49 +0000 (19:59 -0400)
This patch adds support for the second and third mmc channels on OMAP3
processors

Boards wishing to use this feature should define CONFIG_SYS_MMC_SET_DEV
in the board config

Tested on Overo

Signed-off-by: Steve Sakoman <steve@sakoman.com>
Tested-by: Philip Balister <philip@opensdr.com>
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
arch/arm/include/asm/arch-omap3/mmc_host_def.h
drivers/mmc/omap3_mmc.c

index aa751c9..43dd705 100644 (file)
 #define T2_BASE                        0x48002000
 
 typedef struct t2 {
-       unsigned char res1[0x274];
+       unsigned char res1[0x274];      /* 0x000 */
        unsigned int devconf0;          /* 0x274 */
-       unsigned char res2[0x2A8];
+       unsigned char res2[0x060];      /* 0x278 */
+       unsigned int devconf1;          /* 0x2D8 */
+       unsigned char res3[0x244];      /* 0x2DC */
        unsigned int pbias_lite;        /* 0x520 */
 } t2_t;
 
 #define MMCSDIO1ADPCLKISEL             (1 << 24)
+#define MMCSDIO2ADPCLKISEL             (1 << 6)
+
+#define EN_MMC1                                (1 << 24)
+#define EN_MMC2                                (1 << 25)
+#define EN_MMC3                                (1 << 30)
 
 #define PBIASLITEPWRDNZ0               (1 << 1)
 #define PBIASSPEEDCTRL0                        (1 << 2)
@@ -44,7 +51,9 @@ typedef struct t2 {
 /*
  * OMAP HSMMC register definitions
  */
-#define OMAP_HSMMC_BASE                0x4809C000
+#define OMAP_HSMMC1_BASE       0x4809C000
+#define OMAP_HSMMC2_BASE       0x480B4000
+#define OMAP_HSMMC3_BASE       0x480AD000
 
 typedef struct hsmmc {
        unsigned char res1[0x10];
index 96c0e65..25b66f2 100644 (file)
@@ -52,7 +52,27 @@ 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 hsmmc_t *mmc_base = (hsmmc_t *)OMAP_HSMMC1_BASE;
+
+unsigned char mmc_set_dev(int dev)
+{
+       switch (dev) {
+       case 1:
+               mmc_base = (hsmmc_t *)OMAP_HSMMC1_BASE;
+               break;
+       case 2:
+               mmc_base = (hsmmc_t *)OMAP_HSMMC2_BASE;
+               break;
+       case 3:
+               mmc_base = (hsmmc_t *)OMAP_HSMMC3_BASE;
+               break;
+       default:
+               mmc_base = (hsmmc_t *)OMAP_HSMMC1_BASE;
+               return 1;
+       }
+
+       return 0;
+}
 
 block_dev_desc_t *mmc_get_dev(int dev)
 {
@@ -62,6 +82,7 @@ block_dev_desc_t *mmc_get_dev(int dev)
 unsigned char mmc_board_init(void)
 {
        t2_t *t2_base = (t2_t *)T2_BASE;
+       struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
 
 #if defined(CONFIG_TWL4030_POWER)
        twl4030_power_mmc_init();
@@ -74,6 +95,17 @@ unsigned char mmc_board_init(void)
        writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL,
                &t2_base->devconf0);
 
+       writel(readl(&t2_base->devconf1) | MMCSDIO2ADPCLKISEL,
+               &t2_base->devconf1);
+
+       writel(readl(&prcm_base->fclken1_core) |
+               EN_MMC1 | EN_MMC2 | EN_MMC3,
+               &prcm_base->fclken1_core);
+
+       writel(readl(&prcm_base->iclken1_core) |
+               EN_MMC1 | EN_MMC2 | EN_MMC3,
+               &prcm_base->iclken1_core);
+
        return 1;
 }
 
@@ -512,8 +544,11 @@ 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)
 {
+       if (mmc_set_dev(dev) != 0)
+               return 1;
+
        if (configure_mmc(&cur_card_data) != 1)
                return 1;