]> git.sur5r.net Git - u-boot/blobdiff - drivers/mmc/omap3_mmc.c
Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
[u-boot] / drivers / mmc / omap3_mmc.c
index 399c57b70545bec8f757fceef60a9a23ca385e22..9506cca21816bd063faf04c70a51d490b33159a3 100644 (file)
 #include <mmc.h>
 #include <part.h>
 #include <i2c.h>
-#include <asm/arch/mmc.h>
+#include <twl4030.h>
+#include <asm/io.h>
+
+#include "omap3_mmc.h"
 
 const unsigned short mmc_transspeed_val[15][4] = {
        {CLKD(10, 1), CLKD(10, 10), CLKD(10, 100), CLKD(10, 1000)},
@@ -50,65 +53,88 @@ 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_HSMMC1_BASE;
 
-block_dev_desc_t *mmc_get_dev(int dev)
+int mmc_set_dev(int dev_num)
 {
-       return (block_dev_desc_t *) &mmc_blk_dev;
+       switch (dev_num) {
+       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;
 }
 
-void twl4030_mmc_config(void)
+block_dev_desc_t *mmc_get_dev(int dev)
 {
-       unsigned char data;
-
-       data = 0x20;
-       i2c_write(0x4B, 0x82, 1, &data, 1);
-       data = 0x2;
-       i2c_write(0x4B, 0x85, 1, &data, 1);
+       return (block_dev_desc_t *) &mmc_blk_dev;
 }
 
 unsigned char mmc_board_init(void)
 {
-       unsigned int value = 0;
+#if defined(CONFIG_TWL4030_POWER)
+       twl4030_power_mmc_init();
+#endif
+
+#if defined(CONFIG_OMAP34XX)
+       t2_t *t2_base = (t2_t *)T2_BASE;
+       struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
+
+       writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 |
+               PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0,
+               &t2_base->pbias_lite);
+
+       writel(readl(&t2_base->devconf0) | MMCSDIO1ADPCLKISEL,
+               &t2_base->devconf0);
 
-       twl4030_mmc_config();
+       writel(readl(&t2_base->devconf1) | MMCSDIO2ADPCLKISEL,
+               &t2_base->devconf1);
 
-       value = CONTROL_PBIAS_LITE;
-       CONTROL_PBIAS_LITE = value | (1 << 2) | (1 << 1) | (1 << 9);
+       writel(readl(&prcm_base->fclken1_core) |
+               EN_MMC1 | EN_MMC2 | EN_MMC3,
+               &prcm_base->fclken1_core);
 
-       value = CONTROL_DEV_CONF0;
-       CONTROL_DEV_CONF0 = value | (1 << 24);
+       writel(readl(&prcm_base->iclken1_core) |
+               EN_MMC1 | EN_MMC2 | EN_MMC3,
+               &prcm_base->iclken1_core);
+#endif
+
+/* TODO add appropriate OMAP4 init */
 
        return 1;
 }
 
 void mmc_init_stream(void)
 {
-       volatile unsigned int mmc_stat;
+       writel(readl(&mmc_base->con) | INIT_INITSTREAM, &mmc_base->con);
 
-       OMAP_HSMMC_CON |= INIT_INITSTREAM;
+       writel(MMC_CMD0, &mmc_base->cmd);
+       while (!(readl(&mmc_base->stat) & CC_MASK));
 
-       OMAP_HSMMC_CMD = MMC_CMD0;
-       do {
-               mmc_stat = OMAP_HSMMC_STAT;
-       } while (!(mmc_stat & CC_MASK));
+       writel(CC_MASK, &mmc_base->stat);
 
-       OMAP_HSMMC_STAT = CC_MASK;
+       writel(MMC_CMD0, &mmc_base->cmd);
+       while (!(readl(&mmc_base->stat) & CC_MASK));
 
-       OMAP_HSMMC_CMD = MMC_CMD0;
-       do {
-               mmc_stat = OMAP_HSMMC_STAT;
-       } while (!(mmc_stat & CC_MASK));
-
-       OMAP_HSMMC_STAT = OMAP_HSMMC_STAT;
-       OMAP_HSMMC_CON &= ~INIT_INITSTREAM;
+       writel(readl(&mmc_base->con) & ~INIT_INITSTREAM, &mmc_base->con);
 }
 
 unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div)
 {
        unsigned int val;
 
-       mmc_reg_out(OMAP_HSMMC_SYSCTL, (ICE_MASK | DTO_MASK | CEN_MASK),
-                   (ICE_STOP | DTO_15THDTO | CEN_DISABLE));
+       mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK),
+                       (ICE_STOP | DTO_15THDTO | CEN_DISABLE));
 
        switch (iclk) {
        case CLK_INITSEQ:
@@ -123,12 +149,12 @@ unsigned char mmc_clock_config(unsigned int iclk, unsigned short clk_div)
        default:
                return 0;
        }
-       mmc_reg_out(OMAP_HSMMC_SYSCTL,
-                   ICE_MASK | CLKD_MASK, (val << CLKD_OFFSET) | ICE_OSCILLATE);
+       mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK,
+                       (val << CLKD_OFFSET) | ICE_OSCILLATE);
 
-       while ((OMAP_HSMMC_SYSCTL & ICS_MASK) == ICS_NOTREADY) ;
+       while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY);
 
-       OMAP_HSMMC_SYSCTL |= CEN_ENABLE;
+       writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl);
        return 1;
 }
 
@@ -138,59 +164,63 @@ unsigned char mmc_init_setup(void)
 
        mmc_board_init();
 
-       OMAP_HSMMC_SYSCONFIG |= MMC_SOFTRESET;
-       while ((OMAP_HSMMC_SYSSTATUS & RESETDONE) == 0) ;
+       writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
+               &mmc_base->sysconfig);
+       while ((readl(&mmc_base->sysstatus) & RESETDONE) == 0);
 
-       OMAP_HSMMC_SYSCTL |= SOFTRESETALL;
-       while ((OMAP_HSMMC_SYSCTL & SOFTRESETALL) != 0x0) ;
+       writel(readl(&mmc_base->sysctl) | SOFTRESETALL, &mmc_base->sysctl);
+       while ((readl(&mmc_base->sysctl) & SOFTRESETALL) != 0x0);
 
-       OMAP_HSMMC_HCTL = DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0;
-       OMAP_HSMMC_CAPA |= VS30_3V0SUP | VS18_1V8SUP;
+       writel(DTW_1_BITMODE | SDBP_PWROFF | SDVS_3V0, &mmc_base->hctl);
+       writel(readl(&mmc_base->capa) | VS30_3V0SUP | VS18_1V8SUP,
+               &mmc_base->capa);
 
-       reg_val = OMAP_HSMMC_CON & RESERVED_MASK;
+       reg_val = readl(&mmc_base->con) & RESERVED_MASK;
 
-       OMAP_HSMMC_CON = CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH |
-               CDP_ACTIVEHIGH | MIT_CTO | DW8_1_4BITMODE | MODE_FUNC |
-               STR_BLOCK | HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN;
+       writel(CTPL_MMC_SD | reg_val | WPP_ACTIVEHIGH | CDP_ACTIVEHIGH |
+               MIT_CTO | DW8_1_4BITMODE | MODE_FUNC | STR_BLOCK |
+               HR_NOHOSTRESP | INIT_NOINIT | NOOPENDRAIN, &mmc_base->con);
 
        mmc_clock_config(CLK_INITSEQ, 0);
-       OMAP_HSMMC_HCTL |= SDBP_PWRON;
+       writel(readl(&mmc_base->hctl) | SDBP_PWRON, &mmc_base->hctl);
 
-       OMAP_HSMMC_IE = 0x307f0033;
+       writel(IE_BADA | IE_CERR | IE_DEB | IE_DCRC | IE_DTO | IE_CIE |
+               IE_CEB | IE_CCRC | IE_CTO | IE_BRR | IE_BWR | IE_TC | IE_CC,
+               &mmc_base->ie);
 
        mmc_init_stream();
        return 1;
 }
 
 unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg,
-                          unsigned int *response)
+                               unsigned int *response)
 {
-       volatile unsigned int mmc_stat;
+       unsigned int mmc_stat;
 
-       while ((OMAP_HSMMC_PSTATE & DATI_MASK) == DATI_CMDDIS) ;
+       while ((readl(&mmc_base->pstate) & DATI_MASK) == DATI_CMDDIS);
 
-       OMAP_HSMMC_BLK = BLEN_512BYTESLEN | NBLK_STPCNT;
-       OMAP_HSMMC_STAT = 0xFFFFFFFF;
-       OMAP_HSMMC_ARG = arg;
-       OMAP_HSMMC_CMD = cmd | CMD_TYPE_NORMAL | CICE_NOCHECK |
-           CCCE_NOCHECK | MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE |
-           DE_DISABLE;
+       writel(BLEN_512BYTESLEN | NBLK_STPCNT, &mmc_base->blk);
+       writel(0xFFFFFFFF, &mmc_base->stat);
+       writel(arg, &mmc_base->arg);
+       writel(cmd | CMD_TYPE_NORMAL | CICE_NOCHECK | CCCE_NOCHECK |
+               MSBS_SGLEBLK | ACEN_DISABLE | BCE_DISABLE | DE_DISABLE,
+               &mmc_base->cmd);
 
        while (1) {
                do {
-                       mmc_stat = OMAP_HSMMC_STAT;
+                       mmc_stat = readl(&mmc_base->stat);
                } while (mmc_stat == 0);
 
                if ((mmc_stat & ERRI_MASK) != 0)
                        return (unsigned char) mmc_stat;
 
                if (mmc_stat & CC_MASK) {
-                       OMAP_HSMMC_STAT = CC_MASK;
-                       response[0] = OMAP_HSMMC_RSP10;
+                       writel(CC_MASK, &mmc_base->stat);
+                       response[0] = readl(&mmc_base->rsp10);
                        if ((cmd & RSP_TYPE_MASK) == RSP_TYPE_LGHT136) {
-                               response[1] = OMAP_HSMMC_RSP32;
-                               response[2] = OMAP_HSMMC_RSP54;
-                               response[3] = OMAP_HSMMC_RSP76;
+                               response[1] = readl(&mmc_base->rsp32);
+                               response[2] = readl(&mmc_base->rsp54);
+                               response[3] = readl(&mmc_base->rsp76);
                        }
                        break;
                }
@@ -200,7 +230,7 @@ unsigned char mmc_send_cmd(unsigned int cmd, unsigned int arg,
 
 unsigned char mmc_read_data(unsigned int *output_buf)
 {
-       volatile unsigned int mmc_stat;
+       unsigned int mmc_stat;
        unsigned int read_count = 0;
 
        /*
@@ -208,7 +238,7 @@ unsigned char mmc_read_data(unsigned int *output_buf)
         */
        while (1) {
                do {
-                       mmc_stat = OMAP_HSMMC_STAT;
+                       mmc_stat = readl(&mmc_base->stat);
                } while (mmc_stat == 0);
 
                if ((mmc_stat & ERRI_MASK) != 0)
@@ -217,19 +247,22 @@ unsigned char mmc_read_data(unsigned int *output_buf)
                if (mmc_stat & BRR_MASK) {
                        unsigned int k;
 
-                       OMAP_HSMMC_STAT |= BRR_MASK;
+                       writel(readl(&mmc_base->stat) | BRR_MASK,
+                               &mmc_base->stat);
                        for (k = 0; k < MMCSD_SECTOR_SIZE / 4; k++) {
-                               *output_buf = OMAP_HSMMC_DATA;
+                               *output_buf = readl(&mmc_base->data);
                                output_buf++;
                                read_count += 4;
                        }
                }
 
                if (mmc_stat & BWR_MASK)
-                       OMAP_HSMMC_STAT |= BWR_MASK;
+                       writel(readl(&mmc_base->stat) | BWR_MASK,
+                               &mmc_base->stat);
 
                if (mmc_stat & TC_MASK) {
-                       OMAP_HSMMC_STAT |= TC_MASK;
+                       writel(readl(&mmc_base->stat) | TC_MASK,
+                               &mmc_base->stat);
                        break;
                }
        }
@@ -241,8 +274,8 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
        unsigned char err;
        unsigned int argument = 0;
        unsigned int ocr_value, ocr_recvd, ret_cmd41, hcs_val;
-       unsigned int resp[4];
        unsigned short retry_cnt = 2000;
+       mmc_resp_t mmc_resp;
 
        /* Set to Initialization Clock */
        err = mmc_clock_config(CLK_400KHZ, 0);
@@ -253,18 +286,18 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
        argument = 0x00000000;
 
        ocr_value = (0x1FF << 15);
-       err = mmc_send_cmd(MMC_CMD0, argument, resp);
+       err = mmc_send_cmd(MMC_CMD0, argument, mmc_resp.resp);
        if (err != 1)
                return err;
 
        argument = SD_CMD8_CHECK_PATTERN | SD_CMD8_2_7_3_6_V_RANGE;
-       err = mmc_send_cmd(MMC_SDCMD8, argument, resp);
+       err = mmc_send_cmd(MMC_SDCMD8, argument, mmc_resp.resp);
        hcs_val = (err == 1) ?
                MMC_OCR_REG_HOST_CAPACITY_SUPPORT_SECTOR :
                MMC_OCR_REG_HOST_CAPACITY_SUPPORT_BYTE;
 
        argument = 0x0000 << 16;
-       err = mmc_send_cmd(MMC_CMD55, argument, resp);
+       err = mmc_send_cmd(MMC_CMD55, argument, mmc_resp.resp);
        if (err == 1) {
                mmc_card_cur->card_type = SD_CARD;
                ocr_value |= hcs_val;
@@ -273,29 +306,29 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
                mmc_card_cur->card_type = MMC_CARD;
                ocr_value |= MMC_OCR_REG_ACCESS_MODE_SECTOR;
                ret_cmd41 = MMC_CMD1;
-               OMAP_HSMMC_CON &= ~OD;
-               OMAP_HSMMC_CON |= OPENDRAIN;
+               writel(readl(&mmc_base->con) & ~OD, &mmc_base->con);
+               writel(readl(&mmc_base->con) | OPENDRAIN, &mmc_base->con);
        }
 
        argument = ocr_value;
-       err = mmc_send_cmd(ret_cmd41, argument, resp);
+       err = mmc_send_cmd(ret_cmd41, argument, mmc_resp.resp);
        if (err != 1)
                return err;
 
-       ocr_recvd = ((mmc_resp_r3 *) resp)->ocr;
+       ocr_recvd = mmc_resp.r3.ocr;
 
        while (!(ocr_recvd & (0x1 << 31)) && (retry_cnt > 0)) {
                retry_cnt--;
                if (mmc_card_cur->card_type == SD_CARD) {
                        argument = 0x0000 << 16;
-                       err = mmc_send_cmd(MMC_CMD55, argument, resp);
+                       err = mmc_send_cmd(MMC_CMD55, argument, mmc_resp.resp);
                }
 
                argument = ocr_value;
-               err = mmc_send_cmd(ret_cmd41, argument, resp);
+               err = mmc_send_cmd(ret_cmd41, argument, mmc_resp.resp);
                if (err != 1)
                        return err;
-               ocr_recvd = ((mmc_resp_r3 *) resp)->ocr;
+               ocr_recvd = mmc_resp.r3.ocr;
        }
 
        if (!(ocr_recvd & (0x1 << 31)))
@@ -324,26 +357,26 @@ unsigned char mmc_detect_card(mmc_card_data *mmc_card_cur)
        if (!(ocr_recvd & ocr_value))
                return 0;
 
-       err = mmc_send_cmd(MMC_CMD2, argument, resp);
+       err = mmc_send_cmd(MMC_CMD2, argument, mmc_resp.resp);
        if (err != 1)
                return err;
 
        if (mmc_card_cur->card_type == MMC_CARD) {
                argument = mmc_card_cur->RCA << 16;
-               err = mmc_send_cmd(MMC_CMD3, argument, resp);
+               err = mmc_send_cmd(MMC_CMD3, argument, mmc_resp.resp);
                if (err != 1)
                        return err;
        } else {
                argument = 0x00000000;
-               err = mmc_send_cmd(MMC_SDCMD3, argument, resp);
+               err = mmc_send_cmd(MMC_SDCMD3, argument, mmc_resp.resp);
                if (err != 1)
                        return err;
 
-               mmc_card_cur->RCA = ((mmc_resp_r6 *) resp)->newpublishedrca;
+               mmc_card_cur->RCA = mmc_resp.r6.newpublishedrca;
        }
 
-       OMAP_HSMMC_CON &= ~OD;
-       OMAP_HSMMC_CON |= NOOPENDRAIN;
+       writel(readl(&mmc_base->con) & ~OD, &mmc_base->con);
+       writel(readl(&mmc_base->con) | NOOPENDRAIN, &mmc_base->con);
        return 1;
 }
 
@@ -443,10 +476,9 @@ unsigned char configure_mmc(mmc_card_data *mmc_card_cur)
 {
        unsigned char ret_val;
        unsigned int argument;
-       unsigned int resp[4];
        unsigned int trans_clk, trans_fact, trans_unit, retries = 2;
-       mmc_csd_reg_t Card_CSD;
        unsigned char trans_speed;
+       mmc_resp_t mmc_resp;
 
        ret_val = mmc_init_setup();
 
@@ -459,21 +491,16 @@ unsigned char configure_mmc(mmc_card_data *mmc_card_cur)
        } while ((retries > 0) && (ret_val != 1));
 
        argument = mmc_card_cur->RCA << 16;
-       ret_val = mmc_send_cmd(MMC_CMD9, argument, resp);
+       ret_val = mmc_send_cmd(MMC_CMD9, argument, mmc_resp.resp);
        if (ret_val != 1)
                return ret_val;
 
-       ((unsigned int *) &Card_CSD)[3] = resp[3];
-       ((unsigned int *) &Card_CSD)[2] = resp[2];
-       ((unsigned int *) &Card_CSD)[1] = resp[1];
-       ((unsigned int *) &Card_CSD)[0] = resp[0];
-
        if (mmc_card_cur->card_type == MMC_CARD)
-               mmc_card_cur->version = Card_CSD.spec_vers;
+               mmc_card_cur->version = mmc_resp.Card_CSD.spec_vers;
 
-       trans_speed = Card_CSD.tran_speed;
+       trans_speed = mmc_resp.Card_CSD.tran_speed;
 
-       ret_val = mmc_send_cmd(MMC_CMD4, MMC_DSR_DEFAULT << 16, resp);
+       ret_val = mmc_send_cmd(MMC_CMD4, MMC_DSR_DEFAULT << 16, mmc_resp.resp);
        if (ret_val != 1)
                return ret_val;
 
@@ -497,18 +524,18 @@ unsigned char configure_mmc(mmc_card_data *mmc_card_cur)
                return ret_val;
 
        argument = mmc_card_cur->RCA << 16;
-       ret_val = mmc_send_cmd(MMC_CMD7_SELECT, argument, resp);
+       ret_val = mmc_send_cmd(MMC_CMD7_SELECT, argument, mmc_resp.resp);
        if (ret_val != 1)
                return ret_val;
 
        /* Configure the block length to 512 bytes */
        argument = MMCSD_SECTOR_SIZE;
-       ret_val = mmc_send_cmd(MMC_CMD16, argument, resp);
+       ret_val = mmc_send_cmd(MMC_CMD16, argument, mmc_resp.resp);
        if (ret_val != 1)
                return ret_val;
 
        /* get the card size in sectors */
-       ret_val = mmc_read_cardsize(mmc_card_cur, &Card_CSD);
+       ret_val = mmc_read_cardsize(mmc_card_cur, &mmc_resp.Card_CSD);
        if (ret_val != 1)
                return ret_val;
 
@@ -518,12 +545,15 @@ unsigned long mmc_bread(int dev_num, unsigned long blknr, lbaint_t blkcnt,
                        void *dst)
 {
        omap_mmc_read_sect(blknr, (blkcnt * MMCSD_SECTOR_SIZE), &cur_card_data,
-                          (unsigned long *) dst);
+                               (unsigned long *) dst);
        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;